ESP8266 ADC – Read Analog Values with Arduino IDE, MicroPython and Lua

Both ESP8266-12E and ESP8266-07 have one ADC pin that is easily accessible. This means that those ESP8266 boards can read analog signals. In this tutorial we’ll show you how to use analog reading with the ESP8266 using Arduino IDE, MicroPython or Lua firmware.

ESP8266 analog reading read ADC A0 Arduino IDE MicroPython Lua

As an example, we’ll show you how to read analog values from a potentiometer. This post is divided in three sections:

  1. ESP8266 Analog Read with Arduino IDE
  2. ESP8266 Analog Read with MicroPython
  3. ESP8266 Analog Read with Lua/NodeMCU

ESP8266 ADC Specifications

When referring to the ESP8266 ADC pin you will often hear these different terms interchangeably:

  • ADC (Analog-to-digital Converter)
  • TOUT
  • Pin6
  • A0
  • Analog Pin 0

All these terms refer to the same pin in the ESP8266 that is highlighted in the next section.

ESP8266 ADC Resolution

The ADC pin has a 10-bit resolution, which means you’ll get values between 0 and 1024.

ESP8266 Input Voltage Range

The ESP8266 ADC pin input voltage range is 0 to 1V if you’re using the bare chip. However, most ESP8266 development boards come with an internal voltage divider, so the input range is 0 to 3.3V. So, in sumary:

ESP8266 Analog Pin

With the ESP8266 12-E NodeMCU kit and other ESP8266 development boards, it is very easy to access the A0, you simply connect a jumper wire to the pin (see figure below).

ESP8266 NodeMCU kit

If you’re using an ESP8266 chip, like the ESP8266-07, you need to solder a wire to that pin.

Parts Required

To show you how to use analog reading with the ESP8266, we’ll read the values from a potentiometer. For that, you need to wire a potentiometer to your board.

Here’s the hardware that you need to complete this tutorial:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic Diagram

If you’re using an ESP8266 development board, follow the next schematic diagram.

ESP8266 ADC read analog value Arduino IDE MicroPython Lua

If you’re using an ESP8266 chip with input voltage range of 0V to 1V, you need to make sure that the input voltage on the A0 pin doesn’t exceed 1V. So, you need a voltage divider circuit, as shown below.

ESP8266 ADC read analog value circuit

We’re using a 100 Ohm and a 220 Ohm resistor, so that the Vout is 1V.

Recommend reading: ESP8266 Pinout Reference: Which GPIO pins should you use?


1. ESP8266 Analog Read with Arduino IDE

This section shows how to read analog values with the ESP8266 using Arduino IDE.

Install ESP8266 in Arduino IDE

In order to upload code to your ESP8266, you need to install the ESP8266 add-on first, if you haven’t already. Follow the next tutorial:

Code

Copy the following code to your Arduino IDE.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

const int analogInPin = A0;  // ESP8266 Analog Pin ADC0 = A0

int sensorValue = 0;  // value read from the pot
int outputValue = 0;  // value to output to a PWM pin

void setup() {
  // initialize serial communication at 115200
  Serial.begin(115200);
}

void loop() {
  // read the analog in value
  sensorValue = analogRead(analogInPin);
  
  // map it to the range of the PWM out
  outputValue = map(sensorValue, 0, 1024, 0, 255);
  
  // print the readings in the Serial Monitor
  Serial.print("sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t output = ");
  Serial.println(outputValue);

  delay(1000);
}

View raw code

The code starts by declaring the ESP8266 analog pin in the analogInPin variable:

const int analogInPin = A0;  // ESP8266 Analog Pin ADC0 = A0

The potentiometer value will be stored on the sensorValue variable:

int sensorValue = 0;  // value read from the pot

In the setup(), initialize the Serial Monitor for debugging purposes:

void setup() {
  // initialize serial communication at 115200
  Serial.begin(115200);
}

In the loop(), we read the analog value by using the analogRead() function and passing the analogInPin as an argument. The value is saved on the sensorValue variable:

sensorValue = analogRead(analogInPin);

Finally, the readings are displayed on the Serial Monitor, so that you can actually see what is going on.

Serial.print(sensorValue);

If you want to output PWM signals based on the input voltage of the ADC pin, you need to convert the ADC values to a range of 0 to 255. You need to do this because the PWM output only has 8-bit resolution.

outputValue = map(sensorValue, 0, 1024, 0, 255);

Uploading the Code

Upload the previous code to the ESP8266. Make sure you have the right board and COM port select. Go to Tools> Board and select the ESP8266 model you’re using. In our case, we’re using the ESP8266 12-E NodeMCU Kit.

Go to Tools > Port and select the COM port the ESP8266 is connected to.

Press the Arduino IDE upload button.

Note: if you’re using an ESP-07 or ESP-12E chip, you need an FTDI programmer to upload code.

Demonstration

After uploading the code, open the Serial Monitor at a baud rate of 115200. The analog readings should be displayed.

ESP8266 ADC read analog value Arduino IDE Demonstration

Rotate the potentiometer and see the values increasing or decreasing.


2. ESP8266 Analog Read with MicroPython

This section show how to read analog values with the ESP8266 using MicroPython firmware.

To follow this tutorial you need MicroPython firmware installed in your ESP8266 board. You also need an IDE to write and upload the code to your board. We suggest using Thonny IDE or uPyCraft IDE:

Script – Analog Reading ESP82266

The following script for the ESP8266 reads analog values from A0 pin.

# Complete project details at https://RandomNerdTutorials.com

from machine import Pin, ADC
from time import sleep

pot = ADC(0)

while True:
  pot_value = pot.read()
  print(pot_value)
  sleep(0.1)

View raw code

How the code works

To read analog inputs, import the ADC class in addition to the Pin class from the machine module. We also import the sleep method.

from machine import Pin, ADC
from time import sleep

Then, create an ADC object called pot on A0 pin.

pot = ADC(0)

In the loop, read the pot value and save it in the pot_value variable. To read the value from the pot, use the read() method on the pot object.

pot_value = pot.read()

Then, print the pot_value.

print(pot_value)

At the end, add a delay of 100 ms.

sleep(0.1)

In summary:

  • To read an analog value you use the ADC class;
  • To create an ADC object simply call ADC(0).
  • To read the analog value, use the read() method on the ADC object.

Demonstration

After uploading the code to the ESP8266 board using Thonny IDE or uPyCraft IDE, rotate the potentiometer.

Check the shell of your MicroPython IDE to read the values from the potentiometer.

ESP32 ESP8266 Analog Readings with MicroPython demonstration

3. ESP8266 Analog Read with Lua/NodeMCU

This section shows how use the NodeMCU firmware to read analog values with the ESP8266.

Flashing ESP8266 with Lua/NodeMCU firmware

First, you have to flash your ESPs with NodeMCU firmare.

I recommend using the ESPlorer IDE which is a program created by 4refr0nt to send commands to your ESP8266.

Follow these instructions to download and install ESPlorer IDE:

  1. Click here to download ESPlorer
  2. Unzip that folder
  3. Go to the main folder
  4. Run ESPlorer.jar
  5. Open the ESPlorer

Testing the ADC Pin (A0)

To send commands with the ESPlorer IDE, you need to establish a serial communication with your ESP, follow these instructions:

  1. Connect your ESP-12E or FTDI programmer to your computer
  2. Set bad raute as 9600
  3. Select your ESP-12E or FTDI programmer port (COM3, for example)
  4. Press Open/Close
ESPlorer IDE

Then type the following command:

print(adc.read(0))

Click the button “Send” as shown below.

ESPlorer

It should return a value between 0 and 1024. Rotate your potentiometer and send the print(adc.read(0)) command a few more times to get the potentiometer value.

When your potentiometer is near 0V it prints 0 and when it reaches 3.3V it should print 1024.

Wrapping Up

In this tutorial we’ve shown you how to read analog values using the ESP8266 analog pin (A0). One important thing to notice is that the ESP8266 analog input range is either 0-1V if you’re using a bare chip, or 0-3.3V if you’re using a development board.

Either way, you should always be careful not to exceed the maximum recommended voltage. You may consider adding a voltage divider circuit when you need a higher input voltage range.

We hope you’ve found this tutorial useful. If you’re just getting started with the ESP8266, we recommend the following resources:

Thanks for reading.


Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »

Learn how to program and build projects with the ESP32 and ESP8266 using MicroPython firmware DOWNLOAD »


Enjoyed this project? Stay updated by subscribing our weekly newsletter!

45 thoughts on “ESP8266 ADC – Read Analog Values with Arduino IDE, MicroPython and Lua”

  1. Rui
    I have been watching/reading your tutorials for a while with interest.
    I am a little confused with how you have chosen the resistors because you have a parallel combination between the 1K Pot and the 100R (R2).
    Also would it not make sense to have added a small value cap of around 100nF between ground and the output from the pot. Pots are notoriously noisey during use?

    • Hi Rui,
      I have to agree with NealB. You do have a parallel resistance that you are not taking into account in the calculation.

      The voltage divider should go between the output of the pot and ground. The pot’s fixed terminals should be between the 3.3V and ground. And the 220 Ohm resistor connects to the sweep of the pot. The common connection between the fixed resistors goes to the ADC pin. And the 100 Ohm to ground.

      This increases the accuracy of your calculation and lowers the current drain since there is now 1K between 3.3 and ground and not 320 Ohms. Making for less than one third of the current drain.

      All assuming very low current to the ADC of course or nothing much would work anyway.

      The cap is also a great idea to reduce the noise. Good work Neal.

      • Thanks for your suggestions. You guys are 100% right and I thought I had the circuit like you guys said, but using Fritizing I’ve messed up the connections I had in real life.
        I’ve updated the schematics!

        Thanks again for taking the time to leave a comment Paul and NealB.
        Have a great day!

  2. Ho risolto, sostituendo il trimmer, e funziona.
    Ho poi installato sul ESP 07 lo sketch per il TA SCT 013 e benché ruoti il trimmer non mi restituisce i valori.

  3. Scusami.
    I solved it by replacing the trimmer, and it works.
    I then installed the ESP 07 sketch for the TA 013 SCT and rotate the trimmer although I do not return values

  4. Rui,

    I use the Arduino editor w/esp8266 add on. Do you have this code in that IDE?

    Is there a reason you are using the NodeMCU editor vs Arduino IDE. I would think the Arduino IDE would have more users. There are many more chips than the ESP8266 and I hate to have to learn a new editor for each new chip!

    I have purchased your books and look forward to more such projects in the Arduino IDE format.

    Keep up the good work,

    Bi;; Miller

  5. Rui,

    I use the Arduino editor w/esp8266 add on. Do you have this code in that IDE?

    Is there a reason you are using the NodeMCU editor vs Arduino IDE. I would think the Arduino IDE would have more users. There are many more chips than the ESP8266 and I hate to have to learn a new editor for each new chip!

    I have purchased your books and look forward to more such projects in the Arduino IDE format.

    Keep up the good work,

    Bill Miller

  6. Is there a way to read the input voltage on NodeMCU. I would like to be able to read the voltage level of the battery supplying Vin.

  7. Hi, really nice to see your website. It seems that ESP8266 is getting more and more popular! Good work!
    I only have one comment to make, I am using a nodemcu board (v0.9, yeah, the wide one) and the measurable voltage at A0 is between 0V (well, ground gives a reading of “2”, close enough) and 3V. which is “1024”. I don’t know if this is a recent change or what, but it may help someone…

  8. You mentioned using Multimeter to check if it is 1 volt limit or 3.3 v limit, but did not show how.
    So, I risked it and build the same circuit. Wrote a simple Arduino sketch to read the analog value.
    I stopped around 600 and measured the voltage It was 1.99 volt So I assumed that my nodemcu is ok for 3.3v.. BTY the version number I have is old and it is is 0.9

  9. I am trying to connect esp8266 with dfrobot ph sensor. My code is get uploaded bt on serial monitor it doesnot show any readings. I am not understanding why this is happening? Could you just help me out with that?

  10. Hi Rui ,

    I have a question because i see may somthing wrong
    Your formular is : Vout = Vin*R2/(R1+R2)
    But in your toturol –> R1 = 220ohm, R2=100ohm, right?
    So, how you get 3.3V in your connect ?
    Because, my opinion –> with that connect. We only get 1.56V at ADC output
    Thanks, please advice me

    • Hi.
      You only need that voltage divider if the maximum input voltage on the analog pin of the ESP8266 is 1V (some old versions only support up to 1V).
      I need to update this blog post to make it clearer.
      Thanks for noticing.
      Regards,
      Sara 🙂

  11. There is an annoying “feature” of the NodeMCU and the pre-ADC divisor resistor network. The 100K/220K network produces a full count at 3.2v, not 3.3v. So at 3.2v the ADC is already seeing the full 1v. This results in a 3% loss of scale and ADC count is now effectively reduced from the promised 1024 bits down to 993 bits.
    You need to take this into account when using a Steinhart-Hart formula to convert the thermistor resistance into Kelvin. Otherwise the formula does not work.

  12. Hi, and tanks for a nice web site.

    I cannot see that the voltage divider will give the right value.
    Let’s assume that the 1K pot is in the middle position. Without the
    voltage regulator, there will be 500 ohms from both ground and 3.3V
    to the output, giving a voltage of 1.65.
    But you cannot add this other voltage regulator and assume that the
    voltage is still 1.65.
    The path trough the voltage regulator add a resistor of 320 ohm in parallel
    to the 500 ohms of the ground side of the pot, gives an effective value of
    1 / ( 1/500 + 1/320) = 195 ohms.
    The output of the pot will now be 0.96 V and not 1.65.
    Hence, the voltage divider will not divide the right voltage.
    I believe that the resistors in the voltage divider will have to be significantly higher than the resistance in the pot for this to work.
    Regards,
    Stein Gulbrandsen

  13. Parabéns! Rui e Sara,

    Muito bom seu Poste sobre ADC no Nodemecu será muito útil para leitura de sensores analógicos .
    Congratulations!
    Carlos Bruni
    Salvador Bahia Brasil

  14. Hello,

    Thank you very much to share this nice code ! I have a problem. I try to use this code with a DHT22. On the charts it Always shows the same value for temperature (24.3°C), humidity (57%).

    If I print the values in the serial monitor Inside the loop, the values changed and are true but not on the charts. It seems that the function of reading temperature, humidity and pressure are not executed.

    Could you help me to fix this problem. Thank you very much !
    Best regards

Leave a Comment

Download our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.