Aprendiendo MQTT 3: El suscriptor, ESP32 con sensor de temperatura y humedad ambiental.

Montaje ESP32 suscriptor MQTT con temperatura y humedad

Continuamos con la segunda entrega de nuestro montaje, en el que estamos aprendiendo a usar el protocolo de comunicaciones MQTT. Nos centraremos ahora en el suscriptor, que será el elemento encargado de recibir los mensajes de telemetría. Este suscriptor puede ser una pantalla que muestre datos (como en este montaje) o, también, un dispositivo que actúe de una manera u otra según los datos recibidos. Un ejemplo podría ser una electroválvula para riego que se abre o cierra cuando una sonda detecta un cierto nivel de humedad en el terreno.

¡Os animo a que os pongáis manos a la obra y hagáis el montaje es muy gratificante y os dejo todo lo necesario para hacerlo!

El suscriptor MQTT, desde el punto de vista de la programación, es de naturaleza asíncrona. ¿Qué quiero decir con esto? Pues que podrá realizar acciones como cambiar el texto del display, accionar un relé o guardar valores en una base de datos cuando reciba un mensaje, y esto podría ocurrir en cualquier momento. La forma más común y elegante de hacer esto es mediante una función de ‘callback’. Dependiendo del lenguaje de programación con el que estemos trabajando, a esta función también se le podría llamar ‘evento’, ‘acción’, entre otros términos, pero en esencia es un parámetro, propiedad o variable que aloja un método que se invoca cuando sucede algo específico, desencadenando así la ejecución de un bloque de código.

El montaje del display de Temperatura y Humedad.

Para este montaje usaremos un ESP32 que lo vamos a programar con ayuda de platformio en c++ con las librerías:

  • WiFi.h: para la conexión WiFi.
  • PubSubClient.h: para la conexión y operaciones MQTT.
  • Wire.h: para comunicación I2C.
  • LiquidCrystal_I2C.h: para manejar un LCD que utiliza I2C.

El montaje, a nivel de esquema eléctrico, consta de un display LCD de dos líneas y 16 caracteres cada una (16×2). Este se puede conectar de dos maneras: la primera, enviando datos de forma paralela, y la segunda, utilizando un adaptador I2C de serie a paralelo. Con el adaptador I2C, solo necesitamos dos cables para la comunicación con el ESP32, además de otros dos cables para la alimentación eléctrica, uno positivo y otro negativo.

Montaje ESP32 suscriptor MQTT con temperatura y humedad
Montaje ESP32 suscriptor MQTT con temperatura y humedad

Para el ESP32 con el que estoy trabajado tiene la señal i2c de reloj en el pin GPIO 22 y la señal de datos en el pin GPIO 21 (aunque en realidad no están funcionando aquí como GPIO que es una salida de propósito general sino como puerto I2C). Por otro lado el pin morado es está conectado a 3V3 (3,3 Voltios) positivo y el blanco a GND o negativo.

ESP32 Pinout
ESP32 descripción de los pines

El código con el framework de arduino:

Ahora pasamos a describir el código fuente que lo podéis encontrar en https://github.com/elrincondeada/mqttdemo/blob/master/LCDMqttClient/src/main.cpp

Lo primero que hacemos es importar las bibliotecas:

#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

Aquí se importan las bibliotecas necesarias para la conexión WiFi, el protocolo MQTT, la comunicación I2C y el manejo del LCD.

Definición de constantes y variables globales

#define TOPIC_TEMPERATURA "esp32/temperatura"
#define TOPIC_HUMEDAD "esp32/humedad"

Esto se hace para evitar errores al escribir un elemento de código que es constante y se va a usar varias veces. Es este caso el tópico así sabemos que siempre lo vamos a escribir igual y evitamos errores.

// Información de WiFi y MQTT
const char* ssid = "XXXXXXXXXXXXXXXXXXX";
const char* password = "XXXXXXXXXXXXXXX";
const char* mqttServer = "XXXXXXXXXXXXX";
const int mqttPort = 1883;

//Protipado de funciones
void callback(char*, byte*, unsigned int);

// Inicializa el cliente WiFi y MQTT
WiFiClient espClient;
PubSubClient client(espClient);

// Inicializa la LCD con dirección I2C, columnas y filas
LiquidCrystal_I2C lcd(0x27, 16, 2);

Empezamos con la declaración de variables globales, donde encontrarás ‘char*’. No es un simple arreglo de caracteres, es un puntero en C. Si te interesa profundizar en los fundamentos de C y qué es un puntero, te recomiendo este vídeo https://youtu.be/AUAX9xNenuo

Luego tenemos algo llamado ‘prototipado de función’. Se trata simplemente de un adelanto de la función que jugará un rol principal en este código, la función ‘callback’.

Finalmente, instanciamos el cliente WiFi para establecer la conexión con el exterior, el cliente MQTT para la comunicación de mensajes y el controlador del display LCD 16×2, todo ello gestionado mediante el protocolo I2C.

la función setup()

void setup() {
  // Inicializa el LCD
  lcd.init();
  lcd.backlight();
  
  // Conexión WiFi
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  // Conexión WiFi
   while (true) { // Bucle infinito
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("Conectado a WiFi!");
      break; // Sale del bucle cuando se conecta
    }
    Serial.print(".");
    delay(200);
   }

  
  // Conexión MQTT
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);

  while (!client.connected()) {
    Serial.println("Conectando a MQTT...");

    if (client.connect("ESP32")) {
      Serial.println("Conectado");
    } else {
      Serial.print("Error de conexión: ");
      Serial.print(client.state());
      delay(2000);
    }
  }

  Serial.println("Suscripción a tópicos");
  // Se suscribe al tópico
  client.subscribe(TOPIC_TEMPERATURA);
  client.subscribe(TOPIC_HUMEDAD);
}

«La función void setup() es donde toda la magia inicial tiene lugar. Esta función se ejecuta una sola vez al inicio y configura todo lo necesario para que nuestro código funcione de manera óptima.

  1. Inicialización del LCD: Con las instrucciones lcd.init() y lcd.backlight(), inicializamos el display LCD y encendemos su retroiluminación para hacerlo visible.
  2. Conexión WiFi: Primero, iniciamos la comunicación serie con Serial.begin(115200). Luego, la instrucción WiFi.begin(ssid, password) intenta conectar el ESP32 a la red WiFi utilizando las credenciales almacenadas en las variables ssid y password.
  3. Verificación de Conexión WiFi: Aquí entra en juego un bucle infinito (while(true)) que comprueba constantemente si se ha establecido la conexión WiFi. Si la conexión es exitosa (WiFi.status() == WL_CONNECTED), se imprime un mensaje y se rompe el bucle con break.
  4. Conexión MQTT: Las instrucciones client.setServer(mqttServer, mqttPort) y client.setCallback(callback) configuran el servidor MQTT y la función de callback que se llamará cuando lleguen mensajes al tópico suscrito. Es el corazón de este desarrollo.
  5. Verificación de Conexión MQTT: Similar al WiFi, hay un bucle while que intenta conectar con el servidor MQTT hasta que lo logra. Si hay un error, imprime el estado del intento fallido.
  6. Suscripción a Tópicos: Finalmente, client.subscribe(TOPIC_TEMPERATURA) y client.subscribe(TOPIC_HUMEDAD) suscriben el cliente MQTT a los tópicos de temperatura y humedad, respectivamente.»

La función de callback:

void callback(char* topic, byte* payload, unsigned int length) {
  String payloadStr = "";

  Serial.println("mensaje recibido");

  // Convierte los bytes del payload a String
  for (int i = 0; i < length; i++) {
    payloadStr += (char)payload[i];
  }

  Serial.println(payloadStr);

  // Actualiza el LCD con el mensaje recibido
  if(strstr(topic,TOPIC_TEMPERATURA))
  {
    lcd.setCursor(0, 0);
    lcd.print("Temp. ");
  }

  if(strstr(topic,TOPIC_HUMEDAD)) 
  {
    lcd.setCursor(0, 1);
    lcd.print("Humd. ");
  }

  lcd.print(payloadStr);
}

La función callback es el núcleo de cualquier suscriptor MQTT, y aquí es donde reside toda la lógica que determina qué hacer cuando llega un mensaje a los tópicos a los que se ha suscrito el cliente. Vamos a desglosarla:

  1. Parámetros: La función acepta tres parámetros: char* topic, byte* payload, y unsigned int length. El topic indica el tópico al cual pertenece el mensaje recibido, payload es el cuerpo del mensaje en forma de bytes y length es la longitud del payload.
  2. Inicialización: String payloadStr = ""; inicializa una cadena de texto vacía donde almacenaremos el payload convertido.
  3. Mensaje Recibido: Serial.println("mensaje recibido"); es una forma de debugging que nos indica que ha llegado un nuevo mensaje.
  4. Conversión de Bytes a String: El bucle for toma cada byte del payload y lo convierte a su representación de carácter, acumulando todo en payloadStr.
  5. Impresión del Payload: Serial.println(payloadStr); imprime el payload recibido para verificación.
  6. Actualización de la LCD: Aquí es donde el programa se pone interesante. Si el tópico corresponde a la temperatura (strstr(topic, TOPIC_TEMPERATURA)), el cursor de la LCD se posiciona en la primera fila y escribe «Temp.». De forma similar, si el tópico es de humedad, escribe «Humd.» en la segunda fila.
  7. Imprimir Valor: Finalmente, lcd.print(payloadStr); imprime el valor del payload en la LCD, justo después de «Temp.» o «Humd.», dependiendo del tópico al que pertenece el mensaje.

función loop

void loop() {
  client.loop();
}

Esta línea se encarga de mantener el cliente MQTT en funcionamiento y es crucial para el correcto funcionamiento de todo el programa. ¿Por qué? Porque client.loop() se encarga de procesar cualquier mensaje entrante y saliente, y de mantener la conexión con el servidor MQTT viva. Si no se ejecutara esta función de forma continua en el bucle principal, no se recibirían ni procesarían mensajes MQTT, y el cliente podría incluso desconectarse del servidor.

Por lo tanto, aunque pueda parecer una parte trivial del código, no subestimes su importancia. Actúa como el corazón palpitante de tu cliente MQTT, asegurándose de que todo funcione como un reloj.

Conclusión:

Y ahí lo tienes, la segunda entrega de nuestra serie sobre MQTT, donde nos hemos centrado en el rol del suscriptor. No es magia, es tecnología bien aplicada. Hemos desentrañado el código que corre en un ESP32 y que le permite actuar como un suscriptor MQTT. Desde establecer una conexión Wi-Fi hasta interpretar los mensajes MQTT que le llegan, este pequeño dispositivo hace de todo.

Nuestra función callback es el cerebro del operativo: espera en silencio hasta que llega un mensaje relevante y luego se pone en acción para mostrarlo en nuestro LCD. Y no olvidemos nuestro persistente void loop(), el pulso del programa que asegura que el cliente MQTT está siempre listo para actuar.

Si te ha picado el gusanillo de la programación y quieres ir más allá, hay un mundo de posibilidades que puedes explorar. ¿Qué tal integrar una base de datos para guardar los datos recibidos? ¿O quizás quieras controlar otros dispositivos en función de los mensajes recibidos?

Espero que este tutorial te haya proporcionado una buena base para entender cómo funciona un suscriptor MQTT y cómo puedes empezar a jugar con estas tecnologías. Estamos en una era donde los objetos cotidianos se están volviendo cada vez más inteligentes y conectados, y entender estos conceptos básicos te coloca un paso adelante en este emocionante mundo del Internet de las Cosas.

Te animo a que realices tu mismo el montaje. Puedes cambiar el sensor, el display, conectarlo a un asistente domótico, a alexa… Seguiremos experimentando.

¡Hasta la próxima entrega!

Referencias:

Aprendiendo MQTT 2: El publicador, ESP32 con sensor de temperatura y humedad ambiental.

Recepción de mensajes MQTT mostrados en un display LCD con ESP32

En la entrega siguiente de nuestro tutorial sobre MQTT, el enfoque estará puesto en el elemento del publicador. Este se ha implementado a través de una placa ESP32 S3, aunque es importante señalar que cualquier placa compatible con el framework de Arduino serviría para este propósito. En el esquema del protocolo MQTT, el rol del publicador es de carácter síncrono; es decir, publica datos tan pronto como estos se encuentran disponibles.

Componentes importantes:

  • WiFiClient espClient: Es el cliente que gestionará la conexión WiFi.
  • PubSubClient client(espClient): Se encargará de las operaciones MQTT. Utiliza espClient para manejar la parte de red.

El framework de arduino consiste en dos funciones. una función setup que se ejecuta una sola vez y otra función loop que se repite en bucle.

Función setup()

La función setup() es la primera que se ejecuta cuando arranca el programa. Se ejecuta una sola vez y aquí es donde se realizan las configuraciones iniciales.

Usaremos la comunicación serial para usarla como «consola»

Serial.begin(9600);
Serial.println("Demo mqtt con AHT20");

Configuración del Sensor AHT20

if (!aht.begin())
{
  Serial.println("No encontró el sensor AHT?");
  while (1)
    delay(10);
}
Serial.println("AHT20 encontrado!");

Estas líneas intentan inicializar el sensor AHT20. Si no se encuentra el sensor, el programa se detiene indefinidamente (while (1) delay(10);). Si se encuentra, imprime un mensaje de confirmación. «AHT20 encontrado»

Conexión WiFi

WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
  delay(500);
  Serial.print(".");
}
Serial.println("WiFi conectado");
Serial.println("Dirección IP: ");
Serial.println(WiFi.localIP());

Estas líneas intentan conectarse a la red WiFi especificada por las variables ssid y password. Una vez que se establece la conexión, se imprime la dirección IP local asignada al ESP.

Configuración de Cliente MQTT

client.setServer(mqtt_server, mqtt_port);

Esta línea configura la dirección IP y el puerto del servidor MQTT al que se va a conectar. Esto no inicia la conexión, sólo la prepara.

Función loop()

La función loop() es el corazón del programa y se ejecuta indefinidamente una vez que ha terminado setup().

Lectura del Sensor AHT20

sensors_event_t e_humedad, e_temp;
aht.getEvent(&e_humedad, &e_temp);

Aquí estás utilizando la biblioteca Adafruit para leer los valores del sensor AHT20. Los datos se almacenan en las variables e_humedad y e_temp. ¿Sabéis porque llevan los operadores & las variables e_humedad y &e_temp?

Verificación de Conexión MQTT

if (!client.connected())
{
  reconnect();
}
client.loop();

Estas líneas verifican si el cliente MQTT está conectado. Si no es así, se invoca la función reconnect() para intentar establecer la conexión nuevamente. La función client.loop() se encarga de mantener la conexión activa y gestionar las llegadas de mensajes.

Publicación de Datos

if (now - lastMsg > 10000)
{
  ...
  client.publish("esp32/temperatura", msgt);
  client.publish("esp32/humedad", msgh);
}

Este bloque se ejecuta cada 10 segundos (10,000 milisegundos). Aquí, los datos de temperatura y humedad se formatean como cadenas de texto y luego se publican en los temas «esp32/temperatura» y «esp32/humedad» del servidor MQTT.

Función reconnect()

La función reconnect() intenta reconectar al cliente MQTT en caso de que la conexión se pierda. Utiliza una estructura de bucle para seguir intentando hasta que se restablece la conexión.

void reconnect()
{
  // Loop hasta que estemos reconectados
  while (!client.connected())
  {
    Serial.print("Intentando conexión MQTT...");
    // Intentar conectar
    if (client.connect("ESP32Client"))
    {
      Serial.println("conectado");
    }
    else
    {
      Serial.print("falló, rc=");
      Serial.print(client.state());
      Serial.println(" intentar de nuevo en 5 segundos");
      // Esperar 5 segundos antes de volver a intentar
      delay(5000);
    }
  }

Estas líneas intentan conectar el cliente MQTT con el ID de cliente «ESP32Client». Si la conexión es exitosa, imprime «conectado».

Equema eléctrico.

El ESP32 S3 tiene los pines de I2C configurados con pin número 9 SCL y pin número 8 SDA por defecto. El cable amarillo lleva los datos de reloj SCL y el naranja los datos SDA (tengo esa costumbre para el protocolo I2C) los otros dos cables son la alimentación a 3.3V del sensor.

Conclusión:

En este post, hemos explorado un caso práctico de cómo construir un publicador MQTT utilizando una placa ESP32 S3 y un sensor AHT20 para medir temperatura y humedad. A través de esta implementación, hemos logrado comprender no solo cómo extraer datos del sensor, sino también cómo administrar de forma efectiva las conexiones WiFi y MQTT. Este proyecto sirve como un excelente punto de partida para cualquier persona interesada en el mundo del IoT, demostrando que con componentes relativamente simples y librerías potentes, podemos configurar un sistema de monitoreo en tiempo real robusto y escalable.

Es importante subrayar la flexibilidad del código: aunque hemos empleado una placa ESP32 S3, el programa es lo suficientemente versátil como para ser adaptado a otros microcontroladores compatibles con Arduino.

En el entorno cada vez más conectado en el que vivimos, entender y aplicar protocolos como MQTT se convierte en una habilidad invaluable. Los conocimientos adquiridos aquí pueden extenderse a una variedad de aplicaciones, desde domótica hasta soluciones empresariales de IoT. Esperamos que este artículo haya gustado y te animo a que lo hagas tu mismo.

Referencias:

Código fuente:

https://github.com/elrincondeada/mqttdemo

Aprendiendo MQTT: El Protocolo, Aplicaciones y un Ejemplo Práctico

Mqtt elementos y comunicación entre ellos

Como punto de inicio para este blog, me he propuesto ofrecer un enfoque práctico del protocolo de comunicaciones MQTT, una herramienta esencial en el mundo del Internet de las Cosas (IoT). Para comenzar, presentaré tres ejemplos concretos que ilustran los componentes clave del protocolo: el publicador, el suscriptor y el intermediario o ‘broker’. A continuación, encontrarás un video resumen que anticipa lo que abordaremos en detalle. Tras el video, profundizaremos en algunos conceptos teóricos para entender mejor la tecnología que estamos manejando.

¿Qué es MQTT?

El Protocolo de Cola de Mensajes Telemétricos (MQTT, por sus siglas en inglés de Message Queuing Telemetry Transport) es un protocolo de comunicación diseñado para entornos de bajo ancho de banda, alta latencia o redes inestables. Originalmente desarrollado por IBM en 1999, el MQTT ha ganado relevancia en la era del Internet de las Cosas (IoT) debido a su diseño ligero y eficiente. En este post, exploraremos los fundamentos de MQTT y veremos ejemplos de cómo se aplica en escenarios del mundo real. MQTT es un protocolo de mensajería basado en el modelo de publicación/suscripción. En este modelo, hay tres componentes principales:

  1. Publicador: Envía mensajes a un tema específico.
  2. Suscriptor: Escucha mensajes en un tema específico.
  3. Broker: Sirve como intermediario, recibiendo mensajes de los publicadores y enviándolos a los suscriptores.

A diferencia de otros protocolos de mensajería como HTTP, MQTT es más ligero, consume menos recursos y tiene la capacidad de mantener la conexión activa durante más tiempo, lo que lo hace ideal para dispositivos IoT.

Características Principales

  • QoS (Calidad del Servicio): MQTT soporta diferentes niveles de calidad de servicio para el envío de mensajes.
  • Retención de Mensajes: El broker puede retener el último mensaje en un tema para que los nuevos suscriptores puedan recibirlo inmediatamente después de suscribirse.
  • Last Will and Testament (Testamento): Un mensaje que se envía cuando el cliente se desconecta inesperadamente.
  • Seguridad: Aunque MQTT no define medidas de seguridad propias, se puede implementar mediante TLS/SSL.

Es importante mencionar que MQTT ofrece diferentes niveles de «Calidad de Servicio» (QoS) para el envío de mensajes:

  • QoS 0: El mensaje se entrega en el mejor esfuerzo posible, pero no hay confirmación de entrega. Puede haber pérdida de mensajes.
  • QoS 1: El mensaje se entrega al menos una vez, y se confirma con un mensaje PUBACK. Esto asegura la entrega, pero puede haber duplicados.
  • QoS 2: El mensaje se entrega exactamente una vez al receptor. Este es el nivel más alto de QoS y utiliza un intercambio de cuatro pasos para asegurarse de que no hay pérdidas ni duplicados.

Según el nivel de QoS, el broker y el cliente pueden intercambiar mensajes adicionales para asegurar la entrega, pero una vez que la entrega se ha confirmado, el mensaje ya no se guarda en el broker (a menos, como dije antes, que se utilice la bandera «Retain»).

Entonces sí, en general, los mensajes se entregan a los clientes suscritos y luego se «borran» o no se retienen en el broker, a menos que se especifique lo contrario.

Tópicos (Topics) en MQTT

Los tópicos son una de las características más fundamentales en MQTT. Actúan como canales de mensajería a los que los clientes pueden suscribirse o en los cuales pueden publicar mensajes. Cada tópico es simplemente una cadena de texto que suele estar estructurada en niveles, separados por el carácter ‘/’. Por ejemplo, casa/sala/temperatura podría ser un tópico utilizado para publicar la temperatura en la sala de una casa. Cuando un cliente se suscribe a un tópico, recibe todos los mensajes que se publican en ese tópico por parte de cualquier publicador (publisher). De manera similar, cualquier mensaje que un cliente publique en un tópico se enviará a todos los clientes suscritos a ese tópico.

Comodines (Wildcards) en MQTT

Los comodines son caracteres especiales que permiten a los clientes suscribirse a múltiples tópicos simultáneamente. MQTT soporta dos tipos de comodines:

  1. Signo más (+): Este comodín puede sustituir a un solo nivel en un tópico. Por ejemplo, si te suscribes al tópico casa/+/temperatura, recibirías mensajes de casa/sala/temperatura, casa/cocina/temperatura, etc.
  2. Almohadilla (#): Este comodín puede sustituir a múltiples niveles en un tópico. Debe ser utilizado solo al final de un tópico. Por ejemplo, casa/# te suscribiría a todos los tópicos que comiencen con casa, incluyendo casa/sala/temperatura, casa/sala/humedad, casa/cocina/luz, etc.

También es posible utilizar ambos comodines en una sola suscripción. Por ejemplo, casa/+/+/estado podría recibir mensajes de casa/sala/luz/estado, casa/cocina/ventilador/estado, etc.

Los tres elementos en la práctica.

En los siguientes vídeos y posts iremos viendo en detalle los tres elmentos que componen el protocolo. El publicador será un sensor de temperatura y humedad AHT20 gobernado por una placa ESP32 S3. La naturaleza del envío de mensajes va a ser síncrona y se realizará cada cierto intervalo de tiempo. Este es un ejemplo que estaría dentro del loop del framework de arduino.

 long now = millis();
  static long lastMsg = 0;

  if (now - lastMsg > 10000)
  { // Enviar telemetría cada 10 segundos
    lastMsg = now;

    // Aquí, pon el código para leer tu sensor
    float temperatura = e_temp.temperature;
    float humedad = e_humedad.relative_humidity;

    char msgt[50];
    snprintf(msgt, 50, "Valor del sensor: %f", temperatura);
    Serial.print("Publicando mensaje: ");
    Serial.println(msgt);

    // Publicar el mensaje
    client.publish("esp32/temperatura", msgt);

    char msgh[50];
    snprintf(msgh, 50, "Valor del sensor: %f", humedad);
    Serial.print("Publicando mensaje: ");
    Serial.println(msgh);

    // Publicar el mensaje
    client.publish("esp32/humedad", msgh);
  }

El broker, de momento, usaremos EMQX (sitio web EMQX) Nos podemos montar un servidor de pruebas con docker fácilmente. Este sería un ejemplo de Dockerfile:

# Usar la imagen oficial de EMQ X
FROM emqx/emqx
# Exponer los puertos MQTT, MQTT/SSL, WebSockets
EXPOSE 1883 8883 8083
# Ejecutar EMQ X
CMD ["emqx", "start"]

Después, construir la imagen y lanzar la instancia

docker build -t my_emqx .
docker run -d --name my_emqx_instance -p 1883:1883 -p 8083:8083 -p 8883:8883 my_emqx

Si lo preferéis, podemos usar directamente:

docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8883:8883 emqx/emqx

Estos son los puertos que expone y usa el broker. Los puertos del protocolo son los estándares.

  • 1883: Puerto estándar para MQTT sin cifrado.
  • 8883: Puerto estándar para MQTT con cifrado SSL/TLS.
  • 8083: Puerto para el protocolo MQTT sobre WebSockets sin cifrado.
  • 8084: Puerto para el protocolo MQTT sobre WebSockets con cifrado SSL/TLS (esto es lo que añadiste en tu comando).
  • 18083: Puerto para la interfaz de administración web de EMQ X (esto también es adicional en tu comando).

Por último, vamos a hablar del consumidor o suscriptor. La comunicación o recepción de mensajes aquí es de naturaleza asíncrona. En programación, una función de callback, recibirá los datos del mensaje una vez que nos hayamos suscrito a un tópico. La implementación del consumidor la he hecho en c# con dotnet y la librería MQTTnet https://github.com/dotnet/MQTTnet (imaginaros un servicio en la nube que analiza datos) pero también podría ser un actuador que se implentara en otra placa ESP32.

//Evento que se va a lanzar cada vez que se publique en uno de
//los "topic" a los que estamos suscritos
mqttClient.ApplicationMessageReceivedAsync += e =>
{
	Console.WriteLine($"Recibido mensaje. topic:{e.ApplicationMessage.Topic}");
	Console.WriteLine(Encoding.ASCII.GetString(e.ApplicationMessage.PayloadSegment));
	return Task.CompletedTask;
};

Ejemplos de usos de MQTT y aplicaciones:

Automatización del Hogar

MQTT es ampliamente utilizado en sistemas de automatización del hogar como Home Assistant o Domoticz. Por ejemplo, un sensor de temperatura puede publicar lecturas en un tema, y un termostato puede suscribirse a ese tema para ajustar la calefacción o la refrigeración.

Monitoreo de Salud

En un hospital, los dispositivos médicos como monitores de signos vitales pueden utilizar MQTT para enviar datos en tiempo real a un sistema centralizado que los médicos puedan supervisar.

Vehículos Autónomos

Los vehículos autónomos generan grandes cantidades de datos de sensores que deben procesarse en tiempo real. MQTT puede facilitar la transmisión eficiente de estos datos a una estación central para su análisis y toma de decisiones.

Agricultura Inteligente

Sensores de humedad y temperatura en un campo agrícola pueden usar MQTT para enviar sus datos a un sistema central. Basado en estos datos, el sistema puede ajustar automáticamente el riego y la fertilización.

Logística y Seguimiento

Las empresas de logística pueden utilizar MQTT para monitorear en tiempo real la ubicación y el estado de sus vehículos y mercancías, lo que permite una mejor planificación y eficiencia en la entrega.

Conclusión

MQTT se ha establecido como un protocolo esencial para el Internet de las Cosas y otras aplicaciones donde la eficiencia, la simplicidad y la fiabilidad son cruciales. Desde la automatización del hogar hasta aplicaciones empresariales y sanitarias, las posibilidades son prácticamente infinitas. En los siguientes vídeos y ejemplos iremos desgrando cada uno de los elementos del protocolos y aprenderemos experimentando con el. Os animo a estar pendiente y a divertiros.

Referencias:

El código fuente:

https://github.com/elrincondeada/mqttdemo