libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
esp_adc.hpp
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5
6#include "adc.hpp"
7#include "esp_adc/adc_continuous.h"
8#include "hal/adc_types.h"
9
10#if (SOC_ADC_DIGI_RESULT_BYTES == 2)
11#define XR_ADC_DMA_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1
12#define XR_ADC_DMA_GET_CHANNEL(p_data) ((p_data)->type1.channel)
13#define XR_ADC_DMA_GET_DATA(p_data) ((p_data)->type1.data)
14#else
15#define XR_ADC_DMA_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2
16#define XR_ADC_DMA_GET_CHANNEL(p_data) ((p_data)->type2.channel)
17#define XR_ADC_DMA_GET_DATA(p_data) ((p_data)->type2.data)
18#endif
19
20namespace LibXR
21{
22
30{
31 public:
35 class Channel : public ADC
36 {
37 public:
41 Channel() : parent_(nullptr), idx_(0), channel_num_(0) {}
42
50 Channel(ESP32ADC* parent, uint8_t idx, uint8_t channel_num)
51 : parent_(parent), idx_(idx), channel_num_(channel_num)
52 {
53 }
54
60 float Read() override { return parent_ ? parent_->ReadChannel(idx_) : 0.f; }
61
67 uint8_t ChannelNumber() const { return channel_num_; }
68
69 private:
71 uint8_t idx_;
72 uint8_t channel_num_;
73 };
74
88 adc_unit_t unit, const adc_channel_t* channels, uint8_t num_channels,
89 uint32_t freq = SOC_ADC_SAMPLE_FREQ_THRES_LOW,
90 adc_atten_t attenuation = ADC_ATTEN_DB_12,
91 adc_bitwidth_t bitwidth = static_cast<adc_bitwidth_t>(SOC_ADC_DIGI_MAX_BITWIDTH),
92 float reference_voltage = 3.3f, size_t dma_buf_size = 256)
93 : m_unit_(unit),
94 m_num_channels_(num_channels),
95 m_attenuation_(attenuation),
96 m_bitwidth_(bitwidth),
97 m_reference_voltage_(reference_voltage),
98 m_max_raw_((1 << bitwidth) - 1)
99 {
100 m_patterns_ = new adc_digi_pattern_config_t[m_num_channels_];
103 m_sum_buf_ = new int[m_num_channels_];
104 m_cnt_buf_ = new int[m_num_channels_];
105
106 for (uint8_t i = 0; i < m_num_channels_; ++i)
107 {
108 m_patterns_[i].atten = static_cast<uint8_t>(m_attenuation_);
109 m_patterns_[i].channel = channels[i];
110 m_patterns_[i].unit = static_cast<uint8_t>(m_unit_);
111 m_patterns_[i].bit_width = static_cast<uint8_t>(m_bitwidth_);
112 m_channels_[i] = Channel(this, i, channels[i]);
113 m_latest_values_[i] = 0.f;
114 }
115
116 adc_continuous_handle_cfg_t adc_config = {
117 .max_store_buf_size = dma_buf_size,
118 .conv_frame_size = dma_buf_size / 2,
119 .flags = {.flush_pool = 1},
120 };
121 ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_config, &m_handle_));
122
123 adc_continuous_config_t dig_cfg = {};
124 dig_cfg.sample_freq_hz = freq;
125 if (m_unit_ == ADC_UNIT_1)
126 {
127 dig_cfg.conv_mode = ADC_CONV_SINGLE_UNIT_1;
128 }
129 else
130 {
131 dig_cfg.conv_mode = ADC_CONV_SINGLE_UNIT_2;
132 }
133 dig_cfg.format = XR_ADC_DMA_OUTPUT_TYPE;
134 dig_cfg.adc_pattern = m_patterns_;
135 dig_cfg.pattern_num = m_num_channels_;
136 ESP_ERROR_CHECK(adc_continuous_config(m_handle_, &dig_cfg));
137
138 adc_continuous_evt_cbs_t cbs = {
139 .on_conv_done = &ESP32ADC::OnConvDone,
140 };
141 ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(m_handle_, &cbs, this));
142 ESP_ERROR_CHECK(adc_continuous_start(m_handle_));
143 }
144
149 {
150 if (m_handle_)
151 {
152 adc_continuous_stop(m_handle_);
153 adc_continuous_deinit(m_handle_);
154 }
155 delete[] m_patterns_;
156 delete[] m_channels_;
157 delete[] m_latest_values_;
158 delete[] m_sum_buf_;
159 delete[] m_cnt_buf_;
160 }
161
167 Channel& GetChannel(uint8_t idx) { return m_channels_[idx]; }
168
174 float ReadChannel(uint8_t idx) { return m_latest_values_[idx]; }
175
176 private:
180 static bool IRAM_ATTR OnConvDone(adc_continuous_handle_t handle,
181 const adc_continuous_evt_data_t* edata,
182 void* user_data)
183 {
184 auto* self = reinterpret_cast<ESP32ADC*>(user_data);
185 self->HandleSamples(edata->conv_frame_buffer, edata->size);
186 return false;
187 }
188
195 void HandleSamples(const void* buf, size_t size_bytes)
196 {
197 for (uint8_t idx = 0; idx < m_num_channels_; ++idx)
198 {
199 m_sum_buf_[idx] = 0;
200 m_cnt_buf_[idx] = 0;
201 }
202
203 size_t n = size_bytes / sizeof(adc_digi_output_data_t);
204 const adc_digi_output_data_t* samples =
205 static_cast<const adc_digi_output_data_t*>(buf);
206
207 for (size_t i = 0; i < n; ++i)
208 {
209 uint8_t ch = XR_ADC_DMA_GET_CHANNEL(&samples[i]);
210 for (uint8_t idx = 0; idx < m_num_channels_; ++idx)
211 {
212 if (ch == m_channels_[idx].ChannelNumber())
213 {
214 int raw = XR_ADC_DMA_GET_DATA(&samples[i]);
215 m_sum_buf_[idx] += raw;
216 m_cnt_buf_[idx] += 1;
217 break;
218 }
219 }
220 }
221
222 for (uint8_t idx = 0; idx < m_num_channels_; ++idx)
223 {
224 if (m_cnt_buf_[idx] > 0)
225 {
226 float avg = Normalize(static_cast<float>(m_sum_buf_[idx]) / m_cnt_buf_[idx]);
227 m_latest_values_[idx] = avg;
228 }
229 }
230 }
231
238 float Normalize(float raw) const
239 {
240 return (raw / static_cast<float>(m_max_raw_)) * m_reference_voltage_;
241 }
242
243 adc_digi_pattern_config_t* m_patterns_;
248
249 adc_unit_t m_unit_;
251 adc_atten_t m_attenuation_;
252 adc_bitwidth_t m_bitwidth_;
254 uint16_t m_max_raw_;
255 adc_continuous_handle_t m_handle_ = nullptr;
256};
257
258} // namespace LibXR
模拟数字转换器(ADC)基类
Definition adc.hpp:18
ADC 通道对象 / ADC channel object.
Definition esp_adc.hpp:36
uint8_t channel_num_
物理通道号 / Physical ADC channel number
Definition esp_adc.hpp:72
uint8_t ChannelNumber() const
获取物理通道号 / Get physical channel number
Definition esp_adc.hpp:67
Channel(ESP32ADC *parent, uint8_t idx, uint8_t channel_num)
构造通道对象 / Construct channel object
Definition esp_adc.hpp:50
float Read() override
读取当前通道电压值 / Read channel voltage
Definition esp_adc.hpp:60
uint8_t idx_
逻辑通道号 / Logical index
Definition esp_adc.hpp:71
Channel()
默认构造函数 / Default constructor
Definition esp_adc.hpp:41
ESP32ADC * parent_
父ADC对象 / Parent ADC pointer
Definition esp_adc.hpp:70
ESP32 多通道 ADC 驱动 / ESP32 multi-channel ADC driver.
Definition esp_adc.hpp:30
int * m_cnt_buf_
计数缓冲 / Count buffer
Definition esp_adc.hpp:247
float m_reference_voltage_
参考电压 / Reference voltage
Definition esp_adc.hpp:253
float ReadChannel(uint8_t idx)
读取指定通道电压值 / Read channel voltage
Definition esp_adc.hpp:174
Channel & GetChannel(uint8_t idx)
获取通道对象 / Get channel object
Definition esp_adc.hpp:167
float Normalize(float raw) const
将原始 ADC 值归一化为电压 / Normalize raw ADC to voltage
Definition esp_adc.hpp:238
adc_continuous_handle_t m_handle_
ESP-IDF采集句柄 / ADC handle.
Definition esp_adc.hpp:255
float * m_latest_values_
最新均值(每通道)/ Latest average value (per channel)
Definition esp_adc.hpp:245
ESP32ADC(adc_unit_t unit, const adc_channel_t *channels, uint8_t num_channels, uint32_t freq=SOC_ADC_SAMPLE_FREQ_THRES_LOW, adc_atten_t attenuation=ADC_ATTEN_DB_12, adc_bitwidth_t bitwidth=static_cast< adc_bitwidth_t >(SOC_ADC_DIGI_MAX_BITWIDTH), float reference_voltage=3.3f, size_t dma_buf_size=256)
构造 ADC 驱动对象 / Construct ADC driver
Definition esp_adc.hpp:87
void HandleSamples(const void *buf, size_t size_bytes)
解析 DMA 缓冲并计算均值 / Parse DMA buffer and compute averages
Definition esp_adc.hpp:195
Channel * m_channels_
通道对象数组 / Channel objects array
Definition esp_adc.hpp:244
adc_unit_t m_unit_
ADC单元 / ADC unit.
Definition esp_adc.hpp:249
uint8_t m_num_channels_
通道数 / Number of channels
Definition esp_adc.hpp:250
int * m_sum_buf_
求和缓冲 / Accumulation buffer
Definition esp_adc.hpp:246
static bool IRAM_ATTR OnConvDone(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data)
DMA 采样完成回调 / DMA conversion done callback.
Definition esp_adc.hpp:180
uint16_t m_max_raw_
最大原始采样值 / Max raw value
Definition esp_adc.hpp:254
adc_digi_pattern_config_t * m_patterns_
ADC采样模式数组 / Pattern config array.
Definition esp_adc.hpp:243
~ESP32ADC()
析构函数 / Destructor
Definition esp_adc.hpp:148
adc_bitwidth_t m_bitwidth_
位宽 / Bit width
Definition esp_adc.hpp:252
adc_atten_t m_attenuation_
衰减档位 / Attenuation
Definition esp_adc.hpp:251
LibXR 命名空间
Definition ch32_can.hpp:14