ESP32-WiFi-BME
API modular para adquisición ADC continua usando DMA en ESP32-S3 y transmisión binaria mediante WebSocket utilizando FreeRTOS.
Arquitectura General
ADC -> DMA -> RingBuffer -> WebSocket
El proyecto está dividido en APIs modulares independientes:
ADCconfWiFiConfWebSocketHandler
Cada API encapsula una funcionalidad específica para facilitar integración, mantenimiento y reutilización.
ADCconf API
API encargada de configurar y manejar el ADC continuo utilizando DMA mediante la API ESP-IDF.
Características
- ADC continuo
- DMA
- Parseo automático de muestras
- Callback mediante interrupciones
- Conversión de datos crudos a
uint16_t
Configuración
Inclusión
#include "ADCconf.h"
Definición de buffers
#define MS_BLOQUE 10
adc_channel_t CHANNEL = ADC_CHANNEL_3;
const uint32_t HZ_ADC = 1000;
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};
Crear objeto ADC
ADC_BME adc1_3;
Configuración ADC
adc1_3.config(
MUESTRAS_BLOQUE,
CHANNEL,
HZ_ADC,
dma_buffer
);
Inicializar ADC
adc1_3.setup();
Lectura de muestras
uint32_t count =
adc1_3.read(samples_buffer);
La función retorna:
0si no existen datos disponibles- cantidad de muestras válidas si existen datos DMA
Flujo Interno
ADC HW
↓
DMA Buffer
↓
adc_continuous_read()
↓
adc_continuous_parse_data()
↓
samples_buffer[]
WiFiConf API
API modular para configuración WiFi en modo STA.
Características
- Configuración IP estática
- Manejo de eventos WiFi
- Reconexión automática
- Encapsulación de configuración de red
Inclusión
#include "WiFiConf.h"
Crear objeto WiFi
wifi_conf sta_esp32;
Configuración de red
const char* SSID = "MiRed";
const char* PASSWD = "password";
IPAddress local_ip(192,168,0,220);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);
IPAddress dns1(192,168,0,1);
IPAddress dns2(1,1,1,1);
Conexión WiFi
sta_esp32.conectar(
SSID,
PASSWD,
local_ip,
gateway,
subnet,
dns1,
dns2
);
Eventos Implementados
La API maneja automáticamente:
- conexión WiFi
- desconexión
- reconexión
- obtención de IP
WebSocketHandler API
API encargada de manejar eventos WebSocket.
Características
- detección de clientes
- conexión/desconexión
- recepción de mensajes
- manejo de bandera global de conexión
Inclusión
#include "WebSocketHandler.h"
Crear servidor WebSocket
WebSocketsServer webSocket(81);
Inicialización
webSocket.begin();
webSocket.onEvent(webSocketEvent);
Loop principal
webSocket.loop();
Transmisión BIN
webSocket.broadcastBIN(
(uint8_t*)buffer,
size
);
Handler de eventos
void webSocketEvent(
uint8_t num,
WStype_t type,
uint8_t * payload,
size_t length
);
Eventos soportados
Cliente conectado
WStype_CONNECTED
Cliente desconectado
WStype_DISCONNECTED
Mensajes recibidos
WStype_TEXT
Integración con FreeRTOS
El sistema utiliza multitarea mediante FreeRTOS.
ADCTask
Responsable de:
- adquisición ADC
- lectura DMA
- inserción en RingBuffer
WebSocketTask
Responsable de:
webSocket.loop()- transmisión BIN
- extracción del RingBuffer
RingBuffer
Se utiliza xRingbuffer para desacoplar:
Adquisición ADC
de:
Transmisión WebSocket
Creación
RingbufHandle_t bufferHandle =
xRingbufferCreate(
SIZE_BUFFER,
RINGBUF_TYPE_NOSPLIT
);
Inserción
xRingbufferSend(
bufferHandle,
samples_buffer,
count * sizeof(uint16_t),
pdMS_TO_TICKS(1000)
);
Recepción
uint16_t* receivedMessage =
(uint16_t*)xRingbufferReceive(
bufferHandle,
&receivedMessageSize,
pdMS_TO_TICKS(1000)
);
Cliente Python
Ejemplo de recepción de datos binarios.
from websocket import create_connection
import struct
ws = create_connection(
"ws://192.168.0.220:81"
)
while True:
data = ws.recv()
if isinstance(data, bytes):
samples = struct.unpack(
f"<{len(data)//2}H",
data
)
print(samples)
Compilación
El proyecto esta construido en PlatformIO, para compilar el poryecto es importante instalar sus herramientas en el sistema.
Dependencias
lib_deps =
links2004/WebSockets
Hardware Compatible
- ESP32-S3 DevKitC-1
- ESP32-S3 N8
Autor
Sebastian Mariano Flores