mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 01:08:03 +01:00
ESP32 ADC use factory calibration data (#2574)
This commit is contained in:
parent
156104d5f5
commit
cac5b356db
3 changed files with 177 additions and 146 deletions
|
@ -16,50 +16,6 @@ namespace adc {
|
||||||
|
|
||||||
static const char *const TAG = "adc";
|
static const char *const TAG = "adc";
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
inline adc1_channel_t gpio_to_adc1(uint8_t pin) {
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
switch (pin) {
|
|
||||||
case 36:
|
|
||||||
return ADC1_CHANNEL_0;
|
|
||||||
case 37:
|
|
||||||
return ADC1_CHANNEL_1;
|
|
||||||
case 38:
|
|
||||||
return ADC1_CHANNEL_2;
|
|
||||||
case 39:
|
|
||||||
return ADC1_CHANNEL_3;
|
|
||||||
case 32:
|
|
||||||
return ADC1_CHANNEL_4;
|
|
||||||
case 33:
|
|
||||||
return ADC1_CHANNEL_5;
|
|
||||||
case 34:
|
|
||||||
return ADC1_CHANNEL_6;
|
|
||||||
case 35:
|
|
||||||
return ADC1_CHANNEL_7;
|
|
||||||
default:
|
|
||||||
return ADC1_CHANNEL_MAX;
|
|
||||||
}
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
switch (pin) {
|
|
||||||
case 0:
|
|
||||||
return ADC1_CHANNEL_0;
|
|
||||||
case 1:
|
|
||||||
return ADC1_CHANNEL_1;
|
|
||||||
case 2:
|
|
||||||
return ADC1_CHANNEL_2;
|
|
||||||
case 3:
|
|
||||||
return ADC1_CHANNEL_3;
|
|
||||||
case 4:
|
|
||||||
return ADC1_CHANNEL_4;
|
|
||||||
default:
|
|
||||||
return ADC1_CHANNEL_MAX;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
void ADCSensor::set_attenuation(adc_atten_t attenuation) { this->attenuation_ = attenuation; }
|
|
||||||
void ADCSensor::set_autorange(bool autorange) { this->autorange_ = autorange; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ADCSensor::setup() {
|
void 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());
|
||||||
#ifndef USE_ADC_SENSOR_VCC
|
#ifndef USE_ADC_SENSOR_VCC
|
||||||
|
@ -67,15 +23,36 @@ void ADCSensor::setup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
if (this->autorange_)
|
|
||||||
this->attenuation_ = ADC_ATTEN_DB_11;
|
|
||||||
adc1_config_channel_atten(gpio_to_adc1(pin_->get_pin()), attenuation_);
|
|
||||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||||
#if !CONFIG_IDF_TARGET_ESP32C3 && !CONFIG_IDF_TARGET_ESP32H2
|
if (!autorange_) {
|
||||||
adc_gpio_init(ADC_UNIT_1, (adc_channel_t) gpio_to_adc1(pin_->get_pin()));
|
adc1_config_channel_atten(channel_, attenuation_);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
// load characteristics for each attenuation
|
||||||
|
for (int i = 0; i < (int) ADC_ATTEN_MAX; i++) {
|
||||||
|
auto cal_value = esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t) i, ADC_WIDTH_BIT_12,
|
||||||
|
1100, // default vref
|
||||||
|
&cal_characteristics_[i]);
|
||||||
|
switch (cal_value) {
|
||||||
|
case ESP_ADC_CAL_VAL_EFUSE_VREF:
|
||||||
|
ESP_LOGV(TAG, "Using eFuse Vref for calibration");
|
||||||
|
break;
|
||||||
|
case ESP_ADC_CAL_VAL_EFUSE_TP:
|
||||||
|
ESP_LOGV(TAG, "Using two-point eFuse Vref for calibration");
|
||||||
|
break;
|
||||||
|
case ESP_ADC_CAL_VAL_DEFAULT_VREF:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adc_gpio_init doesn't exist on ESP32-C3 or ESP32-H2
|
||||||
|
#if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32H2)
|
||||||
|
adc_gpio_init(ADC_UNIT_1, (adc_channel_t) channel_);
|
||||||
#endif
|
#endif
|
||||||
|
#endif // USE_ESP32
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADCSensor::dump_config() {
|
void ADCSensor::dump_config() {
|
||||||
LOG_SENSOR("", "ADC Sensor", this);
|
LOG_SENSOR("", "ADC Sensor", this);
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
|
@ -84,7 +61,8 @@ void ADCSensor::dump_config() {
|
||||||
#else
|
#else
|
||||||
LOG_PIN(" Pin: ", pin_);
|
LOG_PIN(" Pin: ", pin_);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif // USE_ESP8266
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
LOG_PIN(" Pin: ", pin_);
|
LOG_PIN(" Pin: ", pin_);
|
||||||
if (autorange_)
|
if (autorange_)
|
||||||
|
@ -106,101 +84,81 @@ void ADCSensor::dump_config() {
|
||||||
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // USE_ESP32
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
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=%.2fV", this->get_name().c_str(), value_v);
|
||||||
this->publish_state(value_v);
|
this->publish_state(value_v);
|
||||||
}
|
}
|
||||||
uint16_t ADCSensor::read_raw_() {
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
return adc1_get_raw(gpio_to_adc1(pin_->get_pin()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
|
||||||
return ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
|
||||||
#else
|
|
||||||
return analogRead(this->pin_->get_pin()); // NOLINT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
uint32_t ADCSensor::raw_to_microvolts_(uint16_t raw) {
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32
|
|
||||||
switch (this->attenuation_) {
|
|
||||||
case ADC_ATTEN_DB_0:
|
|
||||||
return raw * 269; // 1e6 * 1.1 / 4095
|
|
||||||
case ADC_ATTEN_DB_2_5:
|
|
||||||
return raw * 366; // 1e6 * 1.5 / 4095
|
|
||||||
case ADC_ATTEN_DB_6:
|
|
||||||
return raw * 537; // 1e6 * 2.2 / 4095
|
|
||||||
case ADC_ATTEN_DB_11:
|
|
||||||
return raw * 952; // 1e6 * 3.9 / 4095
|
|
||||||
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
|
||||||
return raw * 244; // 1e6 * 1.0 / 4095
|
|
||||||
}
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
switch (this->attenuation_) {
|
|
||||||
case ADC_ATTEN_DB_0:
|
|
||||||
return raw * 205; // 1e6 * 0.84 / 4095
|
|
||||||
case ADC_ATTEN_DB_2_5:
|
|
||||||
return raw * 276; // 1e6 * 1.13 / 4095
|
|
||||||
case ADC_ATTEN_DB_6:
|
|
||||||
return raw * 381; // 1e6 * 1.56 / 4095
|
|
||||||
case ADC_ATTEN_DB_11:
|
|
||||||
return raw * 733; // 1e6 * 3.0 / 4095
|
|
||||||
default: // This is to satisfy the unused ADC_ATTEN_MAX
|
|
||||||
return raw * 244; // 1e6 * 1.0 / 4095
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
|
||||||
return raw * 977; // 1e6 / 1024
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
int raw = this->read_raw_();
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
uint32_t v = this->raw_to_microvolts_(raw);
|
return ESP.getVcc() / 1024.0f; // NOLINT(readability-static-accessed-through-instance)
|
||||||
#ifdef USE_ESP32
|
#else
|
||||||
if (autorange_) {
|
return analogRead(this->pin_->get_pin()) / 1024.0f; // NOLINT
|
||||||
int raw11 = raw, raw6 = 4095, raw2 = 4095, raw0 = 4095;
|
|
||||||
uint32_t v11 = v, v6 = 0, v2 = 0, v0 = 0;
|
|
||||||
if (raw11 < 4095) { // Progressively read all attenuation ranges
|
|
||||||
adc1_config_channel_atten(gpio_to_adc1(pin_->get_pin()), ADC_ATTEN_DB_6);
|
|
||||||
raw6 = this->read_raw_();
|
|
||||||
v6 = this->raw_to_microvolts_(raw6);
|
|
||||||
if (raw6 < 4095) {
|
|
||||||
adc1_config_channel_atten(gpio_to_adc1(pin_->get_pin()), ADC_ATTEN_DB_2_5);
|
|
||||||
raw2 = this->read_raw_();
|
|
||||||
v2 = this->raw_to_microvolts_(raw2);
|
|
||||||
if (raw2 < 4095) {
|
|
||||||
adc1_config_channel_atten(gpio_to_adc1(pin_->get_pin()), ADC_ATTEN_DB_0);
|
|
||||||
raw0 = this->read_raw_();
|
|
||||||
v0 = this->raw_to_microvolts_(raw0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
adc1_config_channel_atten(gpio_to_adc1(pin_->get_pin()), ADC_ATTEN_DB_11);
|
|
||||||
} // Contribution coefficients (normalized to 2048)
|
|
||||||
uint16_t c11 = clamp(raw11, 0, 2048); // high 1, middle 1, low 0
|
|
||||||
uint16_t c6 = (2048 - abs(raw6 - 2048)); // high 0, middle 1, low 0
|
|
||||||
uint16_t c2 = (2048 - abs(raw2 - 2048)); // high 0, middle 1, low 0
|
|
||||||
uint16_t c0 = clamp(4095 - raw0, 0, 2048); // high 0, middle 1, low 1
|
|
||||||
uint32_t csum = c11 + c6 + c2 + c0; // sum to normalize the final result
|
|
||||||
if (csum > 0)
|
|
||||||
v = (v11 * c11) + (v6 * c6) + (v2 * c2) + (v0 * c0);
|
|
||||||
else // in case of error, this keeps the 11db output (v)
|
|
||||||
csum = 1;
|
|
||||||
csum *= 1e6; // include the 1e6 microvolts->volts conversion factor
|
|
||||||
return (float) v / (float) csum; // normalize, convert & return
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return v / (float) 1e6; // convert from microvolts to volts
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_ESP32
|
||||||
|
float ADCSensor::sample() {
|
||||||
|
if (!autorange_) {
|
||||||
|
int raw = adc1_get_raw(channel_);
|
||||||
|
if (raw == -1) {
|
||||||
|
return NAN;
|
||||||
|
}
|
||||||
|
uint32_t mv = esp_adc_cal_raw_to_voltage(raw, &cal_characteristics_[(int) attenuation_]);
|
||||||
|
return mv / 1000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw11, raw6 = 4095, raw2 = 4095, raw0 = 4095;
|
||||||
|
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_11);
|
||||||
|
raw11 = adc1_get_raw(channel_);
|
||||||
|
if (raw11 < 4095) {
|
||||||
|
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_6);
|
||||||
|
raw6 = adc1_get_raw(channel_);
|
||||||
|
if (raw6 < 4095) {
|
||||||
|
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_2_5);
|
||||||
|
raw2 = adc1_get_raw(channel_);
|
||||||
|
if (raw2 < 4095) {
|
||||||
|
adc1_config_channel_atten(channel_, ADC_ATTEN_DB_0);
|
||||||
|
raw0 = adc1_get_raw(channel_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw11 == -1) {
|
||||||
|
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 mv6 = esp_adc_cal_raw_to_voltage(raw6, &cal_characteristics_[(int) ADC_ATTEN_DB_6]);
|
||||||
|
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &cal_characteristics_[(int) ADC_ATTEN_DB_2_5]);
|
||||||
|
uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &cal_characteristics_[(int) ADC_ATTEN_DB_0]);
|
||||||
|
|
||||||
|
// Contribution of each value, in range 0-2048
|
||||||
|
uint32_t c11 = std::min(raw11, 2048);
|
||||||
|
uint32_t c6 = 2048 - std::abs(raw6 - 2048);
|
||||||
|
uint32_t c2 = 2048 - std::abs(raw2 - 2048);
|
||||||
|
uint32_t c0 = std::min(4095 - raw0, 2048);
|
||||||
|
// max theoretical csum value is 2048*4 = 8192
|
||||||
|
uint32_t csum = c11 + c6 + c2 + c0;
|
||||||
|
|
||||||
|
// each mv is max 3900; so max value is 3900*2048*4, fits in unsigned
|
||||||
|
uint32_t mv_scaled = (mv11 * c11) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
|
||||||
|
return mv_scaled / (float) (csum * 1000U);
|
||||||
|
}
|
||||||
|
#endif // USE_ESP32
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
#include <esp_adc_cal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -17,8 +18,9 @@ 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);
|
void set_attenuation(adc_atten_t attenuation) { attenuation_ = attenuation; }
|
||||||
void set_autorange(bool autorange);
|
void set_channel(adc1_channel_t channel) { channel_ = channel; }
|
||||||
|
void set_autorange(bool autorange) { autorange_ = autorange; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Update adc values.
|
/// Update adc values.
|
||||||
|
@ -42,7 +44,9 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
||||||
|
adc1_channel_t channel_{};
|
||||||
bool autorange_{false};
|
bool autorange_{false};
|
||||||
|
esp_adc_cal_characteristics_t cal_characteristics_[(int) ADC_ATTEN_MAX] = {};
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,21 @@ from esphome.const import (
|
||||||
CONF_ATTENUATION,
|
CONF_ATTENUATION,
|
||||||
CONF_ID,
|
CONF_ID,
|
||||||
CONF_INPUT,
|
CONF_INPUT,
|
||||||
|
CONF_NUMBER,
|
||||||
CONF_PIN,
|
CONF_PIN,
|
||||||
DEVICE_CLASS_VOLTAGE,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
UNIT_VOLT,
|
UNIT_VOLT,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
|
from esphome.components.esp32 import get_esp32_variant
|
||||||
|
from esphome.components.esp32.const import (
|
||||||
|
VARIANT_ESP32,
|
||||||
|
VARIANT_ESP32C3,
|
||||||
|
VARIANT_ESP32H2,
|
||||||
|
VARIANT_ESP32S2,
|
||||||
|
VARIANT_ESP32S3,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
AUTO_LOAD = ["voltage_sampler"]
|
AUTO_LOAD = ["voltage_sampler"]
|
||||||
|
@ -24,21 +33,77 @@ ATTENUATION_MODES = {
|
||||||
"auto": "auto",
|
"auto": "auto",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adc1_channel_t = cg.global_ns.enum("adc1_channel_t")
|
||||||
|
|
||||||
|
# From https://github.com/espressif/esp-idf/blob/master/components/driver/include/driver/adc_common.h
|
||||||
|
# pin to adc1 channel mapping
|
||||||
|
ESP32_VARIANT_ADC1_PIN_TO_CHANNEL = {
|
||||||
|
VARIANT_ESP32: {
|
||||||
|
36: adc1_channel_t.ADC1_CHANNEL_0,
|
||||||
|
37: adc1_channel_t.ADC1_CHANNEL_1,
|
||||||
|
38: adc1_channel_t.ADC1_CHANNEL_2,
|
||||||
|
39: adc1_channel_t.ADC1_CHANNEL_3,
|
||||||
|
32: adc1_channel_t.ADC1_CHANNEL_4,
|
||||||
|
33: adc1_channel_t.ADC1_CHANNEL_5,
|
||||||
|
34: adc1_channel_t.ADC1_CHANNEL_6,
|
||||||
|
35: adc1_channel_t.ADC1_CHANNEL_7,
|
||||||
|
},
|
||||||
|
VARIANT_ESP32S2: {
|
||||||
|
1: adc1_channel_t.ADC1_CHANNEL_0,
|
||||||
|
2: adc1_channel_t.ADC1_CHANNEL_1,
|
||||||
|
3: adc1_channel_t.ADC1_CHANNEL_2,
|
||||||
|
4: adc1_channel_t.ADC1_CHANNEL_3,
|
||||||
|
5: adc1_channel_t.ADC1_CHANNEL_4,
|
||||||
|
6: adc1_channel_t.ADC1_CHANNEL_5,
|
||||||
|
7: adc1_channel_t.ADC1_CHANNEL_6,
|
||||||
|
8: adc1_channel_t.ADC1_CHANNEL_7,
|
||||||
|
9: adc1_channel_t.ADC1_CHANNEL_8,
|
||||||
|
10: adc1_channel_t.ADC1_CHANNEL_9,
|
||||||
|
},
|
||||||
|
VARIANT_ESP32S3: {
|
||||||
|
1: adc1_channel_t.ADC1_CHANNEL_0,
|
||||||
|
2: adc1_channel_t.ADC1_CHANNEL_1,
|
||||||
|
3: adc1_channel_t.ADC1_CHANNEL_2,
|
||||||
|
4: adc1_channel_t.ADC1_CHANNEL_3,
|
||||||
|
5: adc1_channel_t.ADC1_CHANNEL_4,
|
||||||
|
6: adc1_channel_t.ADC1_CHANNEL_5,
|
||||||
|
7: adc1_channel_t.ADC1_CHANNEL_6,
|
||||||
|
8: adc1_channel_t.ADC1_CHANNEL_7,
|
||||||
|
9: adc1_channel_t.ADC1_CHANNEL_8,
|
||||||
|
10: adc1_channel_t.ADC1_CHANNEL_9,
|
||||||
|
},
|
||||||
|
VARIANT_ESP32C3: {
|
||||||
|
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||||
|
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||||
|
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||||
|
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||||
|
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||||
|
},
|
||||||
|
VARIANT_ESP32H2: {
|
||||||
|
0: adc1_channel_t.ADC1_CHANNEL_0,
|
||||||
|
1: adc1_channel_t.ADC1_CHANNEL_1,
|
||||||
|
2: adc1_channel_t.ADC1_CHANNEL_2,
|
||||||
|
3: adc1_channel_t.ADC1_CHANNEL_3,
|
||||||
|
4: adc1_channel_t.ADC1_CHANNEL_4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def validate_adc_pin(value):
|
def validate_adc_pin(value):
|
||||||
if str(value).upper() == "VCC":
|
if str(value).upper() == "VCC":
|
||||||
return cv.only_on_esp8266("VCC")
|
return cv.only_on_esp8266("VCC")
|
||||||
|
|
||||||
if CORE.is_esp32:
|
if CORE.is_esp32:
|
||||||
from esphome.components.esp32 import is_esp32c3
|
|
||||||
|
|
||||||
value = pins.internal_gpio_input_pin_number(value)
|
value = pins.internal_gpio_input_pin_number(value)
|
||||||
if is_esp32c3():
|
variant = get_esp32_variant()
|
||||||
if not (0 <= value <= 4): # ADC1
|
if variant not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL:
|
||||||
raise cv.Invalid("ESP32-C3: Only pins 0 though 4 support ADC.")
|
raise cv.Invalid(f"This ESP32 variant ({variant}) is not supported")
|
||||||
elif not (32 <= value <= 39): # ADC1
|
|
||||||
raise cv.Invalid("ESP32: Only pins 32 though 39 support ADC.")
|
if value not in ESP32_VARIANT_ADC1_PIN_TO_CHANNEL[variant]:
|
||||||
elif CORE.is_esp8266:
|
raise cv.Invalid(f"{variant} doesn't support ADC on this pin")
|
||||||
|
return pins.internal_gpio_input_pin_schema(value)
|
||||||
|
|
||||||
|
if CORE.is_esp8266:
|
||||||
from esphome.components.esp8266.gpio import CONF_ANALOG
|
from esphome.components.esp8266.gpio import CONF_ANALOG
|
||||||
|
|
||||||
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})(
|
value = pins.internal_gpio_pin_number({CONF_ANALOG: True, CONF_INPUT: True})(
|
||||||
|
@ -50,10 +115,8 @@ def validate_adc_pin(value):
|
||||||
return pins.gpio_pin_schema(
|
return pins.gpio_pin_schema(
|
||||||
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
|
{CONF_ANALOG: True, CONF_INPUT: True}, internal=True
|
||||||
)(value)
|
)(value)
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
return pins.internal_gpio_input_pin_schema(value)
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
adc_ns = cg.esphome_ns.namespace("adc")
|
adc_ns = cg.esphome_ns.namespace("adc")
|
||||||
|
@ -97,3 +160,9 @@ async def to_code(config):
|
||||||
cg.add(var.set_autorange(cg.global_ns.true))
|
cg.add(var.set_autorange(cg.global_ns.true))
|
||||||
else:
|
else:
|
||||||
cg.add(var.set_attenuation(config[CONF_ATTENUATION]))
|
cg.add(var.set_attenuation(config[CONF_ATTENUATION]))
|
||||||
|
|
||||||
|
if CORE.is_esp32:
|
||||||
|
variant = get_esp32_variant()
|
||||||
|
pin_num = config[CONF_PIN][CONF_NUMBER]
|
||||||
|
chan = ESP32_VARIANT_ADC1_PIN_TO_CHANNEL[variant][pin_num]
|
||||||
|
cg.add(var.set_channel(chan))
|
||||||
|
|
Loading…
Reference in a new issue