Use this forum to chat about hardware specific topics for the ESP8266 (peripherals, memory, clocks, JTAG, programming)

User avatar
By Steve Ruiz
#91834 I am trying to test the internal system voltage of an ESP-01, using the ESP8266_RTOS_SDK v3.4.

* Note: this is the internal system voltage measurement, not the external measurement which uses the TOUT pin.

Specifically, I am using the adc example project from the peripherals section of the SDK installation. The file is adc_example_main.c . It builds fine, then flashes, and monitors successfully.

I have setup a test circuit that uses a voltage divider using a trimpot 10k and 20k resistor. The input voltage is 3.3V. The trimpot gives me the range 3.3V to 0. I can see the device stop as the voltage is decreased (as measured by an multimeter).

Problem is, the adc function reading is always 0x01010702 (4466). Since the ADC is 10-bit, I am assuming the value is actually 0x010702 or 370 decimal. This corresponds to 0.370V. My input voltage as measured with a multimeter shows otherwise (plus the module is alive). The voltage never changes, never fluctuates. I have powered different ESP-01s from USB-UARTs, a 3.7 LiPo battery (running through an LDO to get the 3.23 V), and from raspberry pi pins (3.3V and 5V).

The example code is very simple, and uses the adc_read function defined in the adc.h header:

ESP_OK == adc_read(&adc_data[0])

My goal is to measure the system voltage and correlate that with a draining battery, so that I could warn the user when it is time to charge the battery.

The example provided does not seem to work.
Is there a way to access the memory register for the SAR ADC directly from code?
The datasheet for the ESP8266EX does not list the reference voltage used by the SAR ADC.
User avatar
By eriksl
#91852 The internal ADC is completely unreliable. There is nothing wrong with the ADC itself, but it's also used for wifi, all of the time. The SDK documents also state this, so it shouldn't be a surprise. It also mentions that you can have a reliable reading, but only if you use the specific "fast read" function, which can take multiple (suggested: lots!) samples and average them. But this will only work if you turn off wifi first (also in the documentation).

So in short: don't use the ADC. Add a cheap external ADC using I2C, SPI or I2S.
User avatar
By btidey
#91853 The internal ADC on the esp8266 is indeed poor for many adc measurements but I find it is adequate for battery monitoring where precision is less important. By using a running average of say 16 measurements one can get 7 to 8 bit resolution which can give reasonable indication of the state of a lithium battery as it goes from 4.2V to 3.3V in its usable charge span. The poor absolute accuracy can also be a bit problematic but one can calibrate this once, e.g. against a fully charged cell.

I do find the rest of the original post puzzling. There seems to be a desire to use the ADC in a mode where it measures the internal Vdd supply (3.3V) rather than via the external ADC (TOUT) pin. This is never going to prove satisfactory in my opinion if using a battery with a regulator to produce the 3.3V Vdd supply. The regulator will prevent a reasonable battery voltage decay measurement until it is very close to exhaustion. Theoretically one could just catch it as the voltage just starts on its rapid decline but that doesn't sound a good idea to me and will be very dependent on the exact battery characteristic.

I realise that the ESP-01 does not have easy access to the ADC input; one of the many reasons why I never use the ESP-1- myself.

Other puzzles from the post are the numbers. The ADC should be returning a number between 0 and 1023 (0x3ff) and 0x010702 is not 370 decimal.