42 adc_oneshot_unit_init_cfg_t init_config = {};
44 init_config.ulp_mode = ADC_ULP_MODE_DISABLE;
45#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
46 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2
47 init_config.clk_src = ADC_DIGI_CLK_SRC_DEFAULT;
52 ESP_LOGE(TAG,
"Error initializing %s: %d", LOG_STR_ARG(
adc_unit_to_str(this->adc_unit_)), err);
61 adc_oneshot_chan_cfg_t config = {
63 .bitwidth = ADC_BITWIDTH_DEFAULT,
67 ESP_LOGE(TAG,
"Error configuring channel: %d", err);
75 adc_cali_handle_t handle =
nullptr;
77#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
78 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
80 adc_cali_curve_fitting_config_t cali_config = {};
81#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
86 cali_config.bitwidth = ADC_BITWIDTH_DEFAULT;
88 err = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
92 ESP_LOGV(TAG,
"Using curve fitting calibration");
94 ESP_LOGW(TAG,
"Curve fitting calibration failed with error %d, will use uncalibrated readings", err);
98 adc_cali_line_fitting_config_t cali_config = {
101 .bitwidth = ADC_BITWIDTH_DEFAULT,
102#if !defined(USE_ESP32_VARIANT_ESP32S2)
103 .default_vref = 1100,
106 err = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
110 ESP_LOGV(TAG,
"Using line fitting calibration");
112 ESP_LOGW(TAG,
"Line fitting calibration failed with error %d, will use uncalibrated readings", err);
205 auto read_atten = [
this](adc_atten_t atten) -> std::pair<int, float> {
207 adc_oneshot_chan_cfg_t config = {
209 .bitwidth = ADC_BITWIDTH_DEFAULT,
215 ESP_LOGW(TAG,
"Error configuring ADC channel for autorange: %d", err);
222#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
223 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
232 adc_cali_handle_t handle =
nullptr;
234#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
235 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
236 adc_cali_curve_fitting_config_t cali_config = {};
237#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
241 cali_config.atten = atten;
242 cali_config.bitwidth = ADC_BITWIDTH_DEFAULT;
244 err = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
245 ESP_LOGVV(TAG,
"Autorange atten=%d: Calibration handle creation %s (err=%d)", atten,
246 (err == ESP_OK) ?
"SUCCESS" :
"FAILED", err);
248 adc_cali_line_fitting_config_t cali_config = {
251 .bitwidth = ADC_BITWIDTH_DEFAULT,
252#if !defined(USE_ESP32_VARIANT_ESP32S2)
253 .default_vref = 1100,
256 err = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
257 ESP_LOGVV(TAG,
"Autorange atten=%d: Calibration handle creation %s (err=%d)", atten,
258 (err == ESP_OK) ?
"SUCCESS" :
"FAILED", err);
263 ESP_LOGVV(TAG,
"Autorange atten=%d: Raw ADC read %s, value=%d (err=%d)", atten,
264 (err == ESP_OK) ?
"SUCCESS" :
"FAILED",
raw, err);
267 ESP_LOGW(TAG,
"ADC read failed in autorange with error %d", err);
268 if (handle !=
nullptr) {
269#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
270 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
271 adc_cali_delete_scheme_curve_fitting(handle);
273 adc_cali_delete_scheme_line_fitting(handle);
279 float voltage = 0.0f;
280 if (handle !=
nullptr) {
282 err = adc_cali_raw_to_voltage(handle,
raw, &voltage_mv);
284 voltage = voltage_mv / 1000.0f;
285 ESP_LOGVV(TAG,
"Autorange atten=%d: CALIBRATED - raw=%d -> %dmV -> %.6fV", atten,
raw, voltage_mv, voltage);
287 voltage =
raw * 3.3f / 4095.0f;
288 ESP_LOGVV(TAG,
"Autorange atten=%d: UNCALIBRATED FALLBACK - raw=%d -> %.6fV (3.3V ref)", atten,
raw, voltage);
291#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
292 USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
293 adc_cali_delete_scheme_curve_fitting(handle);
295 adc_cali_delete_scheme_line_fitting(handle);
298 voltage =
raw * 3.3f / 4095.0f;
299 ESP_LOGVV(TAG,
"Autorange atten=%d: NO CALIBRATION - raw=%d -> %.6fV (3.3V ref)", atten,
raw, voltage);
302 return {
raw, voltage};
305 auto [raw12, mv12] = read_atten(ADC_ATTEN_DB_12);
307 ESP_LOGE(TAG,
"Failed to read ADC in autorange mode");
311 int raw6 = 4095, raw2 = 4095, raw0 = 4095;
312 float mv6 = 0, mv2 = 0, mv0 = 0;
315 auto [raw6_val, mv6_val] = read_atten(ADC_ATTEN_DB_6);
319 if (raw6 < 4095 && raw6 != -1) {
320 auto [raw2_val, mv2_val] = read_atten(ADC_ATTEN_DB_2_5);
324 if (raw2 < 4095 && raw2 != -1) {
325 auto [raw0_val, mv0_val] = read_atten(ADC_ATTEN_DB_0);
332 if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw12 == -1) {
336 const int adc_half = 2048;
337 const uint32_t c12 = std::min(raw12, adc_half);
339 const int32_t c6_signed = adc_half - std::abs(raw6 - adc_half);
340 const uint32_t c6 = (c6_signed > 0) ? c6_signed : 0;
342 const int32_t c2_signed = adc_half - std::abs(raw2 - adc_half);
343 const uint32_t c2 = (c2_signed > 0) ? c2_signed : 0;
345 const uint32_t c0 = std::min(4095 - raw0, adc_half);
346 const uint32_t csum = c12 + c6 + c2 + c0;
348 ESP_LOGVV(TAG,
"Autorange summary:");
349 ESP_LOGVV(TAG,
" Raw readings: 12db=%d, 6db=%d, 2.5db=%d, 0db=%d", raw12, raw6, raw2, raw0);
350 ESP_LOGVV(TAG,
" Voltages: 12db=%.6f, 6db=%.6f, 2.5db=%.6f, 0db=%.6f", mv12, mv6, mv2, mv0);
351 ESP_LOGVV(TAG,
" Coefficients: c12=%u, c6=%u, c2=%u, c0=%u, sum=%u", c12, c6, c2, c0, csum);
354 ESP_LOGE(TAG,
"Invalid weight sum in autorange calculation");
358 const float final_result = (mv12 * c12 + mv6 * c6 + mv2 * c2 + mv0 * c0) / csum;
359 ESP_LOGV(TAG,
"Autorange final: (%.6f*%u + %.6f*%u + %.6f*%u + %.6f*%u)/%u = %.6fV", mv12, c12, mv6, c6, mv2, c2, mv0,
360 c0, csum, final_result);