ESPHome  2025.2.0
adc_sensor_rp2040.cpp
Go to the documentation of this file.
1 #ifdef USE_RP2040
2 
3 #include "adc_sensor.h"
4 #include "esphome/core/log.h"
5 
6 #ifdef CYW43_USES_VSYS_PIN
7 #include "pico/cyw43_arch.h"
8 #endif // CYW43_USES_VSYS_PIN
9 #include <hardware/adc.h>
10 
11 namespace esphome {
12 namespace adc {
13 
14 static const char *const TAG = "adc.rp2040";
15 
16 void ADCSensor::setup() {
17  ESP_LOGCONFIG(TAG, "Setting up ADC '%s'...", this->get_name().c_str());
18  static bool initialized = false;
19  if (!initialized) {
20  adc_init();
21  initialized = true;
22  }
23 }
24 
26  LOG_SENSOR("", "ADC Sensor", this);
27  if (this->is_temperature_) {
28  ESP_LOGCONFIG(TAG, " Pin: Temperature");
29  } else {
30 #ifdef USE_ADC_SENSOR_VCC
31  ESP_LOGCONFIG(TAG, " Pin: VCC");
32 #else
33  LOG_PIN(" Pin: ", this->pin_);
34 #endif // USE_ADC_SENSOR_VCC
35  }
36  ESP_LOGCONFIG(TAG, " Samples: %i", this->sample_count_);
37  ESP_LOGCONFIG(TAG, " Sampling mode: %s", LOG_STR_ARG(sampling_mode_to_str(this->sampling_mode_)));
38  LOG_UPDATE_INTERVAL(this);
39 }
40 
41 float ADCSensor::sample() {
42  uint32_t raw = 0;
43  auto aggr = Aggregator(this->sampling_mode_);
44 
45  if (this->is_temperature_) {
46  adc_set_temp_sensor_enabled(true);
47  delay(1);
48  adc_select_input(4);
49 
50  for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
51  raw = adc_read();
52  aggr.add_sample(raw);
53  }
54  adc_set_temp_sensor_enabled(false);
55  if (this->output_raw_) {
56  return aggr.aggregate();
57  }
58  return aggr.aggregate() * 3.3f / 4096.0f;
59  }
60 
61  uint8_t pin = this->pin_->get_pin();
62 #ifdef CYW43_USES_VSYS_PIN
63  if (pin == PICO_VSYS_PIN) {
64  // Measuring VSYS on Raspberry Pico W needs to be wrapped with
65  // `cyw43_thread_enter()`/`cyw43_thread_exit()` as discussed in
66  // https://github.com/raspberrypi/pico-sdk/issues/1222, since Wifi chip and
67  // VSYS ADC both share GPIO29
68  cyw43_thread_enter();
69  }
70 #endif // CYW43_USES_VSYS_PIN
71 
72  adc_gpio_init(pin);
73  adc_select_input(pin - 26);
74 
75  for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
76  raw = adc_read();
77  aggr.add_sample(raw);
78  }
79 
80 #ifdef CYW43_USES_VSYS_PIN
81  if (pin == PICO_VSYS_PIN) {
82  cyw43_thread_exit();
83  }
84 #endif // CYW43_USES_VSYS_PIN
85 
86  if (this->output_raw_) {
87  return aggr.aggregate();
88  }
89  float coeff = pin == PICO_VSYS_PIN ? 3.0f : 1.0f;
90  return aggr.aggregate() * 3.3f / 4096.0f * coeff;
91 }
92 
93 } // namespace adc
94 } // namespace esphome
95 
96 #endif // USE_RP2040
const LogString * sampling_mode_to_str(SamplingMode mode)
uint8_t raw[35]
Definition: bl0939.h:19
SamplingMode sampling_mode_
Definition: adc_sensor.h:87
void setup() override
Setup ADC.
virtual uint8_t get_pin() const =0
InternalGPIOPin * pin_
Definition: adc_sensor.h:84
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
const StringRef & get_name() const
Definition: entity_base.cpp:10
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26