Este proyecto muestra cómo usar el protocolo de comunicación MQTT con el ESP32 para publicar mensajes y suscribirse a temas (topics). Como ejemplo, publicaremos lecturas del sensor BME280 en un dashboard de Node-RED y controlaremos una salida del ESP32. El ESP32 se programará usando Arduino IDE.
Resumen del proyecto
En este ejemplo, hay una aplicación Node-RED que controla salidas del ESP32 y recibe lecturas de sensores desde el ESP32 usando el protocolo de comunicación MQTT. La aplicación Node-RED se ejecuta en una Raspberry Pi.
Usaremos el broker Mosquitto instalado en la misma Raspberry Pi. El broker es responsable de recibir todos los mensajes, filtrarlos, decidir quién está interesado en ellos y publicarlos a todos los clientes suscritos.
El flujo de comunicación es el siguiente:
La aplicación Node-RED publica mensajes (“on” o “off”) en el topic esp32/output. El ESP32 está suscrito a ese topic, así que recibe el mensaje con “on” o “off” para encender o apagar el LED. El ESP32 publica la temperatura en el topic esp32/temperature y la humedad en el topic esp32/humidity. La aplicación Node-RED está suscrita a esos topics, así que recibe las lecturas de temperatura y humedad que se pueden mostrar en un gráfico o en un indicador.
Nota: también existe un tutorial similar sobre cómo usar el ESP8266 y Node-RED con MQTT.
Requisitos previos
Deberías estar familiarizado con la Raspberry Pi. Deberías tener el sistema operativo Raspbian instalado en tu Raspberry Pi. Necesitas Node-RED instalado en tu Pi y Node-RED Dashboard. También deberías entender qué es MQTT y cómo funciona.
Componentes necesarios
Para construir el circuito necesitas: una Raspberry Pi, una placa ESP32 DOIT DEVKIT V1, un módulo sensor BME280, un LED de 5 mm, una resistencia de 220 Ω, una protoboard y cables jumper.
Introducción al módulo sensor BME280
El módulo sensor BME280 lee temperatura, humedad y presión. Como la presión cambia con la altitud, también puedes estimar la altitud. Sin embargo, en este tutorial solo leeremos temperatura y humedad.
El sensor puede comunicarse usando protocolos SPI o I2C (hay módulos de este sensor que solo se comunican por I2C y vienen con cuatro pines).
Para usar el protocolo de comunicación SPI, se usan los siguientes pines: SCK (pin de reloj SPI), SDO (MISO), SDI (MOSI) y CS (Chip Select).
Para usar el protocolo de comunicación I2C, el sensor usa los siguientes pines: SCK (pin SCL) y SDI (pin SDA).
Esquema de conexión
Vamos a usar comunicación I2C con el módulo sensor BME280. Para ello, conecta el sensor a los pines SDA y SCL del ESP32. También controlaremos una salida del ESP32, un LED conectado al GPIO 4.
Conexiones del BME280 al ESP32: VCC del sensor a 3,3 V, GND del sensor a GND, SCL del sensor a GPIO 22 y SDA del sensor a GPIO 21. El LED se conecta al GPIO 4 con su resistencia de 220 Ω en serie hacia GND.
Preparar Arduino IDE
Existe un complemento para Arduino IDE que te permite programar el ESP32. Sigue el tutorial de instalación correspondiente a tu sistema operativo antes de continuar. Una vez asegurado de tener el complemento ESP32 instalado, puedes continuar con este tutorial.
Instalar la librería PubSubClient
La librería PubSubClient proporciona un cliente para hacer mensajería publish/subscribe simple con un servidor que soporta MQTT (básicamente permite que tu ESP32 hable con Node-RED).
Puedes instalarla desde el Gestor de Librerías de Arduino. Ve a Programa > Incluir Librería > Gestionar Librerías y busca “PubSubClient”. Selecciona la librería de Nick O’Leary e instálala. La librería viene con varios sketches de ejemplo. Puedes verlos en Archivo > Ejemplos > PubSubClient dentro del software Arduino IDE.
Importante: PubSubClient no es completamente compatible con el ESP32, pero el ejemplo proporcionado en este tutorial funciona de forma muy fiable durante nuestras pruebas.
Instalar la librería del BME280
Para tomar lecturas del módulo sensor BME280 usaremos la librería Adafruit_BME280. Puedes instalarla desde el Gestor de Librerías buscando “adafruit bme280” e instalándola.
Instalar la librería Adafruit_Sensor
Para usar la librería del BME280, también necesitas instalar la librería Adafruit_Sensor. Búscala en el Gestor de Librerías como “Adafruit Unified Sensor” e instálala.
Subir el código
Ahora puedes subir el siguiente código a tu ESP32. El código está comentado donde necesitas hacer cambios. Necesitas editar el código con tu propio SSID, contraseña y dirección IP de la Raspberry Pi.
/*
Rui Santos
Detalles completos del proyecto en https://randomnerdtutorials.com
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
// Reemplaza las siguientes variables con tu combinación SSID/Contraseña
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Añade la dirección IP de tu broker MQTT, ejemplo:
//const char* mqtt_server = "192.168.1.144";
const char* mqtt_server = "YOUR_MQTT_BROKER_IP_ADDRESS";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
Adafruit_BME280 bme; // I2C
float temperature = 0;
float humidity = 0;
// Pin del LED
const int ledPin = 4;
void setup() {
Serial.begin(115200);
// configuración por defecto
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(ledPin, OUTPUT);
}
void setup_wifi() {
delay(10);
// Empezamos conectando a una red WiFi
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Si se recibe un mensaje en el topic esp32/output, comprueba si el mensaje es "on" o "off".
// Cambia el estado de la salida según el mensaje
if (String(topic) == "esp32/output") {
Serial.print("Changing output to ");
if(messageTemp == "on"){
Serial.println("on");
digitalWrite(ledPin, HIGH);
}
else if(messageTemp == "off"){
Serial.println("off");
digitalWrite(ledPin, LOW);
}
}
}
void reconnect() {
// Bucle hasta que estemos reconectados
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Intenta conectar
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Suscríbete
client.subscribe("esp32/output");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Espera 5 segundos antes de reintentar
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > 5000) {
lastMsg = now;
// Temperatura en Celsius
temperature = bme.readTemperature();
// Descomenta la siguiente línea para establecer la temperatura en Fahrenheit
// (y comenta la línea anterior de temperatura)
//temperature = 1.8 * bme.readTemperature() + 32; // Temperatura en Fahrenheit
// Convierte el valor a un array de char
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
client.publish("esp32/temperature", tempString);
humidity = bme.readHumidity();
// Convierte el valor a un array de char
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
client.publish("esp32/humidity", humString);
}
}
Este código publica lecturas de temperatura y humedad en los topics esp32/temperature y esp32/humidity a través del protocolo MQTT. El ESP32 está suscrito al topic esp32/output para recibir los mensajes publicados en ese topic por la aplicación Node-RED. Después, según el mensaje recibido, enciende o apaga el LED.
Suscribirse a topics MQTT
En la función reconnect(), puedes suscribirte a topics MQTT. En este caso, el ESP32 solo está suscrito al topic esp32/output:
client.subscribe("esp32/output");
En la función callback(), el ESP32 recibe los mensajes MQTT de los topics suscritos. Según el topic y el mensaje MQTT, enciende o apaga el LED:
if (String(topic) == "esp32/output") {
Serial.print("Changing output to ");
if (messageTemp == "on") {
Serial.println("on");
digitalWrite(ledPin, HIGH);
}
else if (messageTemp == "off") {
Serial.println("off");
digitalWrite(ledPin, LOW);
}
}
Publicar mensajes MQTT
En el loop(), se publican nuevas lecturas cada 5 segundos. Por defecto, el ESP32 envía la temperatura en Celsius, pero puedes descomentar la última línea para enviar la temperatura en Fahrenheit.
Necesitas convertir la variable float de temperatura a un array de char para poder publicar la lectura de temperatura en el topic esp32/temperature:
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
client.publish("esp32/temperature", tempString);
El mismo proceso se repite para publicar la lectura de humedad en el topic esp32/humidity:
humidity = bme.readHumidity();
char humString[8];
dtostrf(humidity, 1, 2, humString);
client.publish("esp32/humidity", humString);
Crear el flujo de Node-RED
Antes de crear el flujo, necesitas tener instalado en tu Raspberry Pi: Node-RED, Node-RED Dashboard y Mosquitto Broker.
Después, importa el flujo de Node-RED proporcionado. En la ventana de Node-RED, en la esquina superior derecha, selecciona el menú y ve a Import > Clipboard. Después, pega el código proporcionado y pulsa Import. Deberían cargarse los siguientes nodos. Después de hacer cualquier cambio, pulsa el botón Deploy para guardar todos los cambios.
Interfaz de usuario de Node-RED
Ahora tu aplicación Node-RED está lista. Para acceder a la interfaz de usuario de Node-RED y ver cómo queda tu aplicación, accede a cualquier navegador en tu red local y escribe:
http://Tu_Direccion_IP_De_La_RPi:1880/ui
Tu aplicación debería verse de la siguiente forma: puedes controlar el LED encendido y apagado con el interruptor, o puedes ver las lecturas de temperatura en un gráfico y los valores de humedad en un indicador.
Demostración
Abre el Monitor Serie de Arduino IDE para echar un vistazo a los mensajes MQTT que se reciben y publican. Verás cómo cada 5 segundos el ESP32 publica las lecturas de temperatura y humedad, y cómo cuando cambias el interruptor en Node-RED, el ESP32 recibe el mensaje “on” o “off” y enciende o apaga el LED.
Conclusión
En resumen, te hemos mostrado los conceptos básicos que te permiten encender luces y monitorizar sensores con tu ESP32 usando Node-RED y el protocolo de comunicación MQTT. Puedes usar este ejemplo para integrarlo en tu propio sistema de domótica, controlar más salidas o monitorizar otros sensores.
MQTT es el protocolo estándar de facto para IoT, y combinarlo con Node-RED te da un sistema completo de control y monitorización sin necesidad de escribir una aplicación móvil o web desde cero. Con esta base, puedes construir sistemas de domótica profesionales que integren múltiples dispositivos ESP32, sensores de todo tipo y paneles de control personalizados.
Descubre más desde CIBERED
Suscríbete y recibe las últimas entradas en tu correo electrónico.
