#include "Arduino.h" #include "esp_adc/adc_continuous.h" // API ESP-IDF para ADC modo continuo (uso de DMA) adc_channel_t CHANNEL = ADC_CHANNEL_3; #define MS_BLOQUE 10 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}; 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){ ADC_BME* adc =static_cast(user_data); adc->dma_data_ready = true; return false; } public: void 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 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 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[MUESTRAS_BLOQUE]; 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; } }; ADC_BME adc1_3; void setup() { Serial.begin(230400); adc1_3.config(MUESTRAS_BLOQUE, CHANNEL, HZ_ADC, dma_buffer); adc1_3.setup(); } void loop() { uint32_t count = adc1_3.read(samples_buffer); for (uint32_t i = 0; i < count; i++) { Serial.printf("%u\n",samples_buffer[i]); } }