ESP32/ESP8266 Analog Readings with MicroPython

This tutorial shows how to read analog values with the ESP32 and ESP8266 boards using MicroPython firmware. As an example, we’ll read the values from a potentiometer.

ESP32 ESP8266 Analog Readings with MicroPython

Getting analog readings with ESP32 and ESP8266 is a bit different, so there is a section for each board in this tutorial.

Prerequisites

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

Analog Readings – ESP8266

ESP8266 only has one analog pin called A0. The ESP8266 analog pin has 10-bit resolution. It reads the voltage from 0 to 3.3V and then, assigns a value between 0 and 1023.

Note: some versions of the ESP8266 only read a maximum of 1V on the ADC pin. Make sure you don’t exceed the maximum recommended voltage for your board.

Analog Readings – ESP32

There are several pins on the ESP32 that can act as analog pins – these are called ADC pins. All the following GPIOs can act as ADC pins: 0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, and 39.

Learn more about the ESP32 GPIOs: ESP32 Pinout Reference: Which GPIO pins should you use?

ESP32 ADC pins have 12-bit resolution by default. These pins read voltage between 0 and 3.3V and then return a value between 0 and 4095. The resolution can be changed on the code. For example, you may want to have just 10-bit resolution to get a value between 0 and 1023.

analog reading esp32 esp8266 micropython

The following table shows some differences between analog reading on the ESP8266 and the ESP32.

ESP8266ESP32
Analog pinsA0 (ADC 0)GPIOs: 0, 2, 4, 12, 13, 14, 15,
25, 26, 27, 32, 33, 34, 35, 36,
and 39.
Resolution10-bit (0-1023)12-bit (0-4095)
Change resolutionNoYes

Schematic

Analog reading works differently in ESP32 and ESP8266. There is a different schematic and a different script for each board.

To follow this tutorial, you need to wire a potentiometer to your ESP8266 or ESP32 board.

Parts Required

Here’s a list of the parts to you need to build the circuit:

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 – ESP32

Follow the next schematic diagram if you’re using an ESP32 board:

ESP32 Analog Readings with MicroPython circuit schematic diagram

In this example we’re using GPIO 34 to read analog values from the potentiometer, but you can choose any other GPIO that supports ADC. Read our ESP32 Pinout Guide to learn more about the ESP32 GPIOs.

Schematic – ESP8266

Follow the next schematic diagram if you’re using an ESP8266 board:

ESP8266 Analog Readings with MicroPython circuit schematic diagram

The ESP8266 supports analog reading only on the A0 pin.

Script

There are a few differences when it comes to analog reading in ESP32 and ESP8266 regarding the code. You should write a slightly different script depending on the board you’re using. Make sure you follow the code for your specific board.

Script – ESP32

The following script for the ESP32 reads analog values from GPIO 34.

# Complete project details at https://RandomNerdTutorials.com/micropython-programming-with-esp32-and-esp8266/

from machine import Pin, ADC
from time import sleep

pot = ADC(Pin(34))
pot.atten(ADC.ATTN_11DB)       #Full range: 3.3v

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 GPIO 34.

pot = ADC(Pin(34))

The following line defines that we want to be able to read voltage in full range.

pot.atten(ADC.ATTN_11DB)

This means we want to read voltage from 0 to 3.3V. This corresponds to setting the attenuation ratio of 11db. For that, we use the atten() method and pass as argument: ADC.ATTN_11DB.

The atten() method can take the following arguments:

  • ADC.ATTN_0DB — the full range voltage: 1.2V
  • ADC.ATTN_2_5DB — the full range voltage: 1.5V
  • ADC.ATTN_6DB — the full range voltage: 2.0V
  • ADC.ATTN_11DB — the full range voltage: 3.3V

In the while loop, read the pot value and save it in the pot_value variable. To read the value from the pot, simply 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)

When you rotate the potentiometer, you get values from 0 to 4095 – that’s because the ADC pins have a 12-bit resolution by default. You may want to get values in other ranges. You can change the resolution using the width() method as follows:

ADC.width(bit)

The bit argument can be one of the following parameters:

  • ADC.WIDTH_9BIT: range 0 to 511
  • ADC.WIDTH_10BIT: range 0 to 1023
  • ADC.WIDTH_11BIT: range 0 to 2047
  • ADC.WIDTH_12BIT: range 0 to 4095

For example:

ADC.width(ADC.WIDTH_12BIT)

In summary:

  • To read an analog value you need to import the ADC class;
  • To create an ADC object simply use ADC(Pin(GPIO)), in which GPIO is the number of the GPIO you want to read the analog values;
  • To read the analog value, simply use the read() method on the ADC object.

Script – ESP8266

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

# Complete project details at https://RandomNerdTutorials.com/micropython-programming-with-esp32-and-esp8266/

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)

Note: ADC0 (A0) is the only pin on the ESP8266 that supports analog reading.

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). The ESP8266 only supports ADC reading on A0 pin.
  • To read the analog value, use the read() method on the ADC object.

Demonstration

After saving the code to your ESP board using Thonny IDE or uPyCraft IDE, rotate the potentiometer.

ESP32 ESP8266 Analog Readings with MicroPython circuit schematic diagram

Check the shell of your MicroPython IDE to read the values from the potentiometer. If you’re using an ESP32 you should get readings between 0 and 4095 — or readings between 0 and 1023 with an ESP8266.

ESP32 ESP8266 Analog Readings with MicroPython demonstration

Wrapping Up

In this tutorial we’ve shown you how to read analog values using MicroPython with the ESP32 and ESP8266 boards. There are several GPIOs on the ESP32 that can read analog values. On the other side, the ESP8266 only supports analog readings on the A0 (ADC0) pin.

Reading analog values with the ESP32 and ESP8266 is slightly different, but in summary, you need to create an ADC object, and then use the read() method to get the values.

We hope you’ve found this tutorial useful. If you’re just getting started with MicroPython, you may also like the following resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

9 thoughts on “ESP32/ESP8266 Analog Readings with MicroPython”

  1. Measurements was not consistent till we made 20K runs and average.
    Code:

    from machine import Pin, ADC
    from time import sleep

    pot = ADC(Pin(34)) # use your pin number
    pot.atten(ADC.ATTN_11DB) #Full range: 3.3v

    myfloat = 0.0

    number_of_runs = 20000
    for x in range(number_of_runs):
    pot_value = pot.read()

    myfloat = myfloat + pot_value

    if x == 20000:
    break

    myfloat = myfloat / 20000
    print()
    print(myfloat)

    Reply
  2. Hello, i have to say that the one above is a very well written tutorial and conteins a lot of useful concepts…
    but i have a problem… when i run the code the first print is correct but then it always prints the max value of the potentiometer 4095… what should i do?

    Reply
  3. Hi,
    I’m using the ESP-32 to mesure voltages in the order of uV (microvolts) so I have to use the intern amplifyer. Does anyone knows how to configure it?

    Reply
  4. hi
    the shell display of Thonny editor is showing random values i.e even the resistance has not been changed , the values keep changing according to the timer ..any advise plz

    Reply

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.