6 #ifdef USE_ADC_SENSOR_VCC 15 #ifdef CYW43_USES_VSYS_PIN 16 #include "pico/cyw43_arch.h" 18 #include <hardware/adc.h> 24 static const char *
const TAG =
"adc";
28 static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS =
static_cast<adc_bits_width_t
>(ADC_WIDTH_MAX - 1);
30 #ifndef SOC_ADC_RTC_MAX_BITWIDTH 31 #if USE_ESP32_VARIANT_ESP32S2 32 static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
34 static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
38 static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1;
39 static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1;
47 ESP_LOGCONFIG(TAG,
"Setting up ADC '%s'...", this->
get_name().c_str());
48 #if !defined(USE_ADC_SENSOR_VCC) && !defined(USE_RP2040) 53 if (this->
channel1_ != ADC1_CHANNEL_MAX) {
54 adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
58 }
else if (this->
channel2_ != ADC2_CHANNEL_MAX) {
65 for (int32_t i = 0; i <= ADC_ATTEN_DB_12_COMPAT; i++) {
66 auto adc_unit = this->
channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
67 auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
71 case ESP_ADC_CAL_VAL_EFUSE_VREF:
72 ESP_LOGV(TAG,
"Using eFuse Vref for calibration");
74 case ESP_ADC_CAL_VAL_EFUSE_TP:
75 ESP_LOGV(TAG,
"Using two-point eFuse Vref for calibration");
77 case ESP_ADC_CAL_VAL_DEFAULT_VREF:
86 static bool initialized =
false;
93 ESP_LOGCONFIG(TAG,
"ADC '%s' setup finished!", this->
get_name().c_str());
97 LOG_SENSOR(
"",
"ADC Sensor",
this);
98 #if defined(USE_ESP8266) || defined(USE_LIBRETINY) 99 #ifdef USE_ADC_SENSOR_VCC 100 ESP_LOGCONFIG(TAG,
" Pin: VCC");
102 LOG_PIN(
" Pin: ", this->
pin_);
104 #endif // USE_ESP8266 || USE_LIBRETINY 107 LOG_PIN(
" Pin: ", this->
pin_);
109 ESP_LOGCONFIG(TAG,
" Attenuation: auto");
113 ESP_LOGCONFIG(TAG,
" Attenuation: 0db");
115 case ADC_ATTEN_DB_2_5:
116 ESP_LOGCONFIG(TAG,
" Attenuation: 2.5db");
119 ESP_LOGCONFIG(TAG,
" Attenuation: 6db");
121 case ADC_ATTEN_DB_12_COMPAT:
122 ESP_LOGCONFIG(TAG,
" Attenuation: 12db");
132 ESP_LOGCONFIG(TAG,
" Pin: Temperature");
134 #ifdef USE_ADC_SENSOR_VCC 135 ESP_LOGCONFIG(TAG,
" Pin: VCC");
137 LOG_PIN(
" Pin: ", this->
pin_);
138 #endif // USE_ADC_SENSOR_VCC 142 LOG_UPDATE_INTERVAL(
this);
147 float value_v = this->
sample();
148 ESP_LOGV(TAG,
"'%s': Got voltage=%.4fV", this->
get_name().c_str(), value_v);
153 if (sample_count != 0) {
162 #ifdef USE_ADC_SENSOR_VCC 168 raw = (raw + (this->sample_count_ >> 1)) / this->
sample_count_;
172 return raw / 1024.0f;
182 if (this->
channel1_ != ADC1_CHANNEL_MAX) {
184 }
else if (this->
channel2_ != ADC2_CHANNEL_MAX) {
185 adc2_get_raw(this->
channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw);
192 sum = (sum + (this->sample_count_ >> 1)) / this->
sample_count_;
200 int raw12 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
202 if (this->
channel1_ != ADC1_CHANNEL_MAX) {
203 adc1_config_channel_atten(this->
channel1_, ADC_ATTEN_DB_12_COMPAT);
205 if (raw12 < ADC_MAX) {
206 adc1_config_channel_atten(this->
channel1_, ADC_ATTEN_DB_6);
208 if (raw6 < ADC_MAX) {
209 adc1_config_channel_atten(this->
channel1_, ADC_ATTEN_DB_2_5);
211 if (raw2 < ADC_MAX) {
212 adc1_config_channel_atten(this->
channel1_, ADC_ATTEN_DB_0);
217 }
else if (this->
channel2_ != ADC2_CHANNEL_MAX) {
218 adc2_config_channel_atten(this->
channel2_, ADC_ATTEN_DB_12_COMPAT);
219 adc2_get_raw(this->
channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw12);
220 if (raw12 < ADC_MAX) {
221 adc2_config_channel_atten(this->
channel2_, ADC_ATTEN_DB_6);
222 adc2_get_raw(this->
channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw6);
223 if (raw6 < ADC_MAX) {
224 adc2_config_channel_atten(this->
channel2_, ADC_ATTEN_DB_2_5);
225 adc2_get_raw(this->
channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw2);
226 if (raw2 < ADC_MAX) {
227 adc2_config_channel_atten(this->
channel2_, ADC_ATTEN_DB_0);
228 adc2_get_raw(this->
channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw0);
234 if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw12 == -1) {
238 uint32_t mv12 = esp_adc_cal_raw_to_voltage(raw12, &this->
cal_characteristics_[(int32_t) ADC_ATTEN_DB_12_COMPAT]);
239 uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &this->
cal_characteristics_[(int32_t) ADC_ATTEN_DB_6]);
240 uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->
cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
241 uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &this->
cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
244 uint32_t c12 = std::min(raw12, ADC_HALF);
245 uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
246 uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
247 uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
249 uint32_t csum = c12 + c6 + c2 + c0;
252 uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
253 return mv_scaled / (float) (csum * 1000U);
260 adc_set_temp_sensor_enabled(
true);
267 raw = (raw + (this->sample_count_ >> 1)) / this->
sample_count_;
268 adc_set_temp_sensor_enabled(
false);
272 return raw * 3.3f / 4096.0f;
275 #ifdef CYW43_USES_VSYS_PIN 276 if (pin == PICO_VSYS_PIN) {
281 cyw43_thread_enter();
283 #endif // CYW43_USES_VSYS_PIN 286 adc_select_input(pin - 26);
292 raw = (raw + (this->sample_count_ >> 1)) / this->
sample_count_;
294 #ifdef CYW43_USES_VSYS_PIN 295 if (pin == PICO_VSYS_PIN) {
298 #endif // CYW43_USES_VSYS_PIN 303 float coeff = pin == PICO_VSYS_PIN ? 3.0 : 1.0;
304 return raw * 3.3f / 4096.0f * coeff;
316 raw = (raw + (this->sample_count_ >> 1)) / this->
sample_count_;
322 raw = (raw + (this->sample_count_ >> 1)) / this->
sample_count_;
323 return raw / 1000.0f;
325 #endif // USE_LIBRETINY
const float DATA
For components that import data from directly connected sensors like DHT.
ADC_MODE(ADC_VCC) namespace esphome
void setup() override
Setup ADC.
virtual uint8_t get_pin() const =0
std::string get_mac_address()
Get the device MAC address as a string, in lowercase hex notation.
void set_sample_count(uint8_t sample_count)
void publish_state(float state)
Publish a new state to the front-end.
std::string unique_id() override
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM]
void update() override
Update ADC values.
Implementation of SPI Controller mode.
float get_setup_priority() const override
HARDWARE_LATE setup priority
void dump_config() override
const StringRef & get_name() const
void IRAM_ATTR HOT delay(uint32_t ms)