ESPHome 2025.6.3
Loading...
Searching...
No Matches
adc_sensor_esp32.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
2
3#include "adc_sensor.h"
4#include "esphome/core/log.h"
5
6namespace esphome {
7namespace adc {
8
9static const char *const TAG = "adc.esp32";
10
11static const adc_bits_width_t ADC_WIDTH_MAX_SOC_BITS = static_cast<adc_bits_width_t>(ADC_WIDTH_MAX - 1);
12
13#ifndef SOC_ADC_RTC_MAX_BITWIDTH
14#if USE_ESP32_VARIANT_ESP32S2
15static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
16#else
17static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
18#endif // USE_ESP32_VARIANT_ESP32S2
19#endif // SOC_ADC_RTC_MAX_BITWIDTH
20
21static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1;
22static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1;
23
25 ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
26
27 if (this->channel1_ != ADC1_CHANNEL_MAX) {
28 adc1_config_width(ADC_WIDTH_MAX_SOC_BITS);
29 if (!this->autorange_) {
30 adc1_config_channel_atten(this->channel1_, this->attenuation_);
31 }
32 } else if (this->channel2_ != ADC2_CHANNEL_MAX) {
33 if (!this->autorange_) {
34 adc2_config_channel_atten(this->channel2_, this->attenuation_);
35 }
36 }
37
38 for (int32_t i = 0; i <= ADC_ATTEN_DB_12_COMPAT; i++) {
39 auto adc_unit = this->channel1_ != ADC1_CHANNEL_MAX ? ADC_UNIT_1 : ADC_UNIT_2;
40 auto cal_value = esp_adc_cal_characterize(adc_unit, (adc_atten_t) i, ADC_WIDTH_MAX_SOC_BITS,
41 1100, // default vref
42 &this->cal_characteristics_[i]);
43 switch (cal_value) {
44 case ESP_ADC_CAL_VAL_EFUSE_VREF:
45 ESP_LOGV(TAG, "Using eFuse Vref for calibration");
46 break;
47 case ESP_ADC_CAL_VAL_EFUSE_TP:
48 ESP_LOGV(TAG, "Using two-point eFuse Vref for calibration");
49 break;
50 case ESP_ADC_CAL_VAL_DEFAULT_VREF:
51 default:
52 break;
53 }
54 }
55}
56
58 LOG_SENSOR("", "ADC Sensor", this);
59 LOG_PIN(" Pin: ", this->pin_);
60 if (this->autorange_) {
61 ESP_LOGCONFIG(TAG, " Attenuation: auto");
62 } else {
63 switch (this->attenuation_) {
64 case ADC_ATTEN_DB_0:
65 ESP_LOGCONFIG(TAG, " Attenuation: 0db");
66 break;
67 case ADC_ATTEN_DB_2_5:
68 ESP_LOGCONFIG(TAG, " Attenuation: 2.5db");
69 break;
70 case ADC_ATTEN_DB_6:
71 ESP_LOGCONFIG(TAG, " Attenuation: 6db");
72 break;
73 case ADC_ATTEN_DB_12_COMPAT:
74 ESP_LOGCONFIG(TAG, " Attenuation: 12db");
75 break;
76 default: // This is to satisfy the unused ADC_ATTEN_MAX
77 break;
78 }
79 }
80 ESP_LOGCONFIG(TAG,
81 " Samples: %i\n"
82 " Sampling mode: %s",
83 this->sample_count_, LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_)));
84 LOG_UPDATE_INTERVAL(this);
85}
86
88 if (!this->autorange_) {
89 auto aggr = Aggregator(this->sampling_mode_);
90
91 for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
92 int raw = -1;
93 if (this->channel1_ != ADC1_CHANNEL_MAX) {
94 raw = adc1_get_raw(this->channel1_);
95 } else if (this->channel2_ != ADC2_CHANNEL_MAX) {
96 adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw);
97 }
98 if (raw == -1) {
99 return NAN;
100 }
101
102 aggr.add_sample(raw);
103 }
104 if (this->output_raw_) {
105 return aggr.aggregate();
106 }
107 uint32_t mv =
108 esp_adc_cal_raw_to_voltage(aggr.aggregate(), &this->cal_characteristics_[(int32_t) this->attenuation_]);
109 return mv / 1000.0f;
110 }
111
112 int raw12 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
113
114 if (this->channel1_ != ADC1_CHANNEL_MAX) {
115 adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_12_COMPAT);
116 raw12 = adc1_get_raw(this->channel1_);
117 if (raw12 < ADC_MAX) {
118 adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_6);
119 raw6 = adc1_get_raw(this->channel1_);
120 if (raw6 < ADC_MAX) {
121 adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_2_5);
122 raw2 = adc1_get_raw(this->channel1_);
123 if (raw2 < ADC_MAX) {
124 adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_0);
125 raw0 = adc1_get_raw(this->channel1_);
126 }
127 }
128 }
129 } else if (this->channel2_ != ADC2_CHANNEL_MAX) {
130 adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_12_COMPAT);
131 adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw12);
132 if (raw12 < ADC_MAX) {
133 adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_6);
134 adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw6);
135 if (raw6 < ADC_MAX) {
136 adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_2_5);
137 adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw2);
138 if (raw2 < ADC_MAX) {
139 adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_0);
140 adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw0);
141 }
142 }
143 }
144 }
145
146 if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw12 == -1) {
147 return NAN;
148 }
149
150 uint32_t mv12 = esp_adc_cal_raw_to_voltage(raw12, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_12_COMPAT]);
151 uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_6]);
152 uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
153 uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
154
155 uint32_t c12 = std::min(raw12, ADC_HALF);
156 uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
157 uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
158 uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
159 uint32_t csum = c12 + c6 + c2 + c0;
160
161 uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
162 return mv_scaled / (float) (csum * 1000U);
163}
164
165} // namespace adc
166} // namespace esphome
167
168#endif // USE_ESP32
uint8_t raw[35]
Definition bl0939.h:0
const StringRef & get_name() const
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM]
Definition adc_sensor.h:99
adc1_channel_t channel1_
Definition adc_sensor.h:95
void setup() override
Setup ADC.
InternalGPIOPin * pin_
Definition adc_sensor.h:84
adc2_channel_t channel2_
Definition adc_sensor.h:96
SamplingMode sampling_mode_
Definition adc_sensor.h:87
adc_atten_t attenuation_
Definition adc_sensor.h:94
const LogString * sampling_mode_to_str(SamplingMode mode)
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7