mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Add ADC multisampling (#6330)
This commit is contained in:
parent
f46c499c4e
commit
247b2eee30
3 changed files with 112 additions and 72 deletions
|
@ -46,27 +46,27 @@ extern "C"
|
||||||
ADCSensor::setup() {
|
ADCSensor::setup() {
|
||||||
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
||||||
#if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040)
|
#if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040)
|
||||||
pin_->setup();
|
this->pin_->setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
if (channel1_ != ADC1_CHANNEL_MAX) {
|
if (this->channel1_ != ADC1_CHANNEL_MAX) {
|
||||||
adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
|
adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
|
||||||
if (!autorange_) {
|
if (!this->autorange_) {
|
||||||
adc1_config_channel_atten(channel1_, attenuation_);
|
adc1_config_channel_atten(this->channel1_, this->attenuation_);
|
||||||
}
|
}
|
||||||
} else if (channel2_ != ADC2_CHANNEL_MAX) {
|
} else if (this->channel2_ != ADC2_CHANNEL_MAX) {
|
||||||
if (!autorange_) {
|
if (!this->autorange_) {
|
||||||
adc2_config_channel_atten(channel2_, attenuation_);
|
adc2_config_channel_atten(this->channel2_, this->attenuation_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load characteristics for each attenuation
|
// load characteristics for each attenuation
|
||||||
for (int32_t i = 0; i <= ADC_ATTEN_DB_12_COMPAT; i++) {
|
for (int32_t i = 0; i <= ADC_ATTEN_DB_12_COMPAT; i++) {
|
||||||
auto adc_unit = channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
|
auto adc_unit = this->channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
|
||||||
auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
|
auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
|
||||||
1100, // default vref
|
1100, // default vref
|
||||||
&cal_characteristics_[i]);
|
&this->cal_characteristics_[i]);
|
||||||
switch (cal_value) {
|
switch (cal_value) {
|
||||||
case ESP_ADC_CAL_VAL_EFUSE_VREF:
|
case ESP_ADC_CAL_VAL_EFUSE_VREF:
|
||||||
ESP_LOGV(TAG, "Using eFuse Vref for calibration");
|
ESP_LOGV(TAG, "Using eFuse Vref for calibration");
|
||||||
|
@ -99,27 +99,27 @@ void ADCSensor::dump_config() {
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||||
#else
|
#else
|
||||||
LOG_PIN(" Pin: ", pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
#endif
|
#endif
|
||||||
#endif // USE_ESP8266 || USE_LIBRETINY
|
#endif // USE_ESP8266 || USE_LIBRETINY
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
LOG_PIN(" Pin: ", pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
if (autorange_) {
|
if (this->autorange_) {
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: auto");
|
ESP_LOGCONFIG(TAG, " Attenuation: auto");
|
||||||
} else {
|
} else {
|
||||||
switch (this->attenuation_) {
|
switch (this->attenuation_) {
|
||||||
case ADC_ATTEN_DB_0:
|
case ADC_ATTEN_DB_0:
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: 0db");
|
ESP_LOGCONFIG(TAG, " Attenuation: 0db");
|
||||||
break;
|
break;
|
||||||
case ADC_ATTEN_DB_2_5:
|
case ADC_ATTEN_DB_2_5:
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: 2.5db");
|
ESP_LOGCONFIG(TAG, " Attenuation: 2.5db");
|
||||||
break;
|
break;
|
||||||
case ADC_ATTEN_DB_6:
|
case ADC_ATTEN_DB_6:
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: 6db");
|
ESP_LOGCONFIG(TAG, " Attenuation: 6db");
|
||||||
break;
|
break;
|
||||||
case ADC_ATTEN_DB_12_COMPAT:
|
case ADC_ATTEN_DB_12_COMPAT:
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: 12db");
|
ESP_LOGCONFIG(TAG, " Attenuation: 12db");
|
||||||
break;
|
break;
|
||||||
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
||||||
break;
|
break;
|
||||||
|
@ -134,11 +134,11 @@ void ADCSensor::dump_config() {
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||||
#else
|
#else
|
||||||
LOG_PIN(" Pin: ", pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
#endif // USE_ADC_SENSOR_VCC
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
}
|
}
|
||||||
#endif // USE_RP2040
|
#endif // USE_RP2040
|
||||||
|
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,14 +149,24 @@ void ADCSensor::update() {
|
||||||
this->publish_state(value_v);
|
this->publish_state(value_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ADCSensor::set_sample_count(uint8_t sample_count) {
|
||||||
|
if (sample_count != 0) {
|
||||||
|
this->sample_count_ = sample_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
|
uint32_t raw = 0;
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
int32_t raw = ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
raw += ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
||||||
#else
|
#else
|
||||||
int32_t raw = analogRead(this->pin_->get_pin()); // NOLINT
|
raw += analogRead(this->pin_->get_pin()); // NOLINT
|
||||||
#endif
|
#endif
|
||||||
if (output_raw_) {
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
if (this->output_raw_) {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
return raw / 1024.0f;
|
return raw / 1024.0f;
|
||||||
|
@ -165,53 +175,57 @@ float ADCSensor::sample() {
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
if (!autorange_) {
|
if (!this->autorange_) {
|
||||||
int raw = -1;
|
uint32_t sum = 0;
|
||||||
if (channel1_ != ADC1_CHANNEL_MAX) {
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
raw = adc1_get_raw(channel1_);
|
int raw = -1;
|
||||||
} else if (channel2_ != ADC2_CHANNEL_MAX) {
|
if (this->channel1_ != ADC1_CHANNEL_MAX) {
|
||||||
adc2_get_raw(channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw);
|
raw = adc1_get_raw(this->channel1_);
|
||||||
|
} else if (this->channel2_ != ADC2_CHANNEL_MAX) {
|
||||||
|
adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw);
|
||||||
|
}
|
||||||
|
if (raw == -1) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
sum += raw;
|
||||||
}
|
}
|
||||||
|
sum = (sum + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
if (raw == -1) {
|
if (this->output_raw_) {
|
||||||
return NAN;
|
return sum;
|
||||||
}
|
}
|
||||||
if (output_raw_) {
|
uint32_t mv = esp_adc_cal_raw_to_voltage(sum, &this->cal_characteristics_[(int32_t) this->attenuation_]);
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int32_t) attenuation_]);
|
|
||||||
return mv / 1000.0f;
|
return mv / 1000.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int raw12 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
|
int raw12 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
|
||||||
|
|
||||||
if (channel1_ != ADC1_CHANNEL_MAX) {
|
if (this->channel1_ != ADC1_CHANNEL_MAX) {
|
||||||
adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_12_COMPAT);
|
adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_12_COMPAT);
|
||||||
raw12 = adc1_get_raw(channel1_);
|
raw12 = adc1_get_raw(this->channel1_);
|
||||||
if (raw12 < ADC_MAX) {
|
if (raw12 < ADC_MAX) {
|
||||||
adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_6);
|
adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_6);
|
||||||
raw6 = adc1_get_raw(channel1_);
|
raw6 = adc1_get_raw(this->channel1_);
|
||||||
if (raw6 < ADC_MAX) {
|
if (raw6 < ADC_MAX) {
|
||||||
adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_2_5);
|
adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_2_5);
|
||||||
raw2 = adc1_get_raw(channel1_);
|
raw2 = adc1_get_raw(this->channel1_);
|
||||||
if (raw2 < ADC_MAX) {
|
if (raw2 < ADC_MAX) {
|
||||||
adc1_config_channel_atten(channel1_, ADC_ATTEN_DB_0);
|
adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_0);
|
||||||
raw0 = adc1_get_raw(channel1_);
|
raw0 = adc1_get_raw(this->channel1_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (channel2_ != ADC2_CHANNEL_MAX) {
|
} else if (this->channel2_ != ADC2_CHANNEL_MAX) {
|
||||||
adc2_config_channel_atten(channel2_, ADC_ATTEN_DB_12_COMPAT);
|
adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_12_COMPAT);
|
||||||
adc2_get_raw(channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw12);
|
adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw12);
|
||||||
if (raw12 < ADC_MAX) {
|
if (raw12 < ADC_MAX) {
|
||||||
adc2_config_channel_atten(channel2_, ADC_ATTEN_DB_6);
|
adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_6);
|
||||||
adc2_get_raw(channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw6);
|
adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw6);
|
||||||
if (raw6 < ADC_MAX) {
|
if (raw6 < ADC_MAX) {
|
||||||
adc2_config_channel_atten(channel2_, ADC_ATTEN_DB_2_5);
|
adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_2_5);
|
||||||
adc2_get_raw(channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw2);
|
adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw2);
|
||||||
if (raw2 < ADC_MAX) {
|
if (raw2 < ADC_MAX) {
|
||||||
adc2_config_channel_atten(channel2_, ADC_ATTEN_DB_0);
|
adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_0);
|
||||||
adc2_get_raw(channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw0);
|
adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,10 +235,10 @@ float ADCSensor::sample() {
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mv12 = esp_adc_cal_raw_to_voltage(raw12, &cal_characteristics_[(int32_t) ADC_ATTEN_DB_12_COMPAT]);
|
uint32_t mv12 = esp_adc_cal_raw_to_voltage(raw12, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_12_COMPAT]);
|
||||||
uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int32_t) ADC_ATTEN_DB_6]);
|
uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_6]);
|
||||||
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
|
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
|
||||||
uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
|
uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
|
||||||
|
|
||||||
// Contribution of each value, in range 0-2048 (12 bit ADC) or 0-4096 (13 bit ADC)
|
// Contribution of each value, in range 0-2048 (12 bit ADC) or 0-4096 (13 bit ADC)
|
||||||
uint32_t c12 = std::min(raw12, ADC_HALF);
|
uint32_t c12 = std::min(raw12, ADC_HALF);
|
||||||
|
@ -246,8 +260,11 @@ float ADCSensor::sample() {
|
||||||
adc_set_temp_sensor_enabled(true);
|
adc_set_temp_sensor_enabled(true);
|
||||||
delay(1);
|
delay(1);
|
||||||
adc_select_input(4);
|
adc_select_input(4);
|
||||||
|
uint32_t raw = 0;
|
||||||
int32_t raw = adc_read();
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += adc_read();
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
adc_set_temp_sensor_enabled(false);
|
adc_set_temp_sensor_enabled(false);
|
||||||
if (this->output_raw_) {
|
if (this->output_raw_) {
|
||||||
return raw;
|
return raw;
|
||||||
|
@ -268,7 +285,11 @@ float ADCSensor::sample() {
|
||||||
adc_gpio_init(pin);
|
adc_gpio_init(pin);
|
||||||
adc_select_input(pin - 26);
|
adc_select_input(pin - 26);
|
||||||
|
|
||||||
int32_t raw = adc_read();
|
uint32_t raw = 0;
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += adc_read();
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
|
||||||
#ifdef CYW43_USES_VSYS_PIN
|
#ifdef CYW43_USES_VSYS_PIN
|
||||||
if (pin == PICO_VSYS_PIN) {
|
if (pin == PICO_VSYS_PIN) {
|
||||||
|
@ -276,7 +297,7 @@ float ADCSensor::sample() {
|
||||||
}
|
}
|
||||||
#endif // CYW43_USES_VSYS_PIN
|
#endif // CYW43_USES_VSYS_PIN
|
||||||
|
|
||||||
if (output_raw_) {
|
if (this->output_raw_) {
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
|
float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
|
||||||
|
@ -287,10 +308,19 @@ float ADCSensor::sample() {
|
||||||
|
|
||||||
#ifdef USE_LIBRETINY
|
#ifdef USE_LIBRETINY
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
if (output_raw_) {
|
uint32_t raw = 0;
|
||||||
return analogRead(this->pin_->get_pin()); // NOLINT
|
if (this->output_raw_) {
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += analogRead(this->pin_->get_pin()); // NOLINT
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
return raw;
|
||||||
}
|
}
|
||||||
return analogReadVoltage(this->pin_->get_pin()) / 1000.0f; // NOLINT
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
raw += analogReadVoltage(this->pin_->get_pin()); // NOLINT
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
return raw / 1000.0f;
|
||||||
}
|
}
|
||||||
#endif // USE_LIBRETINY
|
#endif // USE_LIBRETINY
|
||||||
|
|
||||||
|
|
|
@ -33,16 +33,16 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||||
public:
|
public:
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
/// Set the attenuation for this pin. Only available on the ESP32.
|
/// Set the attenuation for this pin. Only available on the ESP32.
|
||||||
void set_attenuation(adc_atten_t attenuation) { attenuation_ = attenuation; }
|
void set_attenuation(adc_atten_t attenuation) { this->attenuation_ = attenuation; }
|
||||||
void set_channel1(adc1_channel_t channel) {
|
void set_channel1(adc1_channel_t channel) {
|
||||||
channel1_ = channel;
|
this->channel1_ = channel;
|
||||||
channel2_ = ADC2_CHANNEL_MAX;
|
this->channel2_ = ADC2_CHANNEL_MAX;
|
||||||
}
|
}
|
||||||
void set_channel2(adc2_channel_t channel) {
|
void set_channel2(adc2_channel_t channel) {
|
||||||
channel2_ = channel;
|
this->channel2_ = channel;
|
||||||
channel1_ = ADC1_CHANNEL_MAX;
|
this->channel1_ = ADC1_CHANNEL_MAX;
|
||||||
}
|
}
|
||||||
void set_autorange(bool autorange) { autorange_ = autorange; }
|
void set_autorange(bool autorange) { this->autorange_ = autorange; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Update ADC values
|
/// Update ADC values
|
||||||
|
@ -53,7 +53,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||||
/// `HARDWARE_LATE` setup priority
|
/// `HARDWARE_LATE` setup priority
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
|
void set_pin(InternalGPIOPin *pin) { this->pin_ = pin; }
|
||||||
void set_output_raw(bool output_raw) { output_raw_ = output_raw; }
|
void set_output_raw(bool output_raw) { this->output_raw_ = output_raw; }
|
||||||
|
void set_sample_count(uint8_t sample_count);
|
||||||
float sample() override;
|
float sample() override;
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
|
@ -61,12 +62,13 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
#ifdef USE_RP2040
|
||||||
void set_is_temperature() { is_temperature_ = true; }
|
void set_is_temperature() { this->is_temperature_ = true; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InternalGPIOPin *pin_;
|
InternalGPIOPin *pin_;
|
||||||
bool output_raw_{false};
|
bool output_raw_{false};
|
||||||
|
uint8_t sample_count_{1};
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
#ifdef USE_RP2040
|
||||||
bool is_temperature_{false};
|
bool is_temperature_{false};
|
||||||
|
|
|
@ -29,6 +29,8 @@ _LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
AUTO_LOAD = ["voltage_sampler"]
|
AUTO_LOAD = ["voltage_sampler"]
|
||||||
|
|
||||||
|
CONF_SAMPLES = "samples"
|
||||||
|
|
||||||
|
|
||||||
_attenuation = cv.enum(ATTENUATION_MODES, lower=True)
|
_attenuation = cv.enum(ATTENUATION_MODES, lower=True)
|
||||||
|
|
||||||
|
@ -37,6 +39,10 @@ def validate_config(config):
|
||||||
if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto":
|
if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto":
|
||||||
raise cv.Invalid("Automatic attenuation cannot be used when raw output is set")
|
raise cv.Invalid("Automatic attenuation cannot be used when raw output is set")
|
||||||
|
|
||||||
|
if config.get(CONF_ATTENUATION, None) == "auto" and config.get(CONF_SAMPLES, 1) > 1:
|
||||||
|
raise cv.Invalid(
|
||||||
|
"Automatic attenuation cannot be used when multisampling is set"
|
||||||
|
)
|
||||||
if config.get(CONF_ATTENUATION) == "11db":
|
if config.get(CONF_ATTENUATION) == "11db":
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"`attenuation: 11db` is deprecated, use `attenuation: 12db` instead"
|
"`attenuation: 11db` is deprecated, use `attenuation: 12db` instead"
|
||||||
|
@ -81,6 +87,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||||
cv.only_on_esp32, _attenuation
|
cv.only_on_esp32, _attenuation
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_SAMPLES, default=1): cv.int_range(min=1, max=255),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s")),
|
.extend(cv.polling_component_schema("60s")),
|
||||||
|
@ -104,6 +111,7 @@ async def to_code(config):
|
||||||
cg.add(var.set_pin(pin))
|
cg.add(var.set_pin(pin))
|
||||||
|
|
||||||
cg.add(var.set_output_raw(config[CONF_RAW]))
|
cg.add(var.set_output_raw(config[CONF_RAW]))
|
||||||
|
cg.add(var.set_sample_count(config[CONF_SAMPLES]))
|
||||||
|
|
||||||
if attenuation := config.get(CONF_ATTENUATION):
|
if attenuation := config.get(CONF_ATTENUATION):
|
||||||
if attenuation == "auto":
|
if attenuation == "auto":
|
||||||
|
|
Loading…
Reference in a new issue