Bibliotecas cliente IoT para ESP32 en ESP-IDF (C). Compatible con el middleware SensorWave Go y MicroPython.
- MQTT: Cliente completo con QoS dinámico, suscripciones QoS 2
- HTTP: Soporte SSE (Server-Sent Events), ACKs y retransmisión
- CoAP: Implementación ligera con Observe (suscripciones)
- API Unificada: Misma interfaz que MicroPython
- Compatibilidad 100%: Formato JSON, Base64, URL encoding idéntico a Go
nodo-esp32/
├── main/ # Código principal
│ ├── middleware.c/.h # API principal
│ ├── mqtt.c/.h # Cliente MQTT
│ ├── http.c/.h # Cliente HTTP
│ ├── coap.c/.h # Cliente CoAP
│ ├── wifi.c/.h # Gestión WiFi
│ ├── app_main.c # Ejemplo de uso
│ └── CMakeLists.txt # Build config
├── test/ # Tests unitarios
│ ├── test_sensorwave.c
│ └── CMakeLists.txt
├── CMakeLists.txt # Build principal
├── sdkconfig.defaults # Configuración ESP-IDF
└── idf_component.yml # Dependencias
Requisitos:
- ESP-IDF v5.0 o superior
- Python 3.8+
- CMake 3.16+
Instalación (Linux/macOS):
# Clonar ESP-IDF
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
# Instalar
./install.sh esp32
# Configurar entorno
source export.shInstalación (Windows):
# Usar el instalador oficial de ESP-IDF
# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/# Clonar repositorio
git clone <repositorio-sensorwave>
cd sensorwave/nodo-esp32
# Configurar entorno ESP-IDF
source /path/to/esp-idf/export.sh# Configurar WiFi y opciones (opcional)
idf.py menuconfig
# O editar directamente sdkconfig.defaults# Compilar
idf.py build
# Flash y monitorear
idf.py -p /dev/ttyUSB0 flash monitorReemplazar /dev/ttyUSB0 con tu puerto (Windows: COM3, etc.)
#include "middleware.h"
#include "wifi.h"
// Callback para recibir mensajes
void mi_callback(const char *topico, const char *mensaje) {
printf("Recibido: %s = %s\n", topico, mensaje);
}
void app_main(void) {
// Inicializar WiFi
wifi_conectar("SSID", "PASSWORD", 30);
// Conectar
middleware_conectar(MQTT, "broker.hivemq.com", 1883);
// Suscribirse
middleware_suscribir("casa/sensor", mi_callback);
// Publicar (QoS 0)
middleware_publicar("casa/sensor", "25.5");
// Publicar con QoS 1
middleware_publicar_con_qos("casa/sensor", "25.5", 1);
// Loop principal (FreeRTOS)
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}#include "middleware.h"
#include "wifi.h"
// Callback para notificaciones SSE
void mi_callback(const char *topico, const char *mensaje) {
printf("Notificación: %s\n", mensaje);
}
void app_main(void) {
// Inicializar WiFi
wifi_conectar("SSID", "PASSWORD", 30);
// Conectar
middleware_conectar(HTTP, "192.168.1.100", 8080);
// Suscribirse a notificaciones SSE
middleware_suscribir("alertas", mi_callback);
// Publicar con QoS 1 (reintentos automáticos)
middleware_publicar_con_qos("datos/sensor", "humedad:60%", 1);
}#include "middleware.h"
#include "wifi.h"
// Callback
void mi_callback(const char *topico, const char *mensaje) {
printf("Dato CoAP: %s\n", mensaje);
}
void app_main(void) {
// Inicializar WiFi
wifi_conectar("SSID", "PASSWORD", 30);
// Conectar
middleware_conectar(COAP, "192.168.1.100", 5683);
// Suscribirse (Observe)
middleware_suscribir("sensor/temp", mi_callback);
// Publicar (NON si qos=0, CON si qos=1)
middleware_publicar_con_qos("sensor/temp", "22.5", 1);
}typedef enum {
MQTT, // = 0
HTTP, // = 1
COAP // = 2
} Protocolo;
#define MAX_PAYLOAD_SIZE 65536 // 64KB máximoInicializa la conexión con el protocolo especificado.
Args:
protocolo:MQTT,HTTPoCOAPhost: Dirección IP o hostname (const char*)puerto: Puerto del servidor (int)
Suscribe a un tópico.
Args:
topico: String con el nombre del tópicocallback: Funciónvoid callback(const char *topico, const char *mensaje)
QoS por protocolo:
- MQTT: Suscripción con QoS 2 (automático)
- HTTP: SSE (Server-Sent Events)
- CoAP: Observe (RFC 7641)
Publica un mensaje con QoS 0.
Args:
topico: String con el nombre del tópicomensaje: String con el contenido
Publica un mensaje.
Args:
topico: String con el nombre del tópicomensaje: String con el contenidoqos: 0 o 1
Comportamiento por protocolo:
| Protocolo | QoS 0 | QoS 1 |
|---|---|---|
| MQTT | Fire & forget | ACK del broker |
| HTTP | POST simple | POST + ACK (4 reintentos) |
| CoAP | NON | CON + ACK |
Desuscribe de un tópico.
Cierra la conexión y libera recursos.
Libera la memoria de un mensaje.
Verifica si un tópico coincide con un patrón (soporta wildcards + y #).
# Configuración WiFi por defecto (opcional)
CONFIG_EXAMPLE_WIFI_SSID="tu_ssid"
CONFIG_EXAMPLE_WIFI_PASSWORD="tu_password"
// http.c
#define ACK_TIMEOUT_MS 2000 // Timeout para ACKs HTTP
#define ACK_RANDOM_FACTOR 1.5 // Factor de backoff
#define MAX_RETRANSMIT 4 // Máximo de reintentosVer archivo main/app_main.c:
- Conexión WiFi
- Conexión CoAP
- Suscripción con wildcards (
sensores/#) - Publicación con QoS 1
El archivo idf_component.yml gestiona automáticamente:
espressif/coap- Librería libcoap para CoAPprotocol_examples_common- Componentes comunes de ESP-IDF
Incluidos en ESP-IDF:
esp_mqtt- Cliente MQTTesp_http_client- Cliente HTTPesp_wifi- WiFifreertos- Sistema operativo
El cliente HTTP incluye reconexión automática SSE:
- Hasta 5 intentos de reconexión
- Delay de 2 segundos entre intentos
- Limpieza automática de suscripciones fallidas
Los ACKs de QoS 1 se envían mediante tareas FreeRTOS:
- No bloquean la recepción de mensajes
- Cola interna para manejar múltiples ACKs pendientes
Todas las operaciones de red validan conexión WiFi activa:
- Excepción clara si no hay WiFi
- Timeout configurable en
wifi_conectar()
Todas las operaciones son thread-safe con FreeRTOS:
- Mutex automáticos con
xSemaphoreCreateMutex() - Protección contra race conditions en callbacks concurrentes
- Basado en FreeRTOS para tareas concurrentes
- Usa las APIs nativas de ESP-IDF para MQTT, HTTP y CoAP
- Recomendado: ESP-IDF v5.0+ con soporte completo de CoAP
- Memoria heap configurable vía
sdkconfig
# Compilar tests
idf.py -DBUILD_TEST_APP=ON build
# O usando el script incluido
./run_tests.sh./run_sequential_tests.shSolución: Verificar credenciales WiFi y señal:
wifi_conectar("SSID", "PASSWORD", 30); // 30 segundos timeoutSolución: El ESP32 tiene RAM limitada. Intentar:
- Aumentar heap en
sdkconfig:CONFIG_ESP32_DEFAULT_CPU_FREQ_240 - Usar solo un protocolo a la vez
- Liberar mensajes con
mensaje_liberar()
Solución: Verificar que el servidor CoAP esté accesible y el puerto 5683 esté abierto.
Solución: Verificar URL del broker y conectividad de red:
middleware_conectar(MQTT, "broker.hivemq.com", 1883);MIT License - Ver LICENSE en el repositorio principal.
Versión: 1.0.0
Compatible con: ESP32, ESP32-S3, ESP-IDF >= 5.0
Middleware: SensorWave