ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
adc_sensor_zephyr.cpp
Go to the documentation of this file.
1
2#include "adc_sensor.h"
3#ifdef USE_ZEPHYR
4#include "esphome/core/log.h"
5
6#include "hal/nrf_saadc.h"
7
8namespace esphome::adc {
9
10static const char *const TAG = "adc.zephyr";
11
12void ADCSensor::setup() {
13 if (!adc_is_ready_dt(this->channel_)) {
14 ESP_LOGE(TAG, "ADC controller device %s not ready", this->channel_->dev->name);
15 return;
16 }
17
18 auto err = adc_channel_setup_dt(this->channel_);
19 if (err < 0) {
20 ESP_LOGE(TAG, "Could not setup channel %s (%d)", this->channel_->dev->name, err);
21 return;
22 }
23}
24
25#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
26static const LogString *gain_to_str(enum adc_gain gain) {
27 switch (gain) {
28 case ADC_GAIN_1_6:
29 return LOG_STR("1/6");
30 case ADC_GAIN_1_5:
31 return LOG_STR("1/5");
32 case ADC_GAIN_1_4:
33 return LOG_STR("1/4");
34 case ADC_GAIN_1_3:
35 return LOG_STR("1/3");
36 case ADC_GAIN_2_5:
37 return LOG_STR("2/5");
38 case ADC_GAIN_1_2:
39 return LOG_STR("1/2");
40 case ADC_GAIN_2_3:
41 return LOG_STR("2/3");
42 case ADC_GAIN_4_5:
43 return LOG_STR("4/5");
44 case ADC_GAIN_1:
45 return LOG_STR("1");
46 case ADC_GAIN_2:
47 return LOG_STR("2");
48 case ADC_GAIN_3:
49 return LOG_STR("3");
50 case ADC_GAIN_4:
51 return LOG_STR("4");
52 case ADC_GAIN_6:
53 return LOG_STR("6");
54 case ADC_GAIN_8:
55 return LOG_STR("8");
56 case ADC_GAIN_12:
57 return LOG_STR("12");
58 case ADC_GAIN_16:
59 return LOG_STR("16");
60 case ADC_GAIN_24:
61 return LOG_STR("24");
62 case ADC_GAIN_32:
63 return LOG_STR("32");
64 case ADC_GAIN_64:
65 return LOG_STR("64");
66 case ADC_GAIN_128:
67 return LOG_STR("128");
68 }
69 return LOG_STR("undefined gain");
70}
71
72static const LogString *reference_to_str(enum adc_reference reference) {
73 switch (reference) {
74 case ADC_REF_VDD_1:
75 return LOG_STR("VDD");
76 case ADC_REF_VDD_1_2:
77 return LOG_STR("VDD/2");
78 case ADC_REF_VDD_1_3:
79 return LOG_STR("VDD/3");
80 case ADC_REF_VDD_1_4:
81 return LOG_STR("VDD/4");
82 case ADC_REF_INTERNAL:
83 return LOG_STR("INTERNAL");
84 case ADC_REF_EXTERNAL0:
85 return LOG_STR("External, input 0");
86 case ADC_REF_EXTERNAL1:
87 return LOG_STR("External, input 1");
88 }
89 return LOG_STR("undefined reference");
90}
91
92static const LogString *input_to_str(uint8_t input) {
93 switch (input) {
94 case NRF_SAADC_INPUT_AIN0:
95 return LOG_STR("AIN0");
96 case NRF_SAADC_INPUT_AIN1:
97 return LOG_STR("AIN1");
98 case NRF_SAADC_INPUT_AIN2:
99 return LOG_STR("AIN2");
100 case NRF_SAADC_INPUT_AIN3:
101 return LOG_STR("AIN3");
102 case NRF_SAADC_INPUT_AIN4:
103 return LOG_STR("AIN4");
104 case NRF_SAADC_INPUT_AIN5:
105 return LOG_STR("AIN5");
106 case NRF_SAADC_INPUT_AIN6:
107 return LOG_STR("AIN6");
108 case NRF_SAADC_INPUT_AIN7:
109 return LOG_STR("AIN7");
110 case NRF_SAADC_INPUT_VDD:
111 return LOG_STR("VDD");
112 case NRF_SAADC_INPUT_VDDHDIV5:
113 return LOG_STR("VDDHDIV5");
114 }
115 return LOG_STR("undefined input");
116}
117#endif // ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
118
120 LOG_SENSOR("", "ADC Sensor", this);
121 LOG_PIN(" Pin: ", this->pin_);
122#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
123 ESP_LOGV(TAG,
124 " Name: %s\n"
125 " Channel: %d\n"
126 " vref_mv: %d\n"
127 " Resolution %d\n"
128 " Oversampling %d",
129 this->channel_->dev->name, this->channel_->channel_id, this->channel_->vref_mv, this->channel_->resolution,
130 this->channel_->oversampling);
131
132 ESP_LOGV(TAG,
133 " Gain: %s\n"
134 " reference: %s\n"
135 " acquisition_time: %d\n"
136 " differential %s",
137 LOG_STR_ARG(gain_to_str(this->channel_->channel_cfg.gain)),
138 LOG_STR_ARG(reference_to_str(this->channel_->channel_cfg.reference)),
139 this->channel_->channel_cfg.acquisition_time, YESNO(this->channel_->channel_cfg.differential));
140 if (this->channel_->channel_cfg.differential) {
141 ESP_LOGV(TAG,
142 " Positive: %s\n"
143 " Negative: %s",
144 LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)),
145 LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_negative)));
146 } else {
147 ESP_LOGV(TAG, " Positive: %s", LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)));
148 }
149#endif
150
151 LOG_UPDATE_INTERVAL(this);
152}
153
154float ADCSensor::sample() {
155 auto aggr = Aggregator<int32_t>(this->sampling_mode_);
156 int err;
157 for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
158 int16_t buf = 0;
159 struct adc_sequence sequence = {
160 .buffer = &buf,
161 /* buffer size in bytes, not number of samples */
162 .buffer_size = sizeof(buf),
163 };
164 int32_t val_raw;
165
166 err = adc_sequence_init_dt(this->channel_, &sequence);
167 if (err < 0) {
168 ESP_LOGE(TAG, "Could sequence init %s (%d)", this->channel_->dev->name, err);
169 return 0.0;
170 }
171
172 err = adc_read(this->channel_->dev, &sequence);
173 if (err < 0) {
174 ESP_LOGE(TAG, "Could not read %s (%d)", this->channel_->dev->name, err);
175 return 0.0;
176 }
177
178 val_raw = (int32_t) buf;
179 if (!this->channel_->channel_cfg.differential) {
180 // https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/0ed4d9ffc674ae407be7cacf5696a02f5e789861/cores/nRF5/wiring_analog_nRF52.c#L222
181 if (val_raw < 0) {
182 val_raw = 0;
183 }
184 }
185 aggr.add_sample(val_raw);
186 }
187
188 int32_t val_mv = aggr.aggregate();
189
190 if (this->output_raw_) {
191 return val_mv;
192 }
193
194 err = adc_raw_to_millivolts_dt(this->channel_, &val_mv);
195 /* conversion to mV may not be supported, skip if not */
196 if (err < 0) {
197 ESP_LOGE(TAG, "Value in mV not available %s (%d)", this->channel_->dev->name, err);
198 return 0.0;
199 }
200
201 return val_mv / 1000.0f;
202}
203
204} // namespace esphome::adc
205#endif
float sample() override
Perform a single ADC sampling operation and return the measured value.
void setup() override
Set up the ADC sensor by initializing hardware and calibration parameters.
InternalGPIOPin * pin_
Definition adc_sensor.h:133
void dump_config() override
Output the configuration details of the ADC sensor for debugging purposes.
SamplingMode sampling_mode_
Definition adc_sensor.h:134
adc_channel_t channel_
Definition adc_sensor.h:143
AlsGain501 gain