ESP32 ADC measurement error by 30-40mV
Posted: Fri Oct 15, 2021 6:34 am
Hello. I have been playing with the ESP32 ADC and notice that I always have 30-40mV error in the readings.
For example, I input voltage into my ESP32 from my power supply and compare it with the voltage result from the functions:
voltage returned by the ESP32 is always 30-40mV higher than the actual voltage that I put on the ESP32 pin.
I have calibrated the ESP32 adc as below:
I run the adc info command:
And in the ADC initialization, I change the calibrtion value as following:
Please can someone clarify to me where this 30-40mV error come from and how can I fix this. I do not think that adding an offset of 30mV to every voltage is the most approriate to solve this.
For example, I input voltage into my ESP32 from my power supply and compare it with the voltage result from the functions:
Code: Select all
uint32_t reading = adc1_get_raw(ADC1_CHANNEL_0); //adc in 5
uint32_t voltage = esp_adc_cal_raw_to_voltage(reading, adc_chars);
I have calibrated the ESP32 adc as below:
I run the adc info command:
Code: Select all
Connecting........__
Detecting chip type... ESP32
espefuse.py v3.1-dev
ADC VRef calibration: 1114mV
Code: Select all
#define DEFAULT_VREF 1114 //Use adc2_vref_to_gpio() to obtain a better estimate
#define NO_OF_SAMPLES 64 //Multisampling
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) {
printf("eFuse Two Point: Supported\r\n");
} else {
printf("eFuse Two Point: NOT supported\r\n");
}
//Check Vref is burned into eFuse
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
printf("eFuse Vref: Supported\r\n");
} else {
printf("eFuse Vref: NOT supported\r\n");
}
}
static void print_char_val_type(esp_adc_cal_value_t val_type)
{
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
printf("Characterized using Two Point Value\n");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
printf("Characterized using eFuse Vref\n");
} else {
printf("Characterized using Default Vref\n");
}
}
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);
}
Please can someone clarify to me where this 30-40mV error come from and how can I fix this. I do not think that adding an offset of 30mV to every voltage is the most approriate to solve this.