mirror of
https://github.com/esphome/esphome.git
synced 2025-01-18 20:10:55 +00:00
[adc] Split files by platform (#7940)
This commit is contained in:
parent
14eac3dbce
commit
437b236a4d
@ -3,13 +3,12 @@
|
|||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
#include "esphome/components/voltage_sampler/voltage_sampler.h"
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/core/defines.h"
|
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
#include <esp_adc_cal.h>
|
#include <esp_adc_cal.h>
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
#endif
|
#endif // USE_ESP32
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace adc {
|
namespace adc {
|
||||||
@ -43,7 +42,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
this->channel1_ = ADC1_CHANNEL_MAX;
|
this->channel1_ = ADC1_CHANNEL_MAX;
|
||||||
}
|
}
|
||||||
void set_autorange(bool autorange) { this->autorange_ = autorange; }
|
void set_autorange(bool autorange) { this->autorange_ = autorange; }
|
||||||
#endif
|
#endif // USE_ESP32
|
||||||
|
|
||||||
/// Update ADC values
|
/// Update ADC values
|
||||||
void update() override;
|
void update() override;
|
||||||
@ -59,11 +58,11 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
|
|
||||||
#ifdef USE_ESP8266
|
#ifdef USE_ESP8266
|
||||||
std::string unique_id() override;
|
std::string unique_id() override;
|
||||||
#endif
|
#endif // USE_ESP8266
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
#ifdef USE_RP2040
|
||||||
void set_is_temperature() { this->is_temperature_ = true; }
|
void set_is_temperature() { this->is_temperature_ = true; }
|
||||||
#endif
|
#endif // USE_RP2040
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InternalGPIOPin *pin_;
|
InternalGPIOPin *pin_;
|
||||||
@ -72,7 +71,7 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
|
|
||||||
#ifdef USE_RP2040
|
#ifdef USE_RP2040
|
||||||
bool is_temperature_{false};
|
bool is_temperature_{false};
|
||||||
#endif
|
#endif // USE_RP2040
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
#ifdef USE_ESP32
|
||||||
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
adc_atten_t attenuation_{ADC_ATTEN_DB_0};
|
||||||
@ -83,8 +82,8 @@ class ADCSensor : public sensor::Sensor, public PollingComponent, public voltage
|
|||||||
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM] = {};
|
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM] = {};
|
||||||
#else
|
#else
|
||||||
esp_adc_cal_characteristics_t cal_characteristics_[ADC_ATTEN_MAX] = {};
|
esp_adc_cal_characteristics_t cal_characteristics_[ADC_ATTEN_MAX] = {};
|
||||||
#endif
|
#endif // ESP_IDF_VERSION_MAJOR
|
||||||
#endif
|
#endif // USE_ESP32
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace adc
|
} // namespace adc
|
||||||
|
24
esphome/components/adc/adc_sensor_common.cpp
Normal file
24
esphome/components/adc/adc_sensor_common.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "adc_sensor.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace adc {
|
||||||
|
|
||||||
|
static const char *const TAG = "adc.common";
|
||||||
|
|
||||||
|
void ADCSensor::update() {
|
||||||
|
float value_v = this->sample();
|
||||||
|
ESP_LOGV(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
|
} // namespace esphome
|
@ -1,30 +1,13 @@
|
|||||||
|
#ifdef USE_ESP32
|
||||||
|
|
||||||
#include "adc_sensor.h"
|
#include "adc_sensor.h"
|
||||||
#include "esphome/core/helpers.h"
|
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
|
||||||
#include <Esp.h>
|
|
||||||
ADC_MODE(ADC_VCC)
|
|
||||||
#else
|
|
||||||
#include <Arduino.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
#ifdef CYW43_USES_VSYS_PIN
|
|
||||||
#include "pico/cyw43_arch.h"
|
|
||||||
#endif
|
|
||||||
#include <hardware/adc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace adc {
|
namespace adc {
|
||||||
|
|
||||||
static const char *const TAG = "adc";
|
static const char *const TAG = "adc.esp32";
|
||||||
|
|
||||||
// 13-bit for S2, 12-bit for all other ESP32 variants
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
|
static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
|
||||||
|
|
||||||
#ifndef SOC_ADC_RTC_MAX_BITWIDTH
|
#ifndef SOC_ADC_RTC_MAX_BITWIDTH
|
||||||
@ -32,24 +15,15 @@ static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_widt
|
|||||||
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
|
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
|
||||||
#else
|
#else
|
||||||
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
|
static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
|
||||||
#endif
|
#endif // USE_ESP32_VARIANT_ESP32S2
|
||||||
#endif
|
#endif // SOC_ADC_RTC_MAX_BITWIDTH
|
||||||
|
|
||||||
static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1; // 4095 (12 bit) or 8191 (13 bit)
|
static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1;
|
||||||
static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1; // 2048 (12 bit) or 4096 (13 bit)
|
static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
void ADCSensor::setup() {
|
||||||
extern "C"
|
|
||||||
#endif
|
|
||||||
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());
|
||||||
#if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040)
|
|
||||||
this->pin_->setup();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
if (this->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 (!this->autorange_) {
|
if (!this->autorange_) {
|
||||||
@ -61,7 +35,6 @@ extern "C"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 = this->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,
|
||||||
@ -79,31 +52,10 @@ extern "C"
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_ESP32
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
static bool initialized = false;
|
|
||||||
if (!initialized) {
|
|
||||||
adc_init();
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ESP_LOGCONFIG(TAG, "ADC '%s' setup finished!", this->get_name().c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADCSensor::dump_config() {
|
void ADCSensor::dump_config() {
|
||||||
LOG_SENSOR("", "ADC Sensor", this);
|
LOG_SENSOR("", "ADC Sensor", this);
|
||||||
#if defined(USE_ESP8266) || defined(USE_LIBRETINY)
|
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
|
||||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
|
||||||
#else
|
|
||||||
LOG_PIN(" Pin: ", this->pin_);
|
|
||||||
#endif
|
|
||||||
#endif // USE_ESP8266 || USE_LIBRETINY
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
LOG_PIN(" Pin: ", this->pin_);
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
if (this->autorange_) {
|
if (this->autorange_) {
|
||||||
ESP_LOGCONFIG(TAG, " Attenuation: auto");
|
ESP_LOGCONFIG(TAG, " Attenuation: auto");
|
||||||
@ -125,55 +77,10 @@ void ADCSensor::dump_config() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_ESP32
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
if (this->is_temperature_) {
|
|
||||||
ESP_LOGCONFIG(TAG, " Pin: Temperature");
|
|
||||||
} else {
|
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
|
||||||
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
|
||||||
#else
|
|
||||||
LOG_PIN(" Pin: ", this->pin_);
|
|
||||||
#endif // USE_ADC_SENSOR_VCC
|
|
||||||
}
|
|
||||||
#endif // USE_RP2040
|
|
||||||
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ADCSensor::get_setup_priority() const { return setup_priority::DATA; }
|
|
||||||
void ADCSensor::update() {
|
|
||||||
float value_v = this->sample();
|
|
||||||
ESP_LOGV(TAG, "'%s': Got voltage=%.4fV", this->get_name().c_str(), 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
|
|
||||||
float ADCSensor::sample() {
|
|
||||||
uint32_t raw = 0;
|
|
||||||
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
|
||||||
#ifdef USE_ADC_SENSOR_VCC
|
|
||||||
raw += ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
|
||||||
#else
|
|
||||||
raw += analogRead(this->pin_->get_pin()); // NOLINT
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
|
||||||
if (this->output_raw_) {
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
return raw / 1024.0f;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ESP32
|
|
||||||
float ADCSensor::sample() {
|
float ADCSensor::sample() {
|
||||||
if (!this->autorange_) {
|
if (!this->autorange_) {
|
||||||
uint32_t sum = 0;
|
uint32_t sum = 0;
|
||||||
@ -240,93 +147,17 @@ float ADCSensor::sample() {
|
|||||||
uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->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, &this->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)
|
|
||||||
uint32_t c12 = std::min(raw12, ADC_HALF);
|
uint32_t c12 = std::min(raw12, ADC_HALF);
|
||||||
uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
|
uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
|
||||||
uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
|
uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
|
||||||
uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
|
uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
|
||||||
// max theoretical csum value is 4096*4 = 16384
|
|
||||||
uint32_t csum = c12 + c6 + c2 + c0;
|
uint32_t csum = c12 + c6 + c2 + c0;
|
||||||
|
|
||||||
// each mv is max 3900; so max value is 3900*4096*4, fits in unsigned32
|
|
||||||
uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
|
uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
|
||||||
return mv_scaled / (float) (csum * 1000U);
|
return mv_scaled / (float) (csum * 1000U);
|
||||||
}
|
}
|
||||||
#endif // USE_ESP32
|
|
||||||
|
|
||||||
#ifdef USE_RP2040
|
|
||||||
float ADCSensor::sample() {
|
|
||||||
if (this->is_temperature_) {
|
|
||||||
adc_set_temp_sensor_enabled(true);
|
|
||||||
delay(1);
|
|
||||||
adc_select_input(4);
|
|
||||||
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)
|
|
||||||
adc_set_temp_sensor_enabled(false);
|
|
||||||
if (this->output_raw_) {
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
return raw * 3.3f / 4096.0f;
|
|
||||||
} else {
|
|
||||||
uint8_t pin = this->pin_->get_pin();
|
|
||||||
#ifdef CYW43_USES_VSYS_PIN
|
|
||||||
if (pin == PICO_VSYS_PIN) {
|
|
||||||
// Measuring VSYS on Raspberry Pico W needs to be wrapped with
|
|
||||||
// `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
|
|
||||||
// https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
|
|
||||||
// VSYS ADC both share GPIO29
|
|
||||||
cyw43_thread_enter();
|
|
||||||
}
|
|
||||||
#endif // CYW43_USES_VSYS_PIN
|
|
||||||
|
|
||||||
adc_gpio_init(pin);
|
|
||||||
adc_select_input(pin - 26);
|
|
||||||
|
|
||||||
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
|
|
||||||
if (pin == PICO_VSYS_PIN) {
|
|
||||||
cyw43_thread_exit();
|
|
||||||
}
|
|
||||||
#endif // CYW43_USES_VSYS_PIN
|
|
||||||
|
|
||||||
if (this->output_raw_) {
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
|
|
||||||
return raw * 3.3f / 4096.0f * coeff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_LIBRETINY
|
|
||||||
float ADCSensor::sample() {
|
|
||||||
uint32_t raw = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
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
|
|
||||||
|
|
||||||
#ifdef USE_ESP8266
|
|
||||||
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace adc
|
} // namespace adc
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP32
|
58
esphome/components/adc/adc_sensor_esp8266.cpp
Normal file
58
esphome/components/adc/adc_sensor_esp8266.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifdef USE_ESP8266
|
||||||
|
|
||||||
|
#include "adc_sensor.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
|
#include <Esp.h>
|
||||||
|
ADC_MODE(ADC_VCC)
|
||||||
|
#else
|
||||||
|
#include <Arduino.h>
|
||||||
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace adc {
|
||||||
|
|
||||||
|
static const char *const TAG = "adc.esp8266";
|
||||||
|
|
||||||
|
void ADCSensor::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
||||||
|
#ifndef USE_ADC_SENSOR_VCC
|
||||||
|
this->pin_->setup();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADCSensor::dump_config() {
|
||||||
|
LOG_SENSOR("", "ADC Sensor", this);
|
||||||
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
|
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||||
|
#else
|
||||||
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
|
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ADCSensor::sample() {
|
||||||
|
uint32_t raw = 0;
|
||||||
|
for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
|
||||||
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
|
raw += ESP.getVcc(); // NOLINT(readability-static-accessed-through-instance)
|
||||||
|
#else
|
||||||
|
raw += analogRead(this->pin_->get_pin()); // NOLINT
|
||||||
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
|
}
|
||||||
|
raw = (raw + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
|
||||||
|
if (this->output_raw_) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
return raw / 1024.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ADCSensor::unique_id() { return get_mac_address() + "-adc"; }
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_ESP8266
|
93
esphome/components/adc/adc_sensor_rp2040.cpp
Normal file
93
esphome/components/adc/adc_sensor_rp2040.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#ifdef USE_RP2040
|
||||||
|
|
||||||
|
#include "adc_sensor.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
#ifdef CYW43_USES_VSYS_PIN
|
||||||
|
#include "pico/cyw43_arch.h"
|
||||||
|
#endif // CYW43_USES_VSYS_PIN
|
||||||
|
#include <hardware/adc.h>
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace adc {
|
||||||
|
|
||||||
|
static const char *const TAG = "adc.rp2040";
|
||||||
|
|
||||||
|
void ADCSensor::setup() {
|
||||||
|
ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
|
||||||
|
static bool initialized = false;
|
||||||
|
if (!initialized) {
|
||||||
|
adc_init();
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ADCSensor::dump_config() {
|
||||||
|
LOG_SENSOR("", "ADC Sensor", this);
|
||||||
|
if (this->is_temperature_) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Pin: Temperature");
|
||||||
|
} else {
|
||||||
|
#ifdef USE_ADC_SENSOR_VCC
|
||||||
|
ESP_LOGCONFIG(TAG, " Pin: VCC");
|
||||||
|
#else
|
||||||
|
LOG_PIN(" Pin: ", this->pin_);
|
||||||
|
#endif // USE_ADC_SENSOR_VCC
|
||||||
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
float ADCSensor::sample() {
|
||||||
|
if (this->is_temperature_) {
|
||||||
|
adc_set_temp_sensor_enabled(true);
|
||||||
|
delay(1);
|
||||||
|
adc_select_input(4);
|
||||||
|
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)
|
||||||
|
adc_set_temp_sensor_enabled(false);
|
||||||
|
if (this->output_raw_) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
return raw * 3.3f / 4096.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pin = this->pin_->get_pin();
|
||||||
|
#ifdef CYW43_USES_VSYS_PIN
|
||||||
|
if (pin == PICO_VSYS_PIN) {
|
||||||
|
// Measuring VSYS on Raspberry Pico W needs to be wrapped with
|
||||||
|
// `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
|
||||||
|
// https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
|
||||||
|
// VSYS ADC both share GPIO29
|
||||||
|
cyw43_thread_enter();
|
||||||
|
}
|
||||||
|
#endif // CYW43_USES_VSYS_PIN
|
||||||
|
|
||||||
|
adc_gpio_init(pin);
|
||||||
|
adc_select_input(pin - 26);
|
||||||
|
|
||||||
|
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
|
||||||
|
if (pin == PICO_VSYS_PIN) {
|
||||||
|
cyw43_thread_exit();
|
||||||
|
}
|
||||||
|
#endif // CYW43_USES_VSYS_PIN
|
||||||
|
|
||||||
|
if (this->output_raw_) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
float coeff = pin == PICO_VSYS_PIN ? 3.0f : 1.0f;
|
||||||
|
return raw * 3.3f / 4096.0f * coeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace adc
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif // USE_RP2040
|
Loading…
x
Reference in New Issue
Block a user