mirror of
https://github.com/esphome/esphome.git
synced 2026-05-28 21:59:59 +08:00
[adc] Fix ESP32-C2 ADC calibration to use line fitting (#13756)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,10 +74,9 @@ void ADCSensor::setup() {
|
|||||||
if (this->calibration_handle_ == nullptr) {
|
if (this->calibration_handle_ == nullptr) {
|
||||||
adc_cali_handle_t handle = nullptr;
|
adc_cali_handle_t handle = nullptr;
|
||||||
|
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
// RISC-V variants (except C2) and S3 use curve fitting calibration
|
||||||
// RISC-V variants and S3 use curve fitting calibration
|
|
||||||
adc_cali_curve_fitting_config_t cali_config = {}; // Zero initialize first
|
adc_cali_curve_fitting_config_t cali_config = {}; // Zero initialize first
|
||||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||||
cali_config.chan = this->channel_;
|
cali_config.chan = this->channel_;
|
||||||
@@ -95,14 +94,14 @@ void ADCSensor::setup() {
|
|||||||
ESP_LOGW(TAG, "Curve fitting calibration failed with error %d, will use uncalibrated readings", err);
|
ESP_LOGW(TAG, "Curve fitting calibration failed with error %d, will use uncalibrated readings", err);
|
||||||
this->setup_flags_.calibration_complete = false;
|
this->setup_flags_.calibration_complete = false;
|
||||||
}
|
}
|
||||||
#else // Other ESP32 variants use line fitting calibration
|
#else // ESP32, ESP32-S2, and ESP32-C2 use line fitting calibration
|
||||||
adc_cali_line_fitting_config_t cali_config = {
|
adc_cali_line_fitting_config_t cali_config = {
|
||||||
.unit_id = this->adc_unit_,
|
.unit_id = this->adc_unit_,
|
||||||
.atten = this->attenuation_,
|
.atten = this->attenuation_,
|
||||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
#if !defined(USE_ESP32_VARIANT_ESP32S2)
|
#if !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32C2)
|
||||||
.default_vref = 1100, // Default reference voltage in mV
|
.default_vref = 1100, // Default reference voltage in mV
|
||||||
#endif // !defined(USE_ESP32_VARIANT_ESP32S2)
|
#endif // !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32C2)
|
||||||
};
|
};
|
||||||
err = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
|
err = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
@@ -113,7 +112,7 @@ void ADCSensor::setup() {
|
|||||||
ESP_LOGW(TAG, "Line fitting calibration failed with error %d, will use uncalibrated readings", err);
|
ESP_LOGW(TAG, "Line fitting calibration failed with error %d, will use uncalibrated readings", err);
|
||||||
this->setup_flags_.calibration_complete = false;
|
this->setup_flags_.calibration_complete = false;
|
||||||
}
|
}
|
||||||
#endif // USE_ESP32_VARIANT_ESP32C2 || ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
|
#endif // ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
|
||||||
}
|
}
|
||||||
|
|
||||||
this->setup_flags_.init_complete = true;
|
this->setup_flags_.init_complete = true;
|
||||||
@@ -185,13 +184,12 @@ float ADCSensor::sample_fixed_attenuation_() {
|
|||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "ADC calibration conversion failed with error %d, disabling calibration", err);
|
ESP_LOGW(TAG, "ADC calibration conversion failed with error %d, disabling calibration", err);
|
||||||
if (this->calibration_handle_ != nullptr) {
|
if (this->calibration_handle_ != nullptr) {
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
|
||||||
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
||||||
#else // Other ESP32 variants use line fitting calibration
|
#else // Other ESP32 variants use line fitting calibration
|
||||||
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
||||||
#endif // USE_ESP32_VARIANT_ESP32C2 || ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
|
#endif // ESP32C3 || ESP32C5 || ESP32C6 || ESP32C61 || ESP32H2 || ESP32P4 || ESP32S3
|
||||||
this->calibration_handle_ = nullptr;
|
this->calibration_handle_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,9 +217,8 @@ float ADCSensor::sample_autorange_() {
|
|||||||
// Need to recalibrate for the new attenuation
|
// Need to recalibrate for the new attenuation
|
||||||
if (this->calibration_handle_ != nullptr) {
|
if (this->calibration_handle_ != nullptr) {
|
||||||
// Delete old calibration handle
|
// Delete old calibration handle
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
|
||||||
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
adc_cali_delete_scheme_curve_fitting(this->calibration_handle_);
|
||||||
#else
|
#else
|
||||||
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
adc_cali_delete_scheme_line_fitting(this->calibration_handle_);
|
||||||
@@ -232,9 +229,8 @@ float ADCSensor::sample_autorange_() {
|
|||||||
// Create new calibration handle for this attenuation
|
// Create new calibration handle for this attenuation
|
||||||
adc_cali_handle_t handle = nullptr;
|
adc_cali_handle_t handle = nullptr;
|
||||||
|
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
|
||||||
adc_cali_curve_fitting_config_t cali_config = {};
|
adc_cali_curve_fitting_config_t cali_config = {};
|
||||||
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||||
cali_config.chan = this->channel_;
|
cali_config.chan = this->channel_;
|
||||||
@@ -251,7 +247,7 @@ float ADCSensor::sample_autorange_() {
|
|||||||
.unit_id = this->adc_unit_,
|
.unit_id = this->adc_unit_,
|
||||||
.atten = atten,
|
.atten = atten,
|
||||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
#if !defined(USE_ESP32_VARIANT_ESP32S2)
|
#if !defined(USE_ESP32_VARIANT_ESP32S2) && !defined(USE_ESP32_VARIANT_ESP32C2)
|
||||||
.default_vref = 1100,
|
.default_vref = 1100,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -268,9 +264,8 @@ float ADCSensor::sample_autorange_() {
|
|||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGW(TAG, "ADC read failed in autorange with error %d", err);
|
ESP_LOGW(TAG, "ADC read failed in autorange with error %d", err);
|
||||||
if (handle != nullptr) {
|
if (handle != nullptr) {
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
|
||||||
adc_cali_delete_scheme_curve_fitting(handle);
|
adc_cali_delete_scheme_curve_fitting(handle);
|
||||||
#else
|
#else
|
||||||
adc_cali_delete_scheme_line_fitting(handle);
|
adc_cali_delete_scheme_line_fitting(handle);
|
||||||
@@ -291,9 +286,8 @@ float ADCSensor::sample_autorange_() {
|
|||||||
ESP_LOGVV(TAG, "Autorange atten=%d: UNCALIBRATED FALLBACK - raw=%d -> %.6fV (3.3V ref)", atten, raw, voltage);
|
ESP_LOGVV(TAG, "Autorange atten=%d: UNCALIBRATED FALLBACK - raw=%d -> %.6fV (3.3V ref)", atten, raw, voltage);
|
||||||
}
|
}
|
||||||
// Clean up calibration handle
|
// Clean up calibration handle
|
||||||
#if USE_ESP32_VARIANT_ESP32C2 || USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || \
|
#if USE_ESP32_VARIANT_ESP32C3 || USE_ESP32_VARIANT_ESP32C5 || USE_ESP32_VARIANT_ESP32C6 || \
|
||||||
USE_ESP32_VARIANT_ESP32C6 || USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || \
|
USE_ESP32_VARIANT_ESP32C61 || USE_ESP32_VARIANT_ESP32H2 || USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
||||||
USE_ESP32_VARIANT_ESP32P4 || USE_ESP32_VARIANT_ESP32S3
|
|
||||||
adc_cali_delete_scheme_curve_fitting(handle);
|
adc_cali_delete_scheme_curve_fitting(handle);
|
||||||
#else
|
#else
|
||||||
adc_cali_delete_scheme_line_fitting(handle);
|
adc_cali_delete_scheme_line_fitting(handle);
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
sensor:
|
||||||
|
- id: my_sensor
|
||||||
|
platform: adc
|
||||||
|
pin: GPIO1
|
||||||
|
name: ADC Test sensor
|
||||||
|
update_interval: "1:01"
|
||||||
|
attenuation: 2.5db
|
||||||
|
unit_of_measurement: "°C"
|
||||||
|
icon: "mdi:water-percent"
|
||||||
|
accuracy_decimals: 5
|
||||||
|
setup_priority: -100
|
||||||
|
force_update: true
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
esphome:
|
||||||
|
name: componenttestesp32c2idf
|
||||||
|
friendly_name: $component_name
|
||||||
|
|
||||||
|
esp32:
|
||||||
|
board: esp32-c2-devkitm-1
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
# Use custom partition table with larger app partition (3MB)
|
||||||
|
# Default IDF partitions only allow 1.75MB which is too small for grouped tests
|
||||||
|
partitions: ../partitions_testing.csv
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: VERY_VERBOSE
|
||||||
|
|
||||||
|
packages:
|
||||||
|
component_under_test: !include
|
||||||
|
file: $component_test_file
|
||||||
|
vars:
|
||||||
|
component_test_file: $component_test_file
|
||||||
Reference in New Issue
Block a user