Analog to Digital Converter

Overview

ESP32 integrates two 12-bit SAR (Successive Approximation Register) ADCs (Analog to Digital Converters) and supports measurements on 18 channels (analog enabled pins). Some of these pins can be used to build a programmable gain amplifier which is used for the measurement of small analog signals.

The ADC driver API currently supports ADC1 (9 channels, attached to GPIOs 32 - 39).

API to support ADC2 is not available yet in ESP-IDF. The reason is that ADC2 is also used by Wi-Fi driver, and the application can only use ADC2 when Wi-Fi driver is not using it (and is not about to use it). This coordination mechanism is work in progress at the moment.

Configuration and Reading ADC

Taking an ADC reading involves configuring the ADC with the desired precision and attenuation by calling functions adc1_config_width() and adc1_config_channel_atten(). Configuration is done per channel, see adc1_channel_t, set as a parameter of above functions.

Then it is possible to read ADC conversion result with adc1_get_raw().

It is also possible to read the internal hall effect sensor via ADC1 by calling dedicated function hall_sensor_read(). Note that even the hall sensor is internal to ESP32, reading from it uses channels 0 and 3 of ADC1 (GPIO 36 and 39). Do not connect anything else to these pins and do not change their configuration. Otherwise it may affect the measurement of low value signal from the sesnor.

This API provides convenient way to configure ADC1 for reading from ULP. To do so, call function adc1_ulp_enable() and then set precision and attenuation as discussed above.

There is another specific function adc2_vref_to_gpio() used to route internal reference voltage to a GPIO pin. It comes handy to calibrate ADC reading and this is discussed in section ADC Calibration.

Application Examples

Reading voltage on ADC1 channel 0 (GPIO 36):

#include <driver/adc.h>

...

    adc1_config_width(ADC_WIDTH_12Bit);
    adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);
    int val = adc1_get_raw(ADC1_CHANNEL_0);

The input voltage in above example is from 0 to 1.1V (0 dB attenuation). The input range can be extended by setting higher attenuation, see adc_atten_t.

Reading the internal hall effect sensor:

#include <driver/adc.h>

...

    adc1_config_width(ADC_WIDTH_12Bit);
    int val = hall_sensor_read();

The value read in both these examples is 12 bits wide (range 0-4095).

An example of using the ADC driver including calibration (discussed below) is available in esp-idf: peripherals/adc

ADC Calibration

The esp_adc_cal/include/esp_adc_cal.h API provides functions to correct for differences in measured voltages caused by non-ideal ADC reference voltages in ESP32s. The ideal ADC reference voltage is 1100 mV however the reference voltage of different ESP32s can range from 1000 mV to 1200 mV.

Correcting the measured voltage using this API involves referencing a lookup table of voltages. The voltage obtained from the lookup table is then scaled and shifted by a gain and offset factor that is based on the ADC’s reference voltage. This is done with function esp_adc_cal_get_characteristics().

The reference voltage of the ADCs can be routed to certain GPIOs and measured manually using the ADC driver’s adc2_vref_to_gpio() function.

Example of Reading Calibrated Values

Reading the ADC and obtaining a result in mV:

#include <driver/adc.h>
#include <esp_adc_cal.h>

...
    #define V_REF 1100  // ADC reference voltage

    // Configure ADC
    adc1_config_width(ADC_WIDTH_12Bit);
    adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_11db);

    // Calculate ADC characteristics i.e. gain and offset factors
    esp_adc_cal_characteristics_t characteristics;
    esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_11db, ADC_WIDTH_12Bit, &characteristics);

    // Read ADC and obtain result in mV
    uint32_t voltage = adc1_to_voltage(ADC1_CHANNEL_6, &characteristics);
    printf("%d mV\n",voltage);

Routing ADC reference voltage to GPIO, so it can be manually measured and entered in function esp_adc_cal_get_characteristics():

#include <driver/adc.h>
#include <driver/gpio.h>
#include <esp_err.h>

...

    esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
    if (status == ESP_OK){
        printf("v_ref routed to GPIO\n");
    }else{
        printf("failed to route v_ref\n");
    }

An example of using the ADC driver and obtaining calibrated measurements is available in esp-idf: peripherals/adc

GPIO Lookup Macros

There are macros available to specify the GPIO number of a ADC channel, or vice versa. e.g.

  1. ADC1_CHANNEL_0_GPIO_NUM is the GPIO number of ADC1 channel 0 (36);
  2. ADC1_GPIO32_CHANNEL is the ADC1 channel number of GPIO 32 (ADC1 channel 4).

API Reference

This reference covers three components:

ADC driver

Functions

esp_err_t adc1_config_width(adc_bits_width_t width_bit)

Configure ADC1 capture width.

The configuration is for all channels of ADC1

Return
  • ESP_OK success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • width_bit: Bit capture width for ADC1

esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)

Configure the ADC1 channel, including setting attenuation.

The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage, usually 3.3V) requires setting >0dB signal attenuation for that ADC channel.

Note
This function also configures the input GPIO pin mux to connect it to the ADC1 channel. It must be called before calling adc1_get_raw() for this channel.

When VDD_A is 3.3V:

  • 0dB attenuaton (ADC_ATTEN_0db) gives full-scale voltage 1.1V
  • 2.5dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5V
  • 6dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2V
  • 11dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9V (see note below)

Note
The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
Note
At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
Return
  • ESP_OK success
  • ESP_ERR_INVALID_ARG Parameter error
Parameters
  • channel: ADC1 channel to configure
  • atten: Attenuation level

int adc1_get_raw(adc1_channel_t channel)

Take an ADC1 reading on a single channel.

Note
Call adc1_config_width() before the first time this function is called.
Note
For a given channel, adc1_config_channel_atten(channel) must be called before the first time this function is called.
Return
  • -1: Parameter error
  • Other: ADC1 channel reading.
Parameters
  • channel: ADC1 channel to read

void adc1_ulp_enable()

Configure ADC1 to be usable by the ULP.

This function reconfigures ADC1 to be controlled by the ULP. Effect of this function can be reverted using adc1_get_raw function.

Note that adc1_config_channel_atten, adc1_config_width functions need to be called to configure ADC1 channels, before ADC1 is used by the ULP.

int hall_sensor_read()

Read Hall Sensor.

Note
The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure these channels for use as ADC channels.
Note
The ADC1 module must be enabled by calling adc1_config_width() before calling hall_sensor_read(). ADC1 should be configured for 12 bit readings, as the hall sensor readings are low values and do not cover the full range of the ADC.
Return
The hall sensor reading.

esp_err_t adc2_vref_to_gpio(gpio_num_t gpio)

Output ADC2 reference voltage to gpio 25 or 26 or 27.

This function utilizes the testing mux exclusive to ADC 2 to route the reference voltage one of ADC2’s channels. Supported gpios are gpios 25, 26, and 27. This refernce voltage can be manually read from the pin and used in the esp_adc_cal component.

Return
  • ESP_OK: v_ref successfully routed to selected gpio
  • ESP_ERR_INVALID_ARG: Unsupported gpio
Parameters
  • gpio: GPIO number (gpios 25,26,27 supported)

Enumerations

enum adc_atten_t

Values:

ADC_ATTEN_0db = 0

The input voltage of ADC will be reduced to about 1/1

ADC_ATTEN_2_5db = 1

The input voltage of ADC will be reduced to about 1/1.34

ADC_ATTEN_6db = 2

The input voltage of ADC will be reduced to about 1/2

ADC_ATTEN_11db = 3

The input voltage of ADC will be reduced to about 1/3.6

enum adc_bits_width_t

Values:

ADC_WIDTH_9Bit = 0

ADC capture width is 9Bit

ADC_WIDTH_10Bit = 1

ADC capture width is 10Bit

ADC_WIDTH_11Bit = 2

ADC capture width is 11Bit

ADC_WIDTH_12Bit = 3

ADC capture width is 12Bit

enum adc1_channel_t

Values:

ADC1_CHANNEL_0 = 0

ADC1 channel 0 is GPIO36

ADC1_CHANNEL_1

ADC1 channel 1 is GPIO37

ADC1_CHANNEL_2

ADC1 channel 2 is GPIO38

ADC1_CHANNEL_3

ADC1 channel 3 is GPIO39

ADC1_CHANNEL_4

ADC1 channel 4 is GPIO32

ADC1_CHANNEL_5

ADC1 channel 5 is GPIO33

ADC1_CHANNEL_6

ADC1 channel 6 is GPIO34

ADC1_CHANNEL_7

ADC1 channel 7 is GPIO35

ADC1_CHANNEL_MAX
enum adc2_channel_t

Values:

ADC2_CHANNEL_0 = 0

ADC2 channel 0 is GPIO4

ADC2_CHANNEL_1

ADC2 channel 1 is GPIO0

ADC2_CHANNEL_2

ADC2 channel 2 is GPIO2

ADC2_CHANNEL_3

ADC2 channel 3 is GPIO15

ADC2_CHANNEL_4

ADC2 channel 4 is GPIO13

ADC2_CHANNEL_5

ADC2 channel 5 is GPIO12

ADC2_CHANNEL_6

ADC2 channel 6 is GPIO14

ADC2_CHANNEL_7

ADC2 channel 7 is GPIO27

ADC2_CHANNEL_8

ADC2 channel 8 is GPIO25

ADC2_CHANNEL_9

ADC2 channel 9 is GPIO26

ADC2_CHANNEL_MAX

ADC Calibration

Functions

void esp_adc_cal_get_characteristics(uint32_t v_ref, adc_atten_t atten, adc_bits_width_t bit_width, esp_adc_cal_characteristics_t *chars)

Calculate characteristics of ADC.

This function will calculate the gain and offset factors based on the reference voltage parameter and the Gain and Offset curve provided in the LUT.

Note
reference voltage of the ADCs can be routed to GPIO using adc2_vref_to_gpio() from the ADC driver
Note
The LUT members have been bit shifted by ADC_CAL_GAIN_SCALE or ADC_CAL_OFFSET_SCALE to make them uint32_t compatible. This bit shifting will accounted for in this function
Parameters
  • v_ref: true reference voltage of the ADC in mV (1000 to 1200mV). Nominal value for reference voltage is 1100mV.
  • atten: attenuation setting used to select the corresponding lookup table
  • bit_width: bit width of ADC
  • chars: pointer to structure used to store ADC characteristics of module

uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc, const esp_adc_cal_characteristics_t *chars)

Convert raw ADC reading to voltage in mV.

This function converts a raw ADC reading to a voltage in mV. This conversion is based on the ADC’s characteristics. The raw ADC reading is referenced against the LUT (pointed to inside characteristics struct) to obtain a voltage. Gain and offset factors are then applied to the voltage in order to obtain the final result.

Return
Calculated voltage in mV
Note
characteristics structure must be initialized using esp_adc_cal_get_characteristics() before this function is used
Parameters
  • adc: ADC reading (different bit widths will be handled)
  • chars: pointer to structure containing ADC characteristics of the module. Structure also contains pointer to the corresponding LUT

uint32_t adc1_to_voltage(adc1_channel_t channel, const esp_adc_cal_characteristics_t *chars)

Reads ADC1 and returns voltage in mV.

This function reads the ADC1 using adc1_get_raw() to obtain a raw ADC reading. The reading is then converted into a voltage value using esp_adc_cal_raw_to_voltage().

Return
voltage Calculated voltage in mV
Note
ADC must be initialized using adc1_config_width() and adc1_config_channel_atten() before this function is used
Note
characteristics structure must be initialized using esp_adc_cal_get_characteristics() before this function is used
Parameters
  • channel: Channel of ADC1 to measure
  • chars: Pointer to ADC characteristics struct

Structures

struct esp_adc_cal_lookup_table_t

Structure storing Lookup Table.

The Lookup Tables (LUT) of a given attenuation contains 33 equally spaced points. The Gain and Offset curves are used to find the appopriate gain and offset factor given a reference voltage v_ref.

Note
A seperate LUT is provided for each attenuation and are defined in esp_adc_cal_lookup_tables.c

Public Members

uint32_t gain_m

Gradient of Gain Curve

uint32_t gain_c

Offset of Gain Curve

uint32_t offset_m

Gradient of Offset Curve

uint32_t offset_c

Offset of Offset Curve

uint32_t bit_shift

Bit shift used find corresponding LUT points given an ADC reading

uint32_t voltage[]

Array of voltages in mV representing the ADC-Voltage curve

struct esp_adc_cal_characteristics_t

Structure storing ADC characteristics of given v_ref.

The ADC Characteristics structure stores the gain and offset factors of an ESP32 module’s ADC. These factors are calculated using the reference voltage, and the Gain and Offset curves provided in the lookup tables.

Note
Call esp_adc_cal_get_characteristics() to initialize the structure

Public Members

uint32_t v_ref

Reference Voltage of current ESP32 Module in mV

uint32_t gain

Scaling factor used to correct LUT voltages to current v_ref. Bit shifted by << ADC_CAL_GAIN_SCALE for uint32 arithmetic

uint32_t offset

Offset in mV used to correct LUT Voltages to current v_ref

uint32_t ideal_offset

Offset in mV at the ideal reference voltage

adc_bits_width_t bit_width

Bit width of ADC e.g. ADC_WIDTH_12Bit

const esp_adc_cal_lookup_table_t *table

Pointer to LUT

GPIO Lookup Macros

Macros

ADC1_GPIO36_CHANNEL
ADC1_CHANNEL_0_GPIO_NUM
ADC1_GPIO37_CHANNEL
ADC1_CHANNEL_1_GPIO_NUM
ADC1_GPIO38_CHANNEL
ADC1_CHANNEL_2_GPIO_NUM
ADC1_GPIO39_CHANNEL
ADC1_CHANNEL_3_GPIO_NUM
ADC1_GPIO32_CHANNEL
ADC1_CHANNEL_4_GPIO_NUM
ADC1_GPIO33_CHANNEL
ADC1_CHANNEL_5_GPIO_NUM
ADC1_GPIO34_CHANNEL
ADC1_CHANNEL_6_GPIO_NUM
ADC1_GPIO35_CHANNEL
ADC1_CHANNEL_7_GPIO_NUM
ADC2_GPIO4_CHANNEL
ADC2_CHANNEL_0_GPIO_NUM
ADC2_GPIO0_CHANNEL
ADC2_CHANNEL_1_GPIO_NUM
ADC2_GPIO2_CHANNEL
ADC2_CHANNEL_2_GPIO_NUM
ADC2_GPIO15_CHANNEL
ADC2_CHANNEL_3_GPIO_NUM
ADC2_GPIO13_CHANNEL
ADC2_CHANNEL_4_GPIO_NUM
ADC2_GPIO12_CHANNEL
ADC2_CHANNEL_5_GPIO_NUM
ADC2_GPIO14_CHANNEL
ADC2_CHANNEL_6_GPIO_NUM
ADC2_GPIO27_CHANNEL
ADC2_CHANNEL_7_GPIO_NUM
ADC2_GPIO25_CHANNEL
ADC2_CHANNEL_8_GPIO_NUM
ADC2_GPIO26_CHANNEL
ADC2_CHANNEL_9_GPIO_NUM