Feature:ADC

This commit is contained in:
semarnat committed 2026-05-22 10:26:17 -06:00
1 parent ccf59b22e5
commit 80a703673f
3 files changed
+139 -8

No files matched your search

+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "Arduino.h"
#include "esp_adc/adc_continuous.h"
class ADC_BME {
private:
uint32_t _FRAME_SIZE;
uint32_t _POOL_SIZE;
uint32_t _HZ_ADC;
adc_channel_t _channel;
uint8_t* _dma_buffer;
volatile bool dma_data_ready = false;
adc_continuous_handle_t handle_ADC = NULL;
static bool IRAM_ATTR adc_dma_callback(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data);
public:
void config(const uint32_t muestras_bloque, adc_channel_t channel, const uint32_t hz_adc, uint8_t* dma_buffer);
void setup();
uint32_t read(uint16_t* samples_buffer);
};
+94
View File
@@ -0,0 +1,94 @@
#include "ADCconf.h"
bool IRAM_ATTR ADC_BME::adc_dma_callback(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data){
ADC_BME* adc =static_cast<ADC_BME*>(user_data);
adc->dma_data_ready = true;
return false;
}
void ADC_BME::config(const uint32_t muestras_bloque, adc_channel_t channel, const uint32_t hz_adc, uint8_t* dma_buffer){
_FRAME_SIZE=muestras_bloque*4;
_POOL_SIZE=_FRAME_SIZE*4;
_channel=channel;
_HZ_ADC=hz_adc;
_dma_buffer=dma_buffer;
}
void ADC_BME::setup(){
adc_continuous_handle_cfg_t ADC_config = {
.max_store_buf_size = _POOL_SIZE,
.conv_frame_size = _FRAME_SIZE,
};
ESP_ERROR_CHECK(adc_continuous_new_handle(&ADC_config, &handle_ADC));
adc_digi_pattern_config_t channel_config = {0};
channel_config.channel = _channel;
channel_config.atten = ADC_ATTEN_DB_12;
channel_config.bit_width = ADC_BITWIDTH_12;
channel_config.unit = ADC_UNIT_1;
adc_continuous_config_t adc_config = {
.pattern_num = 1,
.adc_pattern = &channel_config,
.sample_freq_hz = _HZ_ADC,
.conv_mode = ADC_CONV_SINGLE_UNIT_1,
};
ESP_ERROR_CHECK(adc_continuous_config(handle_ADC, &adc_config));
adc_continuous_evt_cbs_t cb_config = {
.on_conv_done = adc_dma_callback,
.on_pool_ovf = NULL
};
ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(handle_ADC, &cb_config, this));
ESP_ERROR_CHECK(adc_continuous_start(handle_ADC));
Serial.println("DMA Iniciado con sistema de bandera.");
}
uint32_t ADC_BME::read(uint16_t* samples_buffer) {
if (!dma_data_ready) {
return 0;
}
dma_data_ready = false;
uint32_t ret_num = 0;
// Leer datos DMA
esp_err_t ret = adc_continuous_read(handle_ADC,_dma_buffer,_FRAME_SIZE,&ret_num,0);
if (ret != ESP_OK)
return 0;
// Buffer temporal parseado
adc_continuous_data_t parsed_data[_FRAME_SIZE/4];
uint32_t parsed_count = 0;
// Parsear datos
esp_err_t parse_ret =
adc_continuous_parse_data(
handle_ADC,
_dma_buffer,
ret_num,
parsed_data,
&parsed_count
);
if (parse_ret != ESP_OK) {
return 0;
}
uint32_t valid_samples = 0;
// Copiar muestras limpias
for (uint32_t i = 0; i < parsed_count; i++) {
if (!parsed_data[i].valid)
continue;
samples_buffer[valid_samples] = parsed_data[i].raw_data;
valid_samples++;
}
return valid_samples;
}
+25 -8
View File
@@ -1,9 +1,19 @@
#include "Arduino.h" #include "Arduino.h"
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
//DEBUG #include "ADCconf.h"
uint8_t i_debug[10] = {0,1,2,3,4,5,6,7,8,9};
const uint16_t SIZE_BUFFER = 1024; // API ESP-IDF para ADC modo continuo (uso de DMA)
#define MS_BLOQUE 10
adc_channel_t CHANNEL = ADC_CHANNEL_3;
const uint32_t HZ_ADC = 1000; // Limitado a 611 - 83333 para el ESP32-S3
const uint32_t MUESTRAS_BLOQUE = (HZ_ADC * MS_BLOQUE) / 1000;
uint8_t dma_buffer[MUESTRAS_BLOQUE * SOC_ADC_DIGI_RESULT_BYTES] = {0};
uint16_t samples_buffer[MUESTRAS_BLOQUE] = {0};
const uint32_t SIZE_BUFFER = MUESTRAS_BLOQUE*10;
ADC_BME adc1_3;
// FreeRTOS // FreeRTOS
TaskHandle_t ADCTaskHandle = NULL; TaskHandle_t ADCTaskHandle = NULL;
TaskHandle_t WebSocketTaskHandle = NULL; TaskHandle_t WebSocketTaskHandle = NULL;
@@ -15,6 +25,9 @@ void WebSocketTask(void *parameter);
void setup(){ void setup(){
Serial.begin(230400); Serial.begin(230400);
adc1_3.config(MUESTRAS_BLOQUE, CHANNEL, HZ_ADC, dma_buffer);
adc1_3.setup();
//Iniciar el buffer circular //Iniciar el buffer circular
if (bufferHandle == NULL) { if (bufferHandle == NULL) {
Serial.printf("Failed to create ring buffer!"); Serial.printf("Failed to create ring buffer!");
@@ -22,7 +35,7 @@ void setup(){
} }
xTaskCreatePinnedToCore( ADCTask, "ADCTask", 10000, NULL, 1, &ADCTaskHandle, 0); xTaskCreatePinnedToCore( ADCTask, "ADCTask", 10000, NULL, 1, &ADCTaskHandle, 0);
xTaskCreatePinnedToCore( WebSocketTask, "WebSocketTask", 10000, NULL, 1, &WebSocketTaskHandle, 0); xTaskCreatePinnedToCore( WebSocketTask, "WebSocketTask", 10000, NULL, 1, &WebSocketTaskHandle, 1);
} }
void loop(){ void loop(){
@@ -30,9 +43,12 @@ void loop(){
void ADCTask(void *parameter){ void ADCTask(void *parameter){
for(;;) { for(;;) {
if (xRingbufferSend(bufferHandle, i_debug, sizeof(i_debug), pdMS_TO_TICKS(1000)) != pdTRUE) { uint32_t count = adc1_3.read(samples_buffer);
if (count > 0) {
if (xRingbufferSend(bufferHandle, samples_buffer, count * sizeof(uint16_t), pdMS_TO_TICKS(1000)) != pdTRUE) {
Serial.println("Failed to send message to ring buffer!"); Serial.println("Failed to send message to ring buffer!");
} }
}
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
} }
} }
@@ -40,12 +56,13 @@ void ADCTask(void *parameter){
void WebSocketTask(void *parameter){ void WebSocketTask(void *parameter){
for(;;) { for(;;) {
size_t receivedMessageSize; size_t receivedMessageSize;
uint8_t* receivedMessage = (uint8_t*)xRingbufferReceive(bufferHandle, &receivedMessageSize, pdMS_TO_TICKS(1000)); uint16_t* receivedMessage = (uint16_t*)xRingbufferReceive(bufferHandle, &receivedMessageSize, pdMS_TO_TICKS(1000));
// 6. Check if the receive operation was successful // 6. Check if the receive operation was successful
if (receivedMessage != NULL) { if (receivedMessage != NULL) {
for(size_t i = 0; i < receivedMessageSize; i++) { size_t samples = receivedMessageSize / sizeof(uint16_t);
Serial.printf("%d ", receivedMessage[i]);} for(size_t i = 0; i < samples; i++) {
Serial.printf("%u ", receivedMessage[i]);}
Serial.println(); Serial.println();
vRingbufferReturnItem(bufferHandle, (void*)receivedMessage); vRingbufferReturnItem(bufferHandle, (void*)receivedMessage);
} else { } else {