ESPHome  2024.12.2
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 
6 namespace esphome {
7 namespace adc {
8 
9 static const char *const TAG = "adc.esp32";
10 
11 static 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
15 static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 13;
16 #else
17 static const int32_t SOC_ADC_RTC_MAX_BITWIDTH = 12;
18 #endif // USE_ESP32_VARIANT_ESP32S2
19 #endif // SOC_ADC_RTC_MAX_BITWIDTH
20 
21 static const int ADC_MAX = (1 << SOC_ADC_RTC_MAX_BITWIDTH) - 1;
22 static const int ADC_HALF = (1 << SOC_ADC_RTC_MAX_BITWIDTH) >> 1;
23 
25  ESP_LOGCONFIG(TAG, "Setting up ADC '%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, " Samples: %i", this->sample_count_);
81  LOG_UPDATE_INTERVAL(this);
82 }
83 
85  if (!this->autorange_) {
86  uint32_t sum = 0;
87  for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
88  int raw = -1;
89  if (this->channel1_ != ADC1_CHANNEL_MAX) {
90  raw = adc1_get_raw(this->channel1_);
91  } else if (this->channel2_ != ADC2_CHANNEL_MAX) {
92  adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw);
93  }
94  if (raw == -1) {
95  return NAN;
96  }
97  sum += raw;
98  }
99  sum = (sum + (this->sample_count_ >> 1)) / this->sample_count_; // NOLINT(clang-analyzer-core.DivideZero)
100  if (this->output_raw_) {
101  return sum;
102  }
103  uint32_t mv = esp_adc_cal_raw_to_voltage(sum, &this->cal_characteristics_[(int32_t) this->attenuation_]);
104  return mv / 1000.0f;
105  }
106 
107  int raw12 = ADC_MAX, raw6 = ADC_MAX, raw2 = ADC_MAX, raw0 = ADC_MAX;
108 
109  if (this->channel1_ != ADC1_CHANNEL_MAX) {
110  adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_12_COMPAT);
111  raw12 = adc1_get_raw(this->channel1_);
112  if (raw12 < ADC_MAX) {
113  adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_6);
114  raw6 = adc1_get_raw(this->channel1_);
115  if (raw6 < ADC_MAX) {
116  adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_2_5);
117  raw2 = adc1_get_raw(this->channel1_);
118  if (raw2 < ADC_MAX) {
119  adc1_config_channel_atten(this->channel1_, ADC_ATTEN_DB_0);
120  raw0 = adc1_get_raw(this->channel1_);
121  }
122  }
123  }
124  } else if (this->channel2_ != ADC2_CHANNEL_MAX) {
125  adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_12_COMPAT);
126  adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw12);
127  if (raw12 < ADC_MAX) {
128  adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_6);
129  adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw6);
130  if (raw6 < ADC_MAX) {
131  adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_2_5);
132  adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw2);
133  if (raw2 < ADC_MAX) {
134  adc2_config_channel_atten(this->channel2_, ADC_ATTEN_DB_0);
135  adc2_get_raw(this->channel2_, ADC_WIDTH_MAX_SOC_BITS, &raw0);
136  }
137  }
138  }
139  }
140 
141  if (raw0 == -1 || raw2 == -1 || raw6 == -1 || raw12 == -1) {
142  return NAN;
143  }
144 
145  uint32_t mv12 = esp_adc_cal_raw_to_voltage(raw12, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_12_COMPAT]);
146  uint32_t mv6 = esp_adc_cal_raw_to_voltage(raw6, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_6]);
147  uint32_t mv2 = esp_adc_cal_raw_to_voltage(raw2, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_2_5]);
148  uint32_t mv0 = esp_adc_cal_raw_to_voltage(raw0, &this->cal_characteristics_[(int32_t) ADC_ATTEN_DB_0]);
149 
150  uint32_t c12 = std::min(raw12, ADC_HALF);
151  uint32_t c6 = ADC_HALF - std::abs(raw6 - ADC_HALF);
152  uint32_t c2 = ADC_HALF - std::abs(raw2 - ADC_HALF);
153  uint32_t c0 = std::min(ADC_MAX - raw0, ADC_HALF);
154  uint32_t csum = c12 + c6 + c2 + c0;
155 
156  uint32_t mv_scaled = (mv12 * c12) + (mv6 * c6) + (mv2 * c2) + (mv0 * c0);
157  return mv_scaled / (float) (csum * 1000U);
158 }
159 
160 } // namespace adc
161 } // namespace esphome
162 
163 #endif // USE_ESP32
uint8_t raw[35]
Definition: bl0939.h:19
adc_atten_t attenuation_
Definition: adc_sensor.h:77
void setup() override
Setup ADC.
InternalGPIOPin * pin_
Definition: adc_sensor.h:68
adc2_channel_t channel2_
Definition: adc_sensor.h:79
esp_adc_cal_characteristics_t cal_characteristics_[SOC_ADC_ATTEN_NUM]
Definition: adc_sensor.h:82
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
const StringRef & get_name() const
Definition: entity_base.cpp:10
adc1_channel_t channel1_
Definition: adc_sensor.h:78