ESP32-S3 ADC reading issue

maskemaske
Posts: 9
Joined: Fri Oct 08, 2021 3:43 pm

ESP32-S3 ADC reading issue

Postby maskemaske » Thu Sep 01, 2022 4:18 pm

We are having issue getting the correct reading from our custom board with ESP32-S3-WROOM-1 module. In our design, we have connected ADC1_CHANNEL_6 (GPIO_NUM_7) in between two resistors, forming a voltage divider. The expected voltage range there is 1V5 to 2V7, which is of our battery power input.

During development we have connected a bench power supply instead of a battery, in series with a voltmeter. We are using this code to acquire the voltage reading:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_system.h"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"

typedef long i32;
static esp_adc_cal_characteristics_t *adc_chars;
static const adc1_channel_t channel = ADC1_CHANNEL_6;
static const adc_bits_width_t width = ADC_WIDTH_BIT_12;
static const adc_atten_t atten = ADC_ATTEN_DB_11;
static uint8 adc_configured = 0;

void adc_init() {
    /* gpio config */
    esp_err_t err;
    gpio_config_t io_conf = {};
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pin_bit_mask =  1ULL << GPIO_NUM_7;
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    err = gpio_config(&io_conf);
    
    /* config attenuation */
    adc1_config_channel_atten(channel, atten);

    /* config bit width */
    adc1_config_width(width);
    adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, 
        atten,
        width,
        1100,
        adc_chars);
}

i32 adc_read() {
    #define BATADC_SAMPLE_SZ 32
    // multisampling
    for (u8 i = 0; i < BATADC_SAMPLE_SZ; i++) {
        i32 raw = adc1_get_raw((adc1_channel_t)channel);
        adc_reading += raw;
        sys_delay_us(20);
    }

    adc_reading /= (BATADC_SAMPLE_SZ);
    voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars) * 2u;
    return voltage;
}

void app_main(void)
{
	adc_init();
	for (;;) {
		ESP_LOGI(TAG, "VBat: %ld", adc_read());
		vTaskDelay(1000);
	}
}
This gives stable readings, as in all samples are within 10mV. But they are wrong! Sometimes up to 150mV! The offset is different each time we power cycle the system.

BUT when we reset the system, by pulling RST to GND, the readings suddenly get very accurate (+-4mV), the offset disappears!

We did not burn any eFuse or set Two-Point calibration values; we are using the module as it shipped.

Are we doing something wrong?

username
Posts: 532
Joined: Thu May 03, 2018 1:18 pm

Re: ESP32-S3 ADC reading issue

Postby username » Fri Sep 02, 2022 2:06 am

Did you try any of the default examples here?

https://github.com/espressif/esp-idf/tr ... herals/adc

maskemaske
Posts: 9
Joined: Fri Oct 08, 2021 3:43 pm

Re: ESP32-S3 ADC reading issue

Postby maskemaske » Fri Sep 02, 2022 9:55 am

Did you try any of the default examples here?

https://github.com/espressif/esp-idf/tr ... herals/adc
Yes. First of all, it does not compile for S3, so I had to remove some parts that check the calibration type (function "check_efuse"). I also had to add a few lines that configure a different GPIO, which acts as enable-pin that enables the power rail I want to measure. See https://pastebin.com/GpZP8bpj
(I also added the x2 multiplicator since I am measuring between a voltage divider)

It works like this, but yields the very same results as my own tests. Let me elaborate what I am seeing (with the oneshot adc example from above):

My device is connected to my bench power supply, set to constant voltage at 4.01V. When I push the ON-button, the esp boots up and reports, for example:
"Raw: 2340 Voltage: 3882mV"
As the code is measuring in an endless loop, these results roll endlessly. The raw value deviates by at most 1. So its very stable.

Now I have soldered a wire to the RST pin of the ESP32 module. When I short it to ground, the chip goes into reset. I hold it down for about 2 seconds, then release it. The ESP32 module boots up again. And now it reports:
"Raw: 2419 Voltage: 4010mV"

PS:
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
idf.py --version
ESP-IDF v4.4.2

maskemaske
Posts: 9
Joined: Fri Oct 08, 2021 3:43 pm

Re: ESP32-S3 ADC reading issue

Postby maskemaske » Fri Sep 02, 2022 10:17 am

Added schematic snapshots of the reset and ADC circuit.
Attachments
vv.png
vv.png (35.82 KiB) Viewed 3693 times
rst.png
rst.png (38.83 KiB) Viewed 3693 times

ESP_Sprite
Posts: 9727
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 ADC reading issue

Postby ESP_Sprite » Fri Sep 02, 2022 12:16 pm

That does not look like a proper power-on-reset circuit: we advise an 10K pullup and an 100nF to 1uF capacitor to ground connected to the EN of the chip.

Who is online

Users browsing this forum: No registered users and 105 guests