Ir al contenido

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.

[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 real

  1. En Arduino IDE: Sketch → Incluir Librería → Gestionar Librerías (o Ctrl + Shift + I)
  2. Busca PubSubClient
  3. Instala PubSubClient by Nick O’Leary (la más popular, más de 10 millones de descargas)
  1. En el mismo gestor, busca ArduinoJson
  2. 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:

Ventana de terminal
ipconfig

Busca 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 necesitas

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 Mosquitto
const 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);
}
}

Edita estas cuatro líneas según tu entorno:

const char* WIFI_SSID = "TU_NOMBRE_DE_RED"; // nombre de tu WiFi
const char* WIFI_PASSWORD = "TU_PASSWORD_WIFI"; // contraseña de tu WiFi
const char* MQTT_SERVER = "192.168.1.100"; // IP de tu PC
const char* MQTT_CLIENT = "esp32-sensor-01"; // nombre único del dispositivo

Sube el sketch y abre el Monitor Serie a 115200 baud. Deberías ver:

Conectando a WiFi......
WiFi conectado — IP: 192.168.1.105
Conectando 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:

Ventana de terminal
docker exec -it mosquitto mosquitto_sub -h localhost -t "sensores/#" -v

Deberí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}

En el editor de Node-RED (http://localhost:1880):

  1. Arrastra un nodo mqtt in al canvas
  2. Configura el servidor: host mosquitto, puerto 1883
  3. Topic: sensores/temperatura
  4. Output: a parsed JSON object
  5. Conecta un nodo json (por si el payload llega como string)
  6. Conecta un nodo ui-gauge:
    • Value: msg.payload.valor
    • Label: Temperatura
    • Units: °C
    • Range: 0 a 50
  7. Conecta un nodo ui-chart (línea de tiempo)
  8. 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.

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)

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.

#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 humedad
const 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ódigoConstanteSignificado
-4MQTT_CONNECTION_TIMEOUTNo hubo respuesta del broker
-3MQTT_CONNECTION_LOSTSe perdió la conexión de red
-2MQTT_CONNECT_FAILEDNo se pudo establecer conexión TCP
-1MQTT_DISCONNECTEDCliente desconectado
0MQTT_CONNECTED✅ Conectado
1MQTT_CONNECT_BAD_PROTOCOLVersión de protocolo no soportada
2MQTT_CONNECT_BAD_CLIENT_IDID de cliente rechazado
5MQTT_CONNECT_UNAUTHORIZEDUsuario/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).


Si tienes más de un ESP32 publicando datos, asegúrate de que cada uno tenga un Client ID único:

// Dispositivo 1
const char* MQTT_CLIENT = "esp32-salon-01";
const char* MQTT_TOPIC = "sensores/salon/temperatura";
// Dispositivo 2
const 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.