ESP32 In MicroPython: Analog Input
Written by Mike James & Harry Fairhead   
Tuesday, 17 October 2023
Article Index
ESP32 In MicroPython: Analog Input
Calibration
How Fast?

The response is non-linear near zero and the reference voltage:

esp32cal
In practice voltages less than 100mV read as zero.

In addition to calibration problems the ADC is also sensitive to noise. You can reduce this by adding a 100nF capacitor across the input line and by averaging multiple readings:

esp32cal2

The ADC can be set to do conversions continuously, reading each of the selected inputs and it can work in low-power mode at a lower frequency. Alternatively, you can simply start a conversion on a given input when you need the data – this is the only mode that MicroPython supports.

The simplest way of using the ADC is to perform a single read of a single input under software control. Before making use of it, you have to create an ADC object associated with the channel:

adc=machine.ADC(pin)

Once you have selected the input you are going to read, you can start a conversion and get the result using:

adc.read()

which returns the raw reading of the ADC. The result is in the range 0 to 4095 for 12-bit resolution.

You can also use:

ADC.read_u16()

which always returns a result in the range 0 to 65535 irrespective of the number of bits actually supplied by the ADC.

Both of these raw readings generally have to be scaled to turn them into physically meaningful values and they are not corrected for any calibration data available.

In most cases you are going to get more accurate and usable results via the method:

ADC.read_uv()

which returns a result automatically calibrated and converted to μV. The resolution is less than suggested and the result is always a multiple of 1000 μV i.e. millivolts.

The simplest A‑to‑D program you can write is:

from machine import ADC,Pin
adc = ADC(Pin(32))
print(adc.read())
print(adc.read_u16())
print(adc.read_uv()/1000000)

For example, with an input at around 1V the output is:

4095

65535

1.063

The actual input voltage may be higher than indicated. If you connect the input to ground you will see:

0

0

0.075

Indicating that the nonlinear portion of the input between zero and 75mV is measured as 75mV.

To make the ADC more useful it supports changing the input voltage range via attenuators:

  • ADC.ATTN_0DB: No attenuation (100mV - 950mV)

  • ADC.ATTN_2_5DB: 2.5dB attenuation (100mV - 1250mV)

  • ADC.ATTN_6DB: 6dB attenuation (150mV - 1750mV)

  • ADC.ATTN_11DB: 11dB attenuation (150mV - 2450mV)

You can set attenuation in the constructor or in the atten method:

adc = ADC(Pin(32),atten=ADC.ATTN_11DB)

or:

adc.atten(ADC.ATTN_11DB)

to set the range to approximately 150mV to 2450mV. Notice that the exact range depends on the reference voltage.

The absolute maximum input voltage to the ADC is 3.6V, but using such a high voltage risks damaging the ESP32. In practice keep the input voltage below 3.3V.

You can also set the number of bits to use with the width method:

adc.width(bits)

and bits can be any of:

  • ADC.WIDTH_9BIT 9-bit data

  • ADC.WIDTH_10BIT 10-bit data

  • ADC.WIDTH_11BIT 11-bit data

  • ADC.WIDTH_12BIT 12-bit data - this is the default configuration

If you want to use any of the more advanced features of the ESP32’s ADC you will need either to create the functions that directly access the hardware or move to C.



Last Updated ( Tuesday, 17 October 2023 )