mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 17:05:21 +01:00
[ESP32 ADC] Add option for raw uncalibrated output (#2663)
This commit is contained in:
parent
2ac232e634
commit
219b225ac0
3 changed files with 26 additions and 11 deletions
|
@ -91,17 +91,21 @@ void ADCSensor::dump_config() {
|
||||||
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
|
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
void ADCSensor::update() {
|
void ADCSensor::update() {
|
||||||
float value_v = this->sample();
|
float value_v = this->sample();
|
||||||
ESP_LOGD(TAG, "'%s': Got voltage=%.2fV", this->get_name().c_str(), value_v);
|
ESP_LOGD(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), value_v);
|
||||||
this->publish_state(value_v);
|
this->publish_state(value_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
return ESP.getVcc() / 1024.0f; // NOLINT(readability-static-accessed-through-instance)
|
int raw = ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
||||||
#else
|
#else
|
||||||
return analogRead(this->pin_->get_pin()) / 1024.0f; // NOLINT
|
int raw = analogRead(this->pin_->get_pin()); // NOLINT
|
||||||
#endif
|
#endif
|
||||||
|
if (output_raw_) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
return raw / 1024.0f;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -112,6 +116,9 @@ float ADCSensor::sample() {
|
||||||
if (raw == -1) {
|
if (raw == -1) {
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
|
if (output_raw_) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int) attenuation_]);
|
uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int) attenuation_]);
|
||||||
return mv / 1000.0f;
|
return mv / 1000.0f;
|
||||||
}
|
}
|
||||||
|
@ -135,10 +142,6 @@ float ADCSensor::sample() {
|
||||||
if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw11 == -1) {
|
if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw11 == -1) {
|
||||||
return NAN;
|
return NAN;
|
||||||
}
|
}
|
||||||
// prevent divide by zero
|
|
||||||
if (raw0 == 0 && raw2 == 0 && raw6 == 0 && raw11 == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t mv11 = esp_adc_cal_raw_to_voltage(raw11, &cal_characteristics_[(int) ADC_ATTEN_DB_11]);
|
uint32_t mv11 = esp_adc_cal_raw_to_voltage(raw11, &cal_characteristics_[(int) ADC_ATTEN_DB_11]);
|
||||||
uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int) ADC_ATTEN_DB_6]);
|
uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int) ADC_ATTEN_DB_6]);
|
||||||
|
|
|
@ -31,6 +31,7 @@ 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; }
|
||||||
float sample() override;
|
float sample() override;
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
|
@ -39,8 +40,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InternalGPIOPin *pin_;
|
InternalGPIOPin *pin_;
|
||||||
uint16_t read_raw_();
|
bool output_raw_{false};
|
||||||
uint32_t raw_to_microvolts_(uint16_t raw);
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
||||||
|
|
|
@ -4,6 +4,7 @@ from esphome import pins
|
||||||
from esphome.components import sensor, voltage_sampler
|
from esphome.components import sensor, voltage_sampler
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ATTENUATION,
|
CONF_ATTENUATION,
|
||||||
|
CONF_RAW,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_INPUT,
|
CONF_INPUT,
|
||||||
CONF_NUMBER,
|
CONF_NUMBER,
|
||||||
|
@ -119,12 +120,18 @@ def validate_adc_pin(value):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def validate_config(config):
|
||||||
|
if config[CONF_RAW] and config.get(CONF_ATTENUATION, None) == "auto":
|
||||||
|
raise cv.Invalid("Automatic attenuation cannot be used when raw output is set.")
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
adc_ns = cg.esphome_ns.namespace("adc")
|
adc_ns = cg.esphome_ns.namespace("adc")
|
||||||
ADCSensor = adc_ns.class_(
|
ADCSensor = adc_ns.class_(
|
||||||
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = cv.All(
|
||||||
sensor.sensor_schema(
|
sensor.sensor_schema(
|
||||||
unit_of_measurement=UNIT_VOLT,
|
unit_of_measurement=UNIT_VOLT,
|
||||||
accuracy_decimals=2,
|
accuracy_decimals=2,
|
||||||
|
@ -135,12 +142,14 @@ CONFIG_SCHEMA = (
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(ADCSensor),
|
cv.GenerateID(): cv.declare_id(ADCSensor),
|
||||||
cv.Required(CONF_PIN): validate_adc_pin,
|
cv.Required(CONF_PIN): validate_adc_pin,
|
||||||
|
cv.Optional(CONF_RAW, default=False): cv.boolean,
|
||||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||||
cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)
|
cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s"))
|
.extend(cv.polling_component_schema("60s")),
|
||||||
|
validate_config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,6 +164,9 @@ async def to_code(config):
|
||||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||||
cg.add(var.set_pin(pin))
|
cg.add(var.set_pin(pin))
|
||||||
|
|
||||||
|
if CONF_RAW in config:
|
||||||
|
cg.add(var.set_output_raw(config[CONF_RAW]))
|
||||||
|
|
||||||
if CONF_ATTENUATION in config:
|
if CONF_ATTENUATION in config:
|
||||||
if config[CONF_ATTENUATION] == "auto":
|
if config[CONF_ATTENUATION] == "auto":
|
||||||
cg.add(var.set_autorange(cg.global_ns.true))
|
cg.add(var.set_autorange(cg.global_ns.true))
|
||||||
|
|
Loading…
Reference in a new issue