ESP32-S3 very big ADC error
Posted: Fri Sep 09, 2022 11:52 am
I am working on a project with ESP32-S3 where we need to measure very small voltage changes via the ADC.
Internal ESP32 12 bit ADC has a 12 bit resolution and assuming that vref is 3.3V, I can calculate the voltage of 1 adc step:
3300/4095 = 0.8mV
I have a few questions:
1.
In the official ESP32 documentation, it says that if attenuation ADC_ATTEN_DB_11 is selected, measurable range is :
150 mV ~ 2450 mV
Does that mean that ESP32 will not be capable of measuring above 2450mV? How is that possible? What if I want to measure across full range (0 - 3300mV)?
2. I have tried to familiarise myself with the ADC and how it works and I flashed very simple program to my CPU:
I use labarotory power supply to generate 250mV (also measure this voltage on digital multimeter) and then this voltage and GND is connected to ESP32 ADC configured pin directly.
https://ibb.co/2dqf66c
As you can see from the image above, the LAB power supply is set to 250mV and the digital multimeter is measuring 228mV. So I am expecting to read somewhere in between (250mV and 228mV)
I cannot wrap my head around why the ESP32 ADC measurements fluctuate so much:
According to the serial logs above you can see that the voltage readings fluctuate from 180mV to over 330mV which is ALOT.
What are the ways to reduce the ADC measuring error? I am expecting to read voltage with +-10mV error if that is possible
Internal ESP32 12 bit ADC has a 12 bit resolution and assuming that vref is 3.3V, I can calculate the voltage of 1 adc step:
3300/4095 = 0.8mV
I have a few questions:
1.
In the official ESP32 documentation, it says that if attenuation ADC_ATTEN_DB_11 is selected, measurable range is :
150 mV ~ 2450 mV
Does that mean that ESP32 will not be capable of measuring above 2450mV? How is that possible? What if I want to measure across full range (0 - 3300mV)?
2. I have tried to familiarise myself with the ADC and how it works and I flashed very simple program to my CPU:
Code: Select all
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ADC1 Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdlib.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#define ADC1_EXAMPLE_CHAN0 ADC1_CHANNEL_2
//ADC Attenuation
#define ADC_EXAMPLE_ATTEN ADC_ATTEN_DB_11
#define ADC_EXAMPLE_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT
#define ADC_WIDTH_BIT_DEFAULT ADC_WIDTH_BIT_12
int adc_raw1;
static esp_adc_cal_characteristics_t adc1_chars;
static bool adc_calibration_init(void)
{
esp_err_t ret;
bool cali_enable = false;
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
if (ret == ESP_ERR_NOT_SUPPORTED) {
ESP_LOGW("CALIBRATION", "Calibration scheme not supported, skip software calibration");
} else if (ret == ESP_ERR_INVALID_VERSION) {
ESP_LOGW("CALIBRATION", "eFuse not burnt, skip software calibration");
} else if (ret == ESP_OK) {
cali_enable = true;
esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
} else {
ESP_LOGE("CALIBRATION", "Invalid arg");
}
return cali_enable;
}
void app_main(void)
{
esp_err_t ret = ESP_OK;
uint32_t voltage = 0;
bool cali_enable = adc_calibration_init();
//ADC1 config
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));
ESP_ERROR_CHECK(adc1_config_channel_atten(ADC1_EXAMPLE_CHAN0, ADC_EXAMPLE_ATTEN));
while (1) {
adc_raw1 = adc1_get_raw(ADC1_EXAMPLE_CHAN0);
ESP_LOGI("ADC_RAW", "raw data: %d", adc_raw1);
if (cali_enable) {
voltage = esp_adc_cal_raw_to_voltage(adc_raw1, &adc1_chars);
ESP_LOGI("ADC_VOLTAGE", "cali data: %d mV", voltage);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
I use labarotory power supply to generate 250mV (also measure this voltage on digital multimeter) and then this voltage and GND is connected to ESP32 ADC configured pin directly.
https://ibb.co/2dqf66c
As you can see from the image above, the LAB power supply is set to 250mV and the digital multimeter is measuring 228mV. So I am expecting to read somewhere in between (250mV and 228mV)
I cannot wrap my head around why the ESP32 ADC measurements fluctuate so much:
Code: Select all
I (653298) ADC_RAW: raw data: 239
I (653298) ADC_VOLTAGE: cali data: 210 mV
I (654298) ADC_RAW: raw data: 234
I (654298) ADC_VOLTAGE: cali data: 205 mV
I (655298) ADC_RAW: raw data: 211
I (655298) ADC_VOLTAGE: cali data: 185 mV
I (656298) ADC_RAW: raw data: 240
I (656298) ADC_VOLTAGE: cali data: 211 mV
I (657298) ADC_RAW: raw data: 222
I (657298) ADC_VOLTAGE: cali data: 196 mV
I (658298) ADC_RAW: raw data: 227
I (658298) ADC_VOLTAGE: cali data: 200 mV
I (659298) ADC_RAW: raw data: 221
I (659298) ADC_VOLTAGE: cali data: 195 mV
I (660298) ADC_RAW: raw data: 243
I (660298) ADC_VOLTAGE: cali data: 213 mV
I (661298) ADC_RAW: raw data: 244
I (661298) ADC_VOLTAGE: cali data: 214 mV
I (662298) ADC_RAW: raw data: 243
I (662298) ADC_VOLTAGE: cali data: 213 mV
I (663298) ADC_RAW: raw data: 244
I (663298) ADC_VOLTAGE: cali data: 214 mV
I (664298) ADC_RAW: raw data: 233
I (664298) ADC_VOLTAGE: cali data: 204 mV
I (665298) ADC_RAW: raw data: 237
I (665298) ADC_VOLTAGE: cali data: 207 mV
I (666298) ADC_RAW: raw data: 245
I (666298) ADC_VOLTAGE: cali data: 215 mV
I (667298) ADC_RAW: raw data: 220
I (667298) ADC_VOLTAGE: cali data: 193 mV
I (668298) ADC_RAW: raw data: 231
I (668298) ADC_VOLTAGE: cali data: 203 mV
I (669298) ADC_RAW: raw data: 243
I (669298) ADC_VOLTAGE: cali data: 213 mV
I (670298) ADC_RAW: raw data: 238
I (670298) ADC_VOLTAGE: cali data: 208 mV
I (671298) ADC_RAW: raw data: 237
I (671298) ADC_VOLTAGE: cali data: 207 mV
I (672298) ADC_RAW: raw data: 235
I (672298) ADC_VOLTAGE: cali data: 206 mV
I (673298) ADC_RAW: raw data: 243
I (673298) ADC_VOLTAGE: cali data: 213 mV
I (674298) ADC_RAW: raw data: 231
I (674298) ADC_VOLTAGE: cali data: 203 mV
I (675298) ADC_RAW: raw data: 243
I (675298) ADC_VOLTAGE: cali data: 213 mV
I (676298) ADC_RAW: raw data: 239
I (676298) ADC_VOLTAGE: cali data: 210 mV
I (677298) ADC_RAW: raw data: 239
I (677298) ADC_VOLTAGE: cali data: 210 mV
I (678298) ADC_RAW: raw data: 243
I (678298) ADC_VOLTAGE: cali data: 213 mV
I (679298) ADC_RAW: raw data: 235
I (679298) ADC_VOLTAGE: cali data: 206 mV
I (680298) ADC_RAW: raw data: 237
I (680298) ADC_VOLTAGE: cali data: 207 mV
I (681298) ADC_RAW: raw data: 250
I (681298) ADC_VOLTAGE: cali data: 219 mV
I (682298) ADC_RAW: raw data: 233
I (682298) ADC_VOLTAGE: cali data: 204 mV
I (683298) ADC_RAW: raw data: 231
I (683298) ADC_VOLTAGE: cali data: 203 mV
I (684298) ADC_RAW: raw data: 253
I (684298) ADC_VOLTAGE: cali data: 222 mV
I (685298) ADC_RAW: raw data: 243
I (685298) ADC_VOLTAGE: cali data: 213 mV
I (686298) ADC_RAW: raw data: 232
I (686298) ADC_VOLTAGE: cali data: 204 mV
I (687298) ADC_RAW: raw data: 363
I (687298) ADC_VOLTAGE: cali data: 316 mV
I (688298) ADC_RAW: raw data: 243
I (688298) ADC_VOLTAGE: cali data: 213 mV
I (689298) ADC_RAW: raw data: 245
I (689298) ADC_VOLTAGE: cali data: 215 mV
I (690298) ADC_RAW: raw data: 233
I (690298) ADC_VOLTAGE: cali data: 204 mV
I (691298) ADC_RAW: raw data: 266
I (691298) ADC_VOLTAGE: cali data: 233 mV
I (692298) ADC_RAW: raw data: 237
I (692298) ADC_VOLTAGE: cali data: 207 mV
I (693298) ADC_RAW: raw data: 232
I (693298) ADC_VOLTAGE: cali data: 204 mV
I (694298) ADC_RAW: raw data: 229
I (694298) ADC_VOLTAGE: cali data: 202 mV
I (695298) ADC_RAW: raw data: 190
I (695298) ADC_VOLTAGE: cali data: 168 mV
I (696298) ADC_RAW: raw data: 252
I (696298) ADC_VOLTAGE: cali data: 221 mV
I (697298) ADC_RAW: raw data: 255
I (697298) ADC_VOLTAGE: cali data: 223 mV
I (698298) ADC_RAW: raw data: 248
I (698298) ADC_VOLTAGE: cali data: 218 mV
I (699298) ADC_RAW: raw data: 269
I (699298) ADC_VOLTAGE: cali data: 235 mV
I (700298) ADC_RAW: raw data: 232
I (700298) ADC_VOLTAGE: cali data: 204 mV
I (701298) ADC_RAW: raw data: 235
I (701298) ADC_VOLTAGE: cali data: 206 mV
I (702298) ADC_RAW: raw data: 285
I (702298) ADC_VOLTAGE: cali data: 249 mV
I (703298) ADC_RAW: raw data: 251
I (703298) ADC_VOLTAGE: cali data: 220 mV
I (704298) ADC_RAW: raw data: 383
I (704298) ADC_VOLTAGE: cali data: 333 mV
I (705298) ADC_RAW: raw data: 247
I (705298) ADC_VOLTAGE: cali data: 217 mV
I (706298) ADC_RAW: raw data: 179
I (706298) ADC_VOLTAGE: cali data: 158 mV
I (707298) ADC_RAW: raw data: 255
I (707298) ADC_VOLTAGE: cali data: 223 mV
I (708298) ADC_RAW: raw data: 175
I (708298) ADC_VOLTAGE: cali data: 155 mV
I (709298) ADC_RAW: raw data: 250
I (709298) ADC_VOLTAGE: cali data: 219 mV
I (710298) ADC_RAW: raw data: 229
I (710298) ADC_VOLTAGE: cali data: 202 mV
I (711298) ADC_RAW: raw data: 229
I (711298) ADC_VOLTAGE: cali data: 202 mV
I (712298) ADC_RAW: raw data: 240
I (712298) ADC_VOLTAGE: cali data: 211 mV
I (713298) ADC_RAW: raw data: 237
I (713298) ADC_VOLTAGE: cali data: 207 mV
I (714298) ADC_RAW: raw data: 179
I (714298) ADC_VOLTAGE: cali data: 158 mV
I (715298) ADC_RAW: raw data: 222
I (715298) ADC_VOLTAGE: cali data: 196 mV
I (716298) ADC_RAW: raw data: 240
I (716298) ADC_VOLTAGE: cali data: 211 mV
I (717298) ADC_RAW: raw data: 245
I (717298) ADC_VOLTAGE: cali data: 215 mV
I (718298) ADC_RAW: raw data: 233
I (718298) ADC_VOLTAGE: cali data: 204 mV
I (719298) ADC_RAW: raw data: 214
I (719298) ADC_VOLTAGE: cali data: 188 mV
I (720298) ADC_RAW: raw data: 252
I (720298) ADC_VOLTAGE: cali data: 221 mV
I (721298) ADC_RAW: raw data: 253
I (721298) ADC_VOLTAGE: cali data: 222 mV
I (722298) ADC_RAW: raw data: 237
I (722298) ADC_VOLTAGE: cali data: 207 mV
I (723298) ADC_RAW: raw data: 231
I (723298) ADC_VOLTAGE: cali data: 203 mV
I (724298) ADC_RAW: raw data: 267
I (724298) ADC_VOLTAGE: cali data: 234 mV
I (725298) ADC_RAW: raw data: 218
I (725298) ADC_VOLTAGE: cali data: 191 mV
I (726298) ADC_RAW: raw data: 238
I (726298) ADC_VOLTAGE: cali data: 208 mV
I (727298) ADC_RAW: raw data: 235
I (727298) ADC_VOLTAGE: cali data: 206 mV
I (728298) ADC_RAW: raw data: 219
I (728298) ADC_VOLTAGE: cali data: 192 mV
I (729298) ADC_RAW: raw data: 213
I (729298) ADC_VOLTAGE: cali data: 187 mV
I (730298) ADC_RAW: raw data: 230
I (730298) ADC_VOLTAGE: cali data: 202 mV
I (731298) ADC_RAW: raw data: 235
I (731298) ADC_VOLTAGE: cali data: 206 mV
I (732298) ADC_RAW: raw data: 307
I (732298) ADC_VOLTAGE: cali data: 269 mV
I (733298) ADC_RAW: raw data: 204
I (733298) ADC_VOLTAGE: cali data: 180 mV
I (734298) ADC_RAW: raw data: 275
I (734298) ADC_VOLTAGE: cali data: 241 mV
I (735298) ADC_RAW: raw data: 228
I (735298) ADC_VOLTAGE: cali data: 201 mV
I (736298) ADC_RAW: raw data: 244
I (736298) ADC_VOLTAGE: cali data: 214 mV
I (737298) ADC_RAW: raw data: 233
I (737298) ADC_VOLTAGE: cali data: 204 mV
I (738298) ADC_RAW: raw data: 265
I (738298) ADC_VOLTAGE: cali data: 232 mV
I (739298) ADC_RAW: raw data: 202
I (739298) ADC_VOLTAGE: cali data: 179 mV
I (740298) ADC_RAW: raw data: 262
I (740298) ADC_VOLTAGE: cali data: 230 mV
I (741298) ADC_RAW: raw data: 248
I (741298) ADC_VOLTAGE: cali data: 218 mV
I (742298) ADC_RAW: raw data: 231
I (742298) ADC_VOLTAGE: cali data: 203 mV
I (743298) ADC_RAW: raw data: 205
I (743298) ADC_VOLTAGE: cali data: 181 mV
I (744298) ADC_RAW: raw data: 249
I (744298) ADC_VOLTAGE: cali data: 219 mV
I (745298) ADC_RAW: raw data: 285
I (745298) ADC_VOLTAGE: cali data: 249 mV
I (746298) ADC_RAW: raw data: 239
I (746298) ADC_VOLTAGE: cali data: 210 mV
I (747298) ADC_RAW: raw data: 235
I (747298) ADC_VOLTAGE: cali data: 206 mV
I (748298) ADC_RAW: raw data: 233
I (748298) ADC_VOLTAGE: cali data: 204 mV
I (749298) ADC_RAW: raw data: 227
I (749298) ADC_VOLTAGE: cali data: 200 mV
What are the ways to reduce the ADC measuring error? I am expecting to read voltage with +-10mV error if that is possible