WiFi y publicación MQTT
En este tutorial el ESP32 se conectará a tu red WiFi local y enviará mensajes MQTT al broker Mosquitto que levantaste en el tutorial de Node-RED + Mosquitto. Node-RED recibirá los datos y los mostrará en el dashboard en tiempo real.
Arquitectura del flujo
Sección titulada «Arquitectura del flujo»[ESP32] │ WiFi (red local) │ TCP puerto 1883 ▼[Mosquitto broker] ← corriendo en Docker en tu PC │ topic: sensores/temperatura ▼[Node-RED] ← nodo "mqtt in" suscrito al topic │ ▼[Dashboard] ← gauge + chart en tiempo realPaso 1: Instalar las librerías necesarias
Sección titulada «Paso 1: Instalar las librerías necesarias»PubSubClient (cliente MQTT)
Sección titulada «PubSubClient (cliente MQTT)»- En Arduino IDE: Sketch → Incluir Librería → Gestionar Librerías (o
Ctrl + Shift + I) - Busca
PubSubClient - Instala PubSubClient by Nick O’Leary (la más popular, más de 10 millones de descargas)
ArduinoJson (formato de payload)
Sección titulada «ArduinoJson (formato de payload)»- En el mismo gestor, busca
ArduinoJson - Instala ArduinoJson by Benoit Blanchon — elige la versión 7.x más reciente
Paso 2: Encontrar la IP del servidor Mosquitto
Sección titulada «Paso 2: Encontrar la IP del servidor Mosquitto»El ESP32 se conectará a Mosquitto usando la dirección IP de tu PC en la red local (no localhost, ya que localhost para el ESP32 sería él mismo).
En tu PC, abre PowerShell o CMD:
ipconfigBusca la sección de tu adaptador WiFi o Ethernet y anota la Dirección IPv4:
Adaptador de Ethernet Ethernet: Dirección IPv4 . . . . . . . . : 192.168.1.100 ← esta es la que necesitasPaso 3: Sketch básico — datos simulados
Sección titulada «Paso 3: Sketch básico — datos simulados»Este sketch se conecta al WiFi y publica una temperatura simulada cada 5 segundos. Es el punto de partida ideal para verificar que todo el pipeline funciona antes de conectar sensores reales.
#include <WiFi.h>#include <PubSubClient.h>#include <ArduinoJson.h>
// ── Configuración WiFi ─────────────────────────────────────────────────────const char* WIFI_SSID = "TU_NOMBRE_DE_RED";const char* WIFI_PASSWORD = "TU_PASSWORD_WIFI";
// ── Configuración MQTT ─────────────────────────────────────────────────────const char* MQTT_SERVER = "192.168.1.100"; // ← IP de tu PC con Mosquittoconst int MQTT_PORT = 1883;const char* MQTT_CLIENT = "esp32-sensor-01";const char* MQTT_TOPIC = "sensores/temperatura";
// ── Intervalo de publicación ───────────────────────────────────────────────const unsigned long PUBLISH_INTERVAL = 5000; // 5 segundos
WiFiClient espClient;PubSubClient mqtt(espClient);unsigned long lastPublish = 0;
// ──────────────────────────────────────────────────────────────────────────void conectarWiFi() { Serial.print("Conectando a WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println(); Serial.print("WiFi conectado — IP: "); Serial.println(WiFi.localIP());}
// ──────────────────────────────────────────────────────────────────────────void conectarMQTT() { while (!mqtt.connected()) { Serial.print("Conectando a MQTT...");
if (mqtt.connect(MQTT_CLIENT)) { Serial.println(" conectado!"); } else { Serial.print(" error rc="); Serial.print(mqtt.state()); Serial.println(" — reintentando en 5s"); delay(5000); } }}
// ──────────────────────────────────────────────────────────────────────────void setup() { Serial.begin(115200); conectarWiFi(); mqtt.setServer(MQTT_SERVER, MQTT_PORT);}
// ──────────────────────────────────────────────────────────────────────────void loop() { // Mantener conexión MQTT activa if (!mqtt.connected()) conectarMQTT(); mqtt.loop();
// Publicar según el intervalo definido unsigned long ahora = millis(); if (ahora - lastPublish >= PUBLISH_INTERVAL) { lastPublish = ahora;
// Simular lectura de sensor (20.0 – 34.9 °C) float temperatura = 20.0 + (random(0, 150) / 10.0);
// Construir payload JSON JsonDocument doc; doc["valor"] = temperatura; doc["unidad"] = "C"; doc["sensor"] = MQTT_CLIENT; doc["uptime_s"] = millis() / 1000;
char payload[128]; serializeJson(doc, payload);
// Publicar mqtt.publish(MQTT_TOPIC, payload);
Serial.print("Publicado en "); Serial.print(MQTT_TOPIC); Serial.print(" → "); Serial.println(payload); }}Personalizar antes de subir
Sección titulada «Personalizar antes de subir»Edita estas cuatro líneas según tu entorno:
const char* WIFI_SSID = "TU_NOMBRE_DE_RED"; // nombre de tu WiFiconst char* WIFI_PASSWORD = "TU_PASSWORD_WIFI"; // contraseña de tu WiFiconst char* MQTT_SERVER = "192.168.1.100"; // IP de tu PCconst char* MQTT_CLIENT = "esp32-sensor-01"; // nombre único del dispositivoPaso 4: Verificar en el Monitor Serie
Sección titulada «Paso 4: Verificar en el Monitor Serie»Sube el sketch y abre el Monitor Serie a 115200 baud. Deberías ver:
Conectando a WiFi......WiFi conectado — IP: 192.168.1.105Conectando a MQTT... conectado!Publicado en sensores/temperatura → {"valor":23.4,"unidad":"C","sensor":"esp32-sensor-01","uptime_s":5}Publicado en sensores/temperatura → {"valor":28.1,"unidad":"C","sensor":"esp32-sensor-01","uptime_s":10}Paso 5: Verificar que Mosquitto recibe los mensajes
Sección titulada «Paso 5: Verificar que Mosquitto recibe los mensajes»En tu PC, abre una terminal y suscríbete al topic:
docker exec -it mosquitto mosquitto_sub -h localhost -t "sensores/#" -vDeberías ver los mensajes del ESP32 llegar cada 5 segundos:
sensores/temperatura {"valor":23.4,"unidad":"C","sensor":"esp32-sensor-01","uptime_s":5}sensores/temperatura {"valor":28.1,"unidad":"C","sensor":"esp32-sensor-01","uptime_s":10}Paso 6: Recibir los datos en Node-RED
Sección titulada «Paso 6: Recibir los datos en Node-RED»En el editor de Node-RED (http://localhost:1880):
- Arrastra un nodo
mqtt inal canvas - Configura el servidor: host
mosquitto, puerto1883 - Topic:
sensores/temperatura - Output:
a parsed JSON object - Conecta un nodo
json(por si el payload llega como string) - Conecta un nodo
ui-gauge:- Value:
msg.payload.valor - Label:
Temperatura - Units:
°C - Range: 0 a 50
- Value:
- Conecta un nodo
ui-chart(línea de tiempo) - Haz clic en Deploy
Abre el dashboard en http://localhost:1880/dashboard — verás los datos del ESP32 en tiempo real.
Paso 7: Sketch con sensor DHT22 (temperatura y humedad real)
Sección titulada «Paso 7: Sketch con sensor DHT22 (temperatura y humedad real)»Una vez que el pipeline funciona con datos simulados, conecta un sensor DHT22 para enviar mediciones reales.
Conexión del DHT22 al ESP32
Sección titulada «Conexión del DHT22 al ESP32»DHT22 ESP32────── ──────VCC ──→ 3.3V (pin 3V3)DATA ──→ GPIO4 (cualquier pin digital)GND ──→ GND
Nota: coloca una resistencia de 10kΩ entre VCC y DATA (pull-up)Instalar la librería DHT
Sección titulada «Instalar la librería DHT»En el gestor de librerías busca DHT sensor library e instala DHT sensor library by Adafruit. También instala Adafruit Unified Sensor cuando te lo pida.
Sketch completo con DHT22
Sección titulada «Sketch completo con DHT22»#include <WiFi.h>#include <PubSubClient.h>#include <ArduinoJson.h>#include <DHT.h>
// ── Configuración WiFi ─────────────────────────────────────────────────────const char* WIFI_SSID = "TU_NOMBRE_DE_RED";const char* WIFI_PASSWORD = "TU_PASSWORD_WIFI";
// ── Configuración MQTT ─────────────────────────────────────────────────────const char* MQTT_SERVER = "192.168.1.100";const int MQTT_PORT = 1883;const char* MQTT_CLIENT = "esp32-dht22-01";
// Topics separados para temperatura y humedadconst char* TOPIC_TEMP = "sensores/temperatura";const char* TOPIC_HUM = "sensores/humedad";
// ── Configuración del sensor ───────────────────────────────────────────────#define DHT_PIN 4 // GPIO donde está conectado DATA del DHT22#define DHT_TYPE DHT22 // Cambiar a DHT11 si usas ese sensor
DHT dht(DHT_PIN, DHT_TYPE);
const unsigned long PUBLISH_INTERVAL = 10000; // 10 segundos
WiFiClient espClient;PubSubClient mqtt(espClient);unsigned long lastPublish = 0;
// ──────────────────────────────────────────────────────────────────────────void conectarWiFi() { Serial.print("Conectando a WiFi"); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); Serial.print("WiFi conectado — IP: "); Serial.println(WiFi.localIP());}
void conectarMQTT() { while (!mqtt.connected()) { Serial.print("Conectando a MQTT..."); if (mqtt.connect(MQTT_CLIENT)) { Serial.println(" conectado!"); } else { Serial.print(" error rc="); Serial.print(mqtt.state()); Serial.println(" — reintentando en 5s"); delay(5000); } }}
// ──────────────────────────────────────────────────────────────────────────void setup() { Serial.begin(115200); dht.begin(); conectarWiFi(); mqtt.setServer(MQTT_SERVER, MQTT_PORT);}
// ──────────────────────────────────────────────────────────────────────────void publicar(const char* topic, const char* campo, float valor) { JsonDocument doc; doc[campo] = round(valor * 10) / 10.0; // 1 decimal doc["sensor"] = MQTT_CLIENT; doc["uptime_s"] = millis() / 1000;
char payload[128]; serializeJson(doc, payload); mqtt.publish(topic, payload);
Serial.print(topic); Serial.print(" → "); Serial.println(payload);}
void loop() { if (!mqtt.connected()) conectarMQTT(); mqtt.loop();
unsigned long ahora = millis(); if (ahora - lastPublish >= PUBLISH_INTERVAL) { lastPublish = ahora;
float temperatura = dht.readTemperature(); float humedad = dht.readHumidity();
// Verificar que la lectura sea válida if (isnan(temperatura) || isnan(humedad)) { Serial.println("Error leyendo el DHT22 — verifica la conexión"); return; }
publicar(TOPIC_TEMP, "valor", temperatura); publicar(TOPIC_HUM, "valor", humedad); }}Referencia rápida: códigos de error de PubSubClient
Sección titulada «Referencia rápida: códigos de error de PubSubClient»Si mqtt.state() devuelve un número negativo, consulta esta tabla:
| Código | Constante | Significado |
|---|---|---|
-4 | MQTT_CONNECTION_TIMEOUT | No hubo respuesta del broker |
-3 | MQTT_CONNECTION_LOST | Se perdió la conexión de red |
-2 | MQTT_CONNECT_FAILED | No se pudo establecer conexión TCP |
-1 | MQTT_DISCONNECTED | Cliente desconectado |
0 | MQTT_CONNECTED | ✅ Conectado |
1 | MQTT_CONNECT_BAD_PROTOCOL | Versión de protocolo no soportada |
2 | MQTT_CONNECT_BAD_CLIENT_ID | ID de cliente rechazado |
5 | MQTT_CONNECT_UNAUTHORIZED | Usuario/contraseña incorrectos |
Los más comunes en problemas de red son -4 (IP incorrecta o Mosquitto no está corriendo) y -2 (ESP32 no alcanza el servidor — verifica que estén en la misma red WiFi).
Múltiples ESP32 en la misma red
Sección titulada «Múltiples ESP32 en la misma red»Si tienes más de un ESP32 publicando datos, asegúrate de que cada uno tenga un Client ID único:
// Dispositivo 1const char* MQTT_CLIENT = "esp32-salon-01";const char* MQTT_TOPIC = "sensores/salon/temperatura";
// Dispositivo 2const char* MQTT_CLIENT = "esp32-cocina-01";const char* MQTT_TOPIC = "sensores/cocina/temperatura";En Node-RED, suscríbete al wildcard sensores/# para recibir de todos los dispositivos en un solo nodo mqtt in, y usa un nodo switch para enrutar por topic o por el campo sensor del JSON.