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 supports ADC1 (9 channels, attached to GPIOs 32 - 39), and ADC2 (10 channels, attached to GPIOs 0, 2, 4, 12 - 15 and 25 - 27). However, there’re some restrictions for the application to use ADC2:
The application can use ADC2 only when Wi-Fi driver is not started, since the ADC is also used by the Wi-Fi driver, which has higher priority.
Some of the ADC2 pins are used as strapping pins (GPIO 0, 2, 15), so they cannot be used freely. For examples, for official Develop Kits:
ESP32 Core Board V2 / ESP32 DevKitC: GPIO 0 cannot be used due to external auto program circuits.
ESP-WROVER-KIT V3: GPIO 0, 2, 4 and 15 cannot be used due to external connections for different purposes.
Using the ESP32 ADC
For the function that improves the default ADC reading accuracy to within 1%
https://github.com/G6EJD/ESP32-ADC-Accuracy-Improvement-function
The ADC should be configured before reading is taken.
For ADC1, configure desired precision and attenuation by calling functions adc1_config_width() and adc1_config_channel_atten().
For ADC2, configure the attenuation by adc2_config_channel_atten(). The reading width of ADC2 is configured every time you take the reading.
Attenuation configuration is done per channel, see adc1_channel_t and adc2_channel_t, set as a parameter of above functions.
Then it is possible to read ADC conversion result with adc1_get_raw() and adc2_get_raw(). Reading width of ADC2 should be set as a parameter of adc2_get_raw() instead of in the configuration functions.
Note
Since the ADC2 is shared with the WIFI module, which has higher priority, reading operation of adc2_get_raw() will fail between esp_wifi_start() and esp_wifi_stop(). Use the return code to see whether the reading is successful.
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.
Reading voltage on ADC1 channel 0 (GPIO 36):
#include <driver/adc.h>... adc1_config_width(ADC_WIDTH_BIT_12); adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_0); 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. An example using the ADC driver including calibration (discussed below) is available in esp-idf: peripherals/adc
Reading voltage on ADC2 channel 7 (GPIO 27):
#include <driver/adc.h>... int read_raw; adc2_config_channel_atten( ADC2_CHANNEL_7, ADC_ATTEN_0db ); esp_err_t r = adc2_get_raw( ADC2_CHANNEL_7, ADC_WIDTH_12Bit, &read_raw); if ( r == ESP_OK ) { printf("%d\n", read_raw ); } else if ( r == ESP_ERR_TIMEOUT ) { printf("ADC2 used by Wi-Fi.\n"); }
The reading may fail due to collision with Wi-Fi, should check it. An example using the ADC2 driver to read the output of DAC is available in esp-idf: peripherals/adc2
Reading the internal hall effect sensor:
#include <driver/adc.h>... adc1_config_width(ADC_WIDTH_BIT_12); int val = hall_sensor_read();
The value read in both these examples is 12 bits wide (range 0-4095).
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.
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_DB_11, ADC_WIDTH_BIT_12, &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
There are macros available to specify the GPIO number of a ADC channel, or vice versa. e.g.
ADC1_CHANNEL_0_GPIO_NUM is the GPIO number of ADC1 channel 0 (36);
ADC1_GPIO32_CHANNEL is the ADC1 channel number of GPIO 32 (ADC1 channel 4).
This reference covers three components:
esp_err_t adc1_pad_get_io_num(adc1_channel_tchannel, gpio_num_t *gpio_num)
esp_err_t adc1_config_width(adc_bits_width_twidth_bit)
int adc1_get_raw(adc1_channel_tchannel)
void adc_power_on()
void adc_power_off()
esp_err_t adc_gpio_init(adc_unit_tadc_unit, adc_channel_tchannel)
esp_err_t adc_set_data_inv(adc_unit_tadc_unit, bool inv_en)
esp_err_t adc_set_clk_div(uint8_t clk_div)
esp_err_t adc_set_i2s_data_source(adc_i2s_source_tsrc)
esp_err_t adc_i2s_mode_init(adc_unit_tadc_unit, adc_channel_tchannel)
void adc1_ulp_enable()
int hall_sensor_read()
esp_err_t adc2_vref_to_gpio(gpio_num_tgpio)
Get the gpio number of a specific ADC1 channel.
ESP_OK if success
ESP_ERR_INVALID_ARG if channal not valid
channel: Channel to get the gpio number
gpio_num: output buffer to hold the gpio number
Configure ADC1 capture width, meanwhile enable output invert for ADC1. The configuration is for all channels of ADC1.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
width_bit: Bit capture width for ADC1
Configure ADC capture width.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
adc_unit: ADC unit index
width_bit: Bit capture width for ADC unit.
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.
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_DB_0) gives full-scale voltage 1.1V
2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
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.)
At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
channel: ADC1 channel to configure
atten: Attenuation level
Take an ADC1 reading on a single channel.
Call adc1_config_width() before the first time this function is called.
For a given channel, adc1_config_channel_atten(channel) must be called before the first time this function is called.
-1: Parameter error
Other: ADC1 channel reading.
channel: ADC1 channel to read
Power on SAR ADC.
Power off SAR ADC.
Initialize ADC pad.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
adc_unit: ADC unit index
channel: ADC channel index
Set ADC data invert.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
adc_unit: ADC unit index
inv_en: whether enable data invert
Set ADC source clock.
ESP_OK success
clk_div: ADC clock divider, ADC clock is divided from APB clock
Set I2S data source.
ESP_OK success
src: I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
Initialize I2S ADC mode.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
adc_unit: ADC unit index
channel: ADC channel index
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.
Read Hall Sensor.
The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure these channels for use as ADC channels.
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.
The hall sensor reading.
Get the gpio number of a specific ADC2 channel.
ESP_OK if success
ESP_ERR_INVALID_ARG if channal not valid
channel: Channel to get the gpio number
gpio_num: output buffer to hold the gpio number
Configure the ADC2 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.
This function also configures the input GPIO pin mux to connect it to the ADC2 channel. It must be called before calling adc2_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)
The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC2 configured bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
ESP_OK success
ESP_ERR_INVALID_ARG Parameter error
channel: ADC2 channel to configure
atten: Attenuation level
Take an ADC2 reading on a single channel.
For a given channel, adc2_config_channel_atten() must be called before the first time this function is called. If Wi-Fi is started via esp_wifi_start(), this function will always fail with ESP_ERR_TIMEOUT.
ESP_OK if success
ESP_ERR_TIMEOUT the WIFI is started, using the ADC2
channel: ADC2 channel to read
width_bit: Bit capture width for ADC2
raw_out: the variable to hold the output data.
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.
ESP_OK: v_ref successfully routed to selected gpio
ESP_ERR_INVALID_ARG: Unsupported gpio
gpio: GPIO number (gpios 25,26,27 supported)
esp_err_t adc_set_data_width(adc_unit_tadc_unit, adc_bits_width_twidth_bit)
esp_err_t adc2_config_channel_atten(adc2_channel_tchannel, adc_atten_tatten)
esp_err_t adc1_config_channel_atten(adc1_channel_tchannel, adc_atten_tatten)
esp_err_t adc2_pad_get_io_num(adc2_channel_tchannel, gpio_num_t *gpio_num)
esp_err_t adc2_get_raw(adc2_channel_tchannel, adc_bits_width_twidth_bit, int *raw_out)
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Return
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Parameters
Note
Note
Note
Note
Note
Note
Note
Note
Note
Note
Note
ADC_ATTEN_0db
ADC_ATTEN_2_5db
ADC_ATTEN_6db
ADC_ATTEN_11db
ADC_WIDTH_9Bit
ADC_WIDTH_10Bit
ADC_WIDTH_11Bit
ADC_WIDTH_12Bit
enumadc_atten_t
Values:
The input voltage of ADC will be reduced to about 1/1
The input voltage of ADC will be reduced to about 1/1.34
The input voltage of ADC will be reduced to about 1/2
The input voltage of ADC will be reduced to about 1/3.6
Values:
ADC capture width is 9Bit
ADC capture width is 10Bit
ADC capture width is 11Bit
ADC capture width is 12Bit
Values:
ADC1 channel 0 is GPIO36
ADC1 channel 1 is GPIO37
ADC1 channel 2 is GPIO38
ADC1 channel 3 is GPIO39
ADC1 channel 4 is GPIO32
ADC1 channel 5 is GPIO33
ADC1 channel 6 is GPIO34
ADC1 channel 7 is GPIO35
Values:
ADC2 channel 0 is GPIO4
ADC2 channel 1 is GPIO0
ADC2 channel 2 is GPIO2
ADC2 channel 3 is GPIO15
ADC2 channel 4 is GPIO13
ADC2 channel 5 is GPIO12
ADC2 channel 6 is GPIO14
ADC2 channel 7 is GPIO27
ADC2 channel 8 is GPIO25
ADC2 channel 9 is GPIO26
Values:
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
ADC channel
Values:
SAR ADC 1
SAR ADC 2, not supported yet
SAR ADC 1 and 2, not supported yet
SAR ADC 1 and 2 alternative mode, not supported yet
Values:
ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data
ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data
Values:
I2S data from GPIO matrix signal
I2S data from ADC
enumadc_i2s_source_t
enumadc_i2s_encode_t
enumadc_bits_width_t
enumadc2_channel_t
enumadc1_channel_t
enumadc_channel_t
enumadc_unit_t
ADC_CHANNEL_9
ADC_CHANNEL_8
ADC_CHANNEL_7
ADC_CHANNEL_6
ADC_CHANNEL_5
ADC_CHANNEL_4
ADC_CHANNEL_3
ADC_CHANNEL_2
ADC_CHANNEL_1
ADC_WIDTH_MAX
ADC_ATTEN_MAX
ADC_ENCODE_MAX
ADC2_CHANNEL_9
ADC2_CHANNEL_8
ADC2_CHANNEL_7
ADC2_CHANNEL_6
ADC2_CHANNEL_5
ADC2_CHANNEL_4
ADC2_CHANNEL_3
ADC2_CHANNEL_2
ADC2_CHANNEL_1
ADC1_CHANNEL_7
ADC1_CHANNEL_6
ADC1_CHANNEL_5
ADC1_CHANNEL_4
ADC1_CHANNEL_3
ADC1_CHANNEL_2
ADC1_CHANNEL_1
ADC_ENCODE_11BIT
ADC_ENCODE_12BIT
ADC2_CHANNEL_MAX
ADC1_CHANNEL_MAX
ADC_UNIT_BOTH = 3
ADC_CHANNEL_0 = 0
ADC_CHANNEL_MAX
ADC_UNIT_2 = 2
ADC_UNIT_1 = 1
ADC_UNIT_MAX
ADC_UNIT_ALTER = 7
ADC2_CHANNEL_0 = 0
ADC1_CHANNEL_0 = 0
ADC_ATTEN_DB_6 = 2
ADC_ATTEN_DB_0 = 0
ADC_WIDTH_BIT_12 = 3
ADC_WIDTH_BIT_11 = 2
ADC_WIDTH_BIT_10 = 1
ADC_ATTEN_DB_2_5 = 1
ADC_WIDTH_BIT_9 = 0
ADC_ATTEN_DB_11 = 3
ADC_I2S_DATA_SRC_IO_SIG = 0
ADC_I2S_DATA_SRC_ADC = 1
ADC_I2S_DATA_SRC_MAX
void esp_adc_cal_get_characteristics(uint32_t v_ref, adc_atten_tatten, adc_bits_width_tbit_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.
reference voltage of the ADCs can be routed to GPIO using adc2_vref_to_gpio() from the ADC driver
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
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
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.
Calculated voltage in mV
characteristics structure must be initialized using esp_adc_cal_get_characteristics() before this function is used
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
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().
voltage Calculated voltage in mV
ADC must be initialized using adc1_config_width() and adc1_config_channel_atten() before this function is used
characteristics structure must be initialized using esp_adc_cal_get_characteristics() before this function is used
channel: Channel of ADC1 to measure
chars: Pointer to ADC characteristics struct
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.
A seperate LUT is provided for each attenuation and are defined in esp_adc_cal_lookup_tables.c
Public Members
Gradient of Gain Curve
Offset of Gain Curve
Gradient of Offset Curve
Offset of Offset Curve
Bit shift used find corresponding LUT points given an ADC reading
Array of voltages in mV representing the ADC-Voltage curve
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.
Call esp_adc_cal_get_characteristics() to initialize the structure
Public Members
Reference Voltage of current ESP32 Module in mV
Scaling factor used to correct LUT voltages to current v_ref. Bit shifted by << ADC_CAL_GAIN_SCALE for uint32 arithmetic
Offset in mV used to correct LUT Voltages to current v_ref
Offset in mV at the ideal reference voltage
Bit width of ADC e.g. ADC_WIDTH_BIT_12
Pointer to LUT
uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc, constesp_adc_cal_characteristics_t *chars)
uint32_t adc1_to_voltage(adc1_channel_tchannel, constesp_adc_cal_characteristics_t *chars)
structesp_adc_cal_lookup_table_t
structesp_adc_cal_characteristics_t
Note
Note
Note
Note
Note
Note
Note
Parameters
Parameters
Parameters
Return
Return
uint32_t offset
uint32_t gain_c
uint32_t gain_m
uint32_t offset_c
uint32_t offset_m
uint32_t v_ref
uint32_t gain
uint32_t bit_shift
uint32_t voltage[]
uint32_t ideal_offset
adc_bits_width_tbit_width
constesp_adc_cal_lookup_table_t *table
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