Page 1 of 1

ESP32 ADC calibration tips

Posted: Tue Feb 08, 2022 5:50 am
by zazas321
Hello. I would like to know how can I perform ADC calibration to achieve the best results. We are using resistance temperature sensor.

To read the resistance temperature value, we use voltage divider (See the image link below for the schematic screenshot):
https://ibb.co/hYrJ4fD


The adc is setup as following:

Code: Select all

esp_adc_cal_characteristics_t *adc_chars;
static  adc_bits_width_t width = ADC_WIDTH_BIT_12;
static  adc_atten_t atten = ADC_ATTEN_DB_11;
static  adc_unit_t unit = ADC_UNIT_1;



static void check_efuse(void)
{
    //Check if TP is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
        ESP_LOGI(ADC_TAG,"eFuse Two Point: Supported");
    } else {
        ESP_LOGI(ADC_TAG,"eFuse Two Point: NOT supported");
    }
    //Check Vref is burned into eFuse
    if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
        ESP_LOGI(ADC_TAG,"eFuse Vref: Supported");
    } else {
        ESP_LOGI(ADC_TAG,"eFuse Vref: NOT supported");
    }

}


static void print_char_val_type(esp_adc_cal_value_t val_type)
{
    if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
        ESP_LOGI(ADC_TAG,"Characterized using Two Point Value");
    } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
        ESP_LOGI(ADC_TAG,"Characterized using eFuse Vref");
    } else {
        ESP_LOGI(ADC_TAG,"Characterized using Default Vref");
    }
}

void ADC_Init(void)
{
// ADC config


    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(ADC1_CHANNEL_5,ADC_ATTEN_DB_11); 
    adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_11);
    adc1_config_channel_atten(ADC1_CHANNEL_3,ADC_ATTEN_DB_11);
    adc1_config_channel_atten(ADC1_CHANNEL_6,ADC_ATTEN_DB_11);
    check_efuse();
    //Characterize ADC
    //adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));

    adc_chars = (esp_adc_cal_characteristics_t *)calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, width, DEFAULT_VREF, adc_chars);
    print_char_val_type(val_type);

    vTaskDelay(1000/portTICK_PERIOD_MS);
}

I have noticed across multiple devices that the error between the temperature that I can measure on the ADC pin with the multimeter and the voltage that ESP32 returns using esp_adc_cal_raw_to_voltage has about 30-40 mv error which is not ideal for our product.

I have a variable resistance box to simulare my resistance sensor. For example, when I set it to 20kOhm the voltage output should be 1.57V but the ESP32 returns 1.6V using esp_adc_cal_raw_to_voltage.

Can someone suggest me what is the best way to setup and calibrate adc?

Re: ESP32 ADC calibration tips

Posted: Tue Feb 08, 2022 3:06 pm
by vanBassum
I have read that the ADC from de ESP itself isnt the most acurate one. Maybe an external reference could help. I'm not sure if just a calibration will help your case.

Re: ESP32 ADC calibration tips

Posted: Tue Feb 08, 2022 4:44 pm
by Vader_Mester
zazas321 wrote:
Tue Feb 08, 2022 5:50 am
Hello. I would like to know how can I perform ADC calibration to achieve the best results. We are using resistance temperature sensor.

To read the resistance temperature value, we use voltage divider (See the image link below for the schematic screenshot):
https://ibb.co/hYrJ4fD

I have noticed across multiple devices that the error between the temperature that I can measure on the ADC pin with the multimeter and the voltage that ESP32 returns using esp_adc_cal_raw_to_voltage has about 30-40 mv error which is not ideal for our product.

I have a variable resistance box to simulare my resistance sensor. For example, when I set it to 20kOhm the voltage output should be 1.57V but the ESP32 returns 1.6V using esp_adc_cal_raw_to_voltage.

Can someone suggest me what is the best way to setup and calibrate adc?
When you say error, do you mean an actual error (+/-) or an offset in a fixed direction?

If you have a fixed offset, you can easily calibrate it out, by saving the offset value in flash (like using NVS).
You can even save it on millivolts not ADC values, so getting the final result is easier.
You can also set one of the eFuse location that is free to be used by the application, to store this offset.
Either way you have it persistently stored that stays there between boots.
Then when you boot up, you read it out to a variable and use it in every ADC calculation.

If it is an actuall error, meaning that the value swings by this much in both directions from sample to sample, that is probably a hardware or circuitry issue, which you need to fix yourself. Can be power supply stability problem, or noise.

Re: ESP32 ADC calibration tips

Posted: Wed Feb 09, 2022 5:18 am
by zazas321
When I say error I mean slight deviation from the actual voltage and the voltage that the ESP32 reads. Adding an offset to flash is not a problem for a single device. All device will have slightly different offsets and there will be thousands of them. I wont be able to calibrate all of them by hand. I need a software method so the devices can calibrate themselves accordingly.


I dont think there could be an issue with hardware. I have tested with various ESP32 devkit boards and they all have same issues. They all have ADC error. I can use signal generator or apply some known voltage on the ADC pin. For example I can provide 1.5V on the ADC pin and the ESP32 will not measure 1.5V. My particular device would measure 1.52V. So the ESP32 has a measuring error of 0.02V at 1.5V . Is that normal error for the ESP32 adc or there is something wrong with my ESP32?

Re: ESP32 ADC calibration tips

Posted: Wed Feb 09, 2022 3:10 pm
by vanBassum
Sounds like a reference problem. If all the devices had the same error a linear calibration (Ax+B) would be sufficient. In that case the calibration would be the same for all devices. Since all devices have a different error, you can't get away with this.

An ADC has to have a known voltage as reference, if this reference is different for each device so will be the measured value. Let me aks you this, how does the device know what voltage is applied to a pin without some kind of reference?

Re: ESP32 ADC calibration tips

Posted: Thu Feb 10, 2022 11:21 am
by Vader_Mester
zazas321 wrote:
Wed Feb 09, 2022 5:18 am
When I say error I mean slight deviation from the actual voltage and the voltage that the ESP32 reads. Adding an offset to flash is not a problem for a single device. All device will have slightly different offsets and there will be thousands of them. I wont be able to calibrate all of them by hand. I need a software method so the devices can calibrate themselves accordingly.


I dont think there could be an issue with hardware. I have tested with various ESP32 devkit boards and they all have same issues. They all have ADC error. I can use signal generator or apply some known voltage on the ADC pin. For example I can provide 1.5V on the ADC pin and the ESP32 will not measure 1.5V. My particular device would measure 1.52V. So the ESP32 has a measuring error of 0.02V at 1.5V . Is that normal error for the ESP32 adc or there is something wrong with my ESP32?
If you add a voltage reference, like a Microchip LM4030-2.5, this is an extremely precise voltage reference. Just add it to the product. Since you know, that you need to measure 2.5V exactly, you can pretty much use this to self calibrate your ADC measurements.

Re: ESP32 ADC calibration tips

Posted: Thu Feb 10, 2022 3:53 pm
by vanBassum
Yes that is a possibility, altough i would advice you to add this as a reference. Because of things like drift, temp coëfficiënt ect. A calibration doens't account for these things unless you want to do a calibration before each measurement.

Re: ESP32 ADC calibration tips

Posted: Thu Feb 10, 2022 10:47 pm
by FirstFreeLogin
@zazas321 You no need external Vref to calibration. At some production stage (e.g programing) you can calibrate it by precision resistor connected instead your temperature sensor. Now you will know what count ADC must back and you can cancel different.
I place pcb on special tool with spring needle where I burn finish firmware. Also in this firmware I have test and calibration procedure (it run only if a tool is detected)

Re: ESP32 ADC calibration tips

Posted: Tue Jun 14, 2022 4:39 am
by zazas321
Thank you all for suggestions :)