ESPHome 2026.11.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
10ESPHOME_LOG_TAG(TAG, "adc");
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 default:
115 break;
116 }
117 return LOG_STR("undefined input");
118}
119#endif // ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
120
122 LOG_SENSOR("", "ADC Sensor", this);
123 LOG_PIN(" Pin: ", this->pin_);
124#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
125 ESP_LOGV(TAG,
126 " Name: %s\n"
127 " Channel: %d\n"
128 " vref_mv: %d\n"
129 " Resolution %d\n"
130 " Oversampling %d",
131 this->channel_->dev->name, this->channel_->channel_id, this->channel_->vref_mv, this->channel_->resolution,
132 this->channel_->oversampling);
133
134 ESP_LOGV(TAG,
135 " Gain: %s\n"
136 " reference: %s\n"
137 " acquisition_time: %d\n"
138 " differential %s",
139 LOG_STR_ARG(gain_to_str(this->channel_->channel_cfg.gain)),
140 LOG_STR_ARG(reference_to_str(this->channel_->channel_cfg.reference)),
141 this->channel_->channel_cfg.acquisition_time, YESNO(this->channel_->channel_cfg.differential));
142 if (this->channel_->channel_cfg.differential) {
143 ESP_LOGV(TAG,
144 " Positive: %s\n"
145 " Negative: %s",
146 LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)),
147 LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_negative)));
148 } else {
149 ESP_LOGV(TAG, " Positive: %s", LOG_STR_ARG(input_to_str(this->channel_->channel_cfg.input_positive)));
150 }
151#endif
152
153 LOG_UPDATE_INTERVAL(this);
154}
155
156float ADCSensor::sample() {
157 auto aggr = Aggregator<int32_t>(this->sampling_mode_);
158 int err;
159 for (uint8_t sample = 0; sample < this->sample_count_; sample++) {
160 int16_t buf = 0;
161 struct adc_sequence sequence = {
162 .buffer = &buf,
163 /* buffer size in bytes, not number of samples */
164 .buffer_size = sizeof(buf),
165 };
166 int32_t val_raw;
167
168 err = adc_sequence_init_dt(this->channel_, &sequence);
169 if (err < 0) {
170 ESP_LOGE(TAG, "Could sequence init %s (%d)", this->channel_->dev->name, err);
171 return 0.0;
172 }
173
174 err = adc_read(this->channel_->dev, &sequence);
175 if (err < 0) {
176 ESP_LOGE(TAG, "Could not read %s (%d)", this->channel_->dev->name, err);
177 return 0.0;
178 }
179
180 val_raw = (int32_t) buf;
181 if (!this->channel_->channel_cfg.differential) {
182 // https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/0ed4d9ffc674ae407be7cacf5696a02f5e789861/cores/nRF5/wiring_analog_nRF52.c#L222
183 if (val_raw < 0) {
184 val_raw = 0;
185 }
186 }
187 aggr.add_sample(val_raw);
188 }
189
190 int32_t val_mv = aggr.aggregate();
191
192 if (this->output_raw_) {
193 return val_mv;
194 }
195
196 err = adc_raw_to_millivolts_dt(this->channel_, &val_mv);
197 /* conversion to mV may not be supported, skip if not */
198 if (err < 0) {
199 ESP_LOGE(TAG, "Value in mV not available %s (%d)", this->channel_->dev->name, err);
200 return 0.0;
201 }
202
203 return val_mv / 1000.0f;
204}
205
206} // namespace esphome::adc
207#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
ESPHOME_LOG_TAG(TAG, "adc")