Skip to content

uPesy now ships to the entire European Union

Livraison à partir de seulement 2.50€ !

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Measure an analog voltage with the ESP32 ADC in MicroPython

(Updated at 11/28/2022)

On the ESP32, some pins are connected to the integrated ADC of the microcontroller. An ADC is an analog to digital converter that returns a digital value proportional to the measured voltage.

Features

On the ESP32, pins 36, 39, 34 and 35 can be analog inputs with MicroPython. The resolution of the measurements is 12 bits, so the measurements are between 0 and 4095.

Warning

Unlike the Arduino, the analog inputs on the ESP32 must not exceed a voltage of 3.3V. This could damage or even destroy the inputs of the ADC. It is, therefore, necessary to check that you do not use a supply voltage of 5V to measure the value of a sensor. There are solutions to limit the input voltage of the ADC.

Read an analog input from the ESP32 with MicroPython

The voltage of analog input is measured using the sub-module ADC of the machine . As for PWM, a physical pin is associated with the ADC object.

from machine import Pin, ADC

# Pin definitions
adc_pin = Pin(36, mode=Pin.IN)
adc = ADC(adc_pin)
adc.atten(ADC.ATTN_11DB)

Do not forget to import the ADC sub-module. You will note that for the ESP32, you must also specify attenuation of 11 dB (with ADC.ATTN_11DB ) to read a voltage over the range of 0 to 3.3V.

You can also create an ADC by specifying the number of the analog channel you want to use.

from machine import ADC
adc = ADC(0) # Select the ADC_0 ()

Warning

On the ESP32, the analog channels are assigned to the pins disorderly. It is, therefore, better to use the definition by pin number.

Once you have configured an analog input in MicroPython, you only need to use the function read() to read the analog value.

from machine import Pin, ADC
adc = ADC(Pin(36, mode=Pin.IN))
print(adc.read())

It will be necessary to use a cross product to have the value measured in volt:

\[V_{volt} = \frac{3.3V}{4095} \times V_{bits}\]

Mini-Project: Control the intensity of an LED via a potentiometer on the ESP32

We will use PWM and ADC with MicroPython to control the brightness of an external LED.

Electrical schematic :

Wiring diagram esp32 adc potentiometer with LED

Electrical circuit to be made

Note

Remember putting a resistor in series with the LED to prevent it from burning (330 Ω, for example)

To read the position of the potentiometer alone:

from machine import Pin, ADC
import time


# Create an ADC object linked to pin 36
adc = ADC(Pin(36, mode=Pin.IN))

while True:

    # Read ADC and convert to voltage
    val = adc.read()
    val = val * (3.3 / 4095)
    print(round(val, 2), "V") # Keep only 2 digits

    # Wait a bit before taking another reading
    time.sleep_ms(100)

For reading the position of the potentiometer and changing the brightness:

from machine import Pin, ADC, PWM
import time


def map(x, in_min, in_max, out_min, out_max):
    """ return linear interpolation like map() fonction in Arduino"""
    return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min


if __name__ == "__main__":

    # Create a PWM object linked to pin 23
    pwm_led = PWM(Pin(23,mode=Pin.OUT))
    pwm_led.freq(1_000)

    # Create an ADC object linked to pin 36
    adc = ADC(Pin(36, mode=Pin.IN))
    adc.atten(ADC.ATTN_11DB)

    while True:

        val = adc.read()
        pwm_value = map(x=val, in_min=0, in_max=4095, out_min=0,out_max=1023)
        pwm_led.duty(pwm_value)
        time.sleep_ms(10)