ESP32 ADC calibration tips
Posted: 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
The adc is setup as following:
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?
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?