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