Cómo usar MQTT y Json en el ESP8266 o ESP32


Continuamos con las entradas destinadas a la comunicación con ESP8266 o ESP32 viendo cómo enviar un mensaje en formato Json por MQTT.

En la entrada anterior vimos cómo emplear MQTT de forma asíncrona gracias a la librería AsyncMqttClient. Por otro lado, también vimos cómo emplear el formato Json tanto en llamadas Ajax como en Websockets.

Ahora nos toca juntar MQTT y Json. La buena noticia es que ambos combinan perfectamente. De hecho, es muy frecuente que el mensaje que enviamos por MQTT esté en formato Json.

Así que vamos a ver como emplear Json y MQTT en un ejemplo sencillo. Como de costumbre partiremos del ejemplo anterior por lo que, si aún no lo habéis hecho, conviene que le echéis un vistazo.

Anuncio:

Recordemos que en el ejemplo anterior empleamos un ESP32 para mandar un dato, que en este caso era simplemente el valor Millis(). El mismo dispositivo recibía el mensaje y lo mostraba por serial. De esta forma, evitamos emplear dos dispositivos para probar la comunicación.

Ahora vamos a hacer lo mismo, pero esta vez vamos a enviar el mensaje MQTT en formato Json. Así el bucle principal queda, esencialmente, idéntico al ejemplo anterior.

#include <WiFi.h>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>

#include "config.h"  // Sustituir con datos de vuestra red
#include "MQTT.hpp"
#include "ESP32_Utils.hpp"
#include "ESP32_Utils_MQTT_Async.hpp"

void setup(void)
{
	Serial.begin(115200);
	delay(500);

	WiFi.onEvent(WiFiEvent);
	InitMqtt();

	ConnectWiFi_STA();
}

void loop()
{
	PublishMqtt();

	delay(1000);
}

Donde la única diferencia, respecto al ejemplo anterior, es que hemos añadido la dependencia a la librería ArduinoJson.

Por otro lado, el fichero ESP32_Utils_MQTT_Async.hpp no ha cambiado. Ya dijimos que la idea era tener funciones que pudiéramos reusar en varios proyectos. Así que nos evitamos volverlo a copiar el contenido del mismo.

Lo que sí ha cambiado, lógicamente, es el fichero MQTT.hpp. Recordamos que en este fichero hemos agrupado la funcionalidad específica de nuestro proyecto en cuanto a MQTT.

#pragma once

const IPAddress MQTT_HOST(192, 168, 1, 150);
const int MQTT_PORT = 1883;

AsyncMqttClient mqttClient;

String GetPayloadContent(char* data, size_t len)
{
	String content = "";
	for(size_t i = 0; i < len; i++)
	{
		content.concat(data[i]);
	}
	return content;
}

void SuscribeMqtt()
{
	uint16_t packetIdSub = mqttClient.subscribe("hello/world", 0);
	Serial.print("Subscribing at QoS 2, packetId: ");
	Serial.println(packetIdSub);
}

void PublishMqtt()
{
	String payload = "";

	StaticJsonDocument<300> jsonDoc;
	jsonDoc["data"] = millis();
	serializeJson(jsonDoc, payload);

	mqttClient.publish("hello/world", 0, true, (char*)payload.c_str());
}

void OnMqttReceived(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
{
	Serial.print("Received on ");
	Serial.print(topic);
	Serial.print(": ");

	String content = GetPayloadContent(payload, len);

	StaticJsonDocument<200> doc;
	DeserializationError error = deserializeJson(doc, content);
	if(error) return;

	unsigned long data = doc["data"];
	Serial.print("Millis:");
	Serial.println(data);
}

Como vemos, en lugar de enviar un simple dato como en el ejemplo anterior, donde enviábamos el valor millis(), esta vez estamos enviando una cadena de texto codificada como Json.

En este Json estamos codificando un campo 'data' con el valor de millis(). Evidentemente, el Json podría ser cualquier otra cosa. Pero, para mostrar el uso y probar la comunicación, es suficiente.

Por otro lado, en la función de callback OnMqttReceived, estamos recibiendo el mensaje MQTT, decodificando el Json, y mostrando por puerto serial el campo 'data', que contiene el valor de millis() enviado.

Bastante sencillo. Ahora subimos todo a nuestro ESP32 y veremos por puerto serial el valor de Millis(), que el mismo dispositivo ha enviado.

Si empleamos un cliente genérico de MQTT como MQTT Explorer veremos que, efectivamente, los mensajes se envían a través del broker. Y, si tuviéramos más dispositivos, todos recibirían el mensaje a la vez.

Básicamente, ya hemos visto todo lo que hay en comunicación MQTT en el backend, es decir, entre dispositivos. Le podríamos dar todas las vueltas que queramos pero, en esencia, no hay más que hacer. ¿No ha sido difícil verdad? Bueno, no nos cansaremos de decir que una de las ventajas de MQTT es que es muy sencillo y robusto de usar.

Lo que sí nos queda por ver es cómo consumir MQTT desde el front end. Pero eso será en la próxima entrada, donde veremos cómo consumir este Json desde una página web servida por el propio ESP32 ¡Hasta la próxima !

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github.

Versión para el ESP8266: https://github.com/luisllamasbinaburo/ESP8266-Examples

Versión para el ESP32: https://github.com/luisllamasbinaburo/ESP32-Examples

Si te ha gustado esta entrada y quieres leer más sobre ESP8266 o el ESP32 puedes consultar la sección tutoriales de ESP8266/32
5 1 vote
Article Rating

Anuncio:

Previous Solución al ejercicio de código limpio y ordenado en C++ para Arduino
Next WinnerMicro W806, placa de desarrollo 32bit 240Mhz por 2$
0 Comments
Inline Feedbacks
View all comments