Analog to Digital Converter (ADC) Calibration Driver
Introduction
This guide introduces the ADC calibration driver to convert ADC raw results into more accurate voltage values in millivolts. After creating a calibration scheme, call adc_cali_chan_raw_to_voltage().
Functional Overview
The following sections of this document cover the typical steps to install and use the ADC calibration driver:
Calibration Scheme Creation - covers how to create a calibration scheme handle and delete the calibration scheme handle.
Result Conversion - covers how to convert ADC raw result to calibrated result.
Thread Safety - lists which APIs are guaranteed to be thread-safe by the driver.
Minimize Noise - describes a general way to minimize the noise.
Calibration Scheme Creation
The ADC calibration driver provides ADC calibration scheme(s). From the calibration driver's point of view, an ADC calibration scheme is created for an ADC calibration handle adc_cali_handle_t.
adc_cali_check_scheme() can be used to know which calibration scheme is supported on the chip. If you already know the supported schemes, this step can be skipped. Just call the corresponding function to create the scheme handle.
If you use your custom ADC calibration schemes, you could either modify this function adc_cali_check_scheme(), or just skip this step and call your custom creation function.
ADC Calibration Line Fitting Scheme
ESP32-S31 supports ADC_CALI_SCHEME_VER_LINE_FITTING scheme. To create this scheme, set up adc_cali_line_fitting_config_t first.
adc_cali_line_fitting_config_t::unit_id, the ADC that your ADC raw results are from.adc_cali_line_fitting_config_t::atten, ADC attenuation that your ADC raw results use.adc_cali_line_fitting_config_t::bitwidth, bit width of ADC raw result.
Only ADC_ATTEN_DB_0 is supported. Convert the raw result with adc_cali_chan_raw_to_voltage(). Each channel belongs to one side of a differential pair: even-numbered channels are N-side (polarity inverted in single-ended use), odd-numbered channels are P-side. If the calibration eFuse is not burnt, scheme creation still succeeds and applies an identity transform (k = 1, b = 0).
After setting up the configuration structure, call adc_cali_create_scheme_line_fitting() to create a Line Fitting calibration scheme handle.
ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting");
adc_cali_line_fitting_config_t cali_config = {
.unit_id = unit,
.atten = atten,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting(&cali_config, &handle));
When the ADC calibration is no longer used, please delete the calibration scheme handle by calling adc_cali_delete_scheme_line_fitting().
Delete Line Fitting Scheme
ESP_LOGI(TAG, "delete %s calibration scheme", "Line Fitting");
ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle));
Note
If you want to use your custom calibration schemes, you could provide a creation function to create your calibration scheme handle. Check the function table adc_cali_scheme_t in components/esp_adc/interface/adc_cali_interface.h to know the ESP ADC calibration interface.
Result Conversion
After setting up the calibration characteristics, convert the ADC raw result into a calibrated result in mV.
The raw result is a 17-bit comparator vector. Call adc_cali_chan_raw_to_voltage() and pass the ADC channel that produced the raw result. Even-numbered channels are N-side and odd-numbered channels are P-side.
These functions may fail due to an invalid argument. Especially, if they return ESP_ERR_INVALID_STATE, this means the calibration scheme is not created. You need to create a calibration scheme handle, use adc_cali_check_scheme() to know the supported calibration scheme. On the other hand, you could also provide a custom calibration scheme and create the handle.
Get Voltage
ESP_ERROR_CHECK(adc_cali_chan_raw_to_voltage(adc_cali_handle, EXAMPLE_ADC1_CHAN0, adc_raw[0][0], &voltage[0][0]));
ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]);
Thread Safety
The factory functions adc_cali_create_scheme_line_fitting() and adc_cali_create_scheme_curve_fitting() are guaranteed to be thread-safe by the driver. Therefore, you can call them from different RTOS tasks without protection by extra locks.
Other functions that take the adc_cali_handle_t as the first positional parameter are not thread-safe, you should avoid calling them from multiple tasks.
Minimize Noise
The ESP32-S31 ADC is sensitive to noise, leading to large discrepancies in ADC readings. Depending on the usage scenario, you may need to connect a bypass capacitor (e.g., a 100 nF ceramic capacitor) to the ADC input pad in use, to minimize noise. Besides, multisampling may also be used to further mitigate the effects of noise.
API Reference
Header File
This header file can be included with:
#include "esp_adc/adc_cali.h"
This header file is a part of the API provided by the
esp_adccomponent. To declare that your component depends onesp_adc, add the following to your CMakeLists.txt:REQUIRES esp_adc
or
PRIV_REQUIRES esp_adc
Functions
-
esp_err_t adc_cali_check_scheme(adc_cali_scheme_ver_t *scheme_mask)
Check the supported ADC calibration scheme.
- Parameters:
scheme_mask -- [out] Supported ADC calibration scheme(s)
- Returns:
ESP_OK: On success
ESP_ERR_INVALID_ARG: Invalid argument
ESP_ERR_NOT_SUPPORTED: No supported calibration scheme
-
esp_err_t adc_cali_raw_to_voltage(adc_cali_handle_t handle, int raw, int *voltage)
Convert ADC raw data to calibrated voltage.
Note
Schemes that apply channel-dependent corrections cannot do so here. Use
adc_cali_chan_raw_to_voltage()when the conversion depends on the ADC channel.Note
On ESP32-S31 this function is not supported and returns
ESP_ERR_NOT_SUPPORTED. Useadc_cali_chan_raw_to_voltage().- Parameters:
handle -- [in] ADC calibration handle
raw -- [in] ADC raw data
voltage -- [out] Calibrated ADC voltage (in mV)
- Returns:
ESP_OK: On success
ESP_ERR_INVALID_ARG: Invalid argument
ESP_ERR_INVALID_STATE: Invalid state, scheme didn't registered
ESP_ERR_NOT_SUPPORTED: Scheme requires the channel-aware conversion API
-
esp_err_t adc_cali_chan_raw_to_voltage(adc_cali_handle_t handle, adc_channel_t channel, int raw, int *voltage)
Convert ADC raw data to calibrated voltage (channel-aware)
Compared with
adc_cali_raw_to_voltage(), this takes the ADC channel the raw data was sampled from, so schemes that need it can apply channel-dependent corrections.Note
On ESP32-S31,
rawis a 17-bit comparator vector. Even-numbered channels are N-side and odd-numbered channels are P-side.- Parameters:
handle -- [in] ADC calibration handle
channel -- [in] ADC channel the raw data was sampled from
raw -- [in] ADC raw data
voltage -- [out] Calibrated ADC voltage (in mV)
- Returns:
ESP_OK: On success
ESP_ERR_INVALID_ARG: Invalid argument
ESP_ERR_INVALID_STATE: Invalid state, scheme didn't registered
Type Definitions
-
typedef struct adc_cali_scheme_t *adc_cali_handle_t
ADC calibration handle.
Enumerations
Header File
This header file can be included with:
#include "esp_adc/adc_cali_scheme.h"
This header file is a part of the API provided by the
esp_adccomponent. To declare that your component depends onesp_adc, add the following to your CMakeLists.txt:REQUIRES esp_adc
or
PRIV_REQUIRES esp_adc