May 13, 2021

The ESP8266 ADC

The ESP8266 has a one channel 10 bit ADC. It is limited to a 1 volt range, so be careful and use a resistor divider to scale your signal accordingly.

The SDK has a simple routine to fetch data from it:

system_adc_read()
This is almost all you need to know if you are programming in C and using the SDK from Espressif, like sensible people do. This will give you a value in the range 0 to 1023.

Input pin

The ADC input is via the "Tout" pin. I have no idea why they call it "Tout". This hints that it has some alternate function as a timer output, but that does not seem to be the case. On the ESP8266 chip itself, this is pin 6. It may be labeled "ADC" (as on some ESP12 modules) or even something absurd like "A0" on the NodeMCU boards.

If you are working with a NodeMCU board (as I usually am) you use the pin labeled A0. The NodeMCU gang had their own zany idea of renaming all the pins. The interesting thing is that they provide a voltage divider for whatever signal you place on this pin, namely a 220K and 100K resistor. So 3.2 volts gets scaled to 1 volt on the ADC. 3.3 volts gets scaled to 1.03 volts which (probably) won't damage the ESP8266. This is kind of handy and surely prevents many unhappy mistakes.

Reading the V3.3 supply voltage

The SDK has a function system_get_vdd33() that can use the ADC to read the chip supply voltage. Something has to be switched to make the ADC do this though. Just calling this function always returns 0xffff = 65535 (maybe -1 is intended?) The SDK document says that this pin must be suspended for this to work, but gives no hint how a person would "suspend" the pin. What they mean apparently is that the pin must be floating, i.e. nothing is connected to the pin.