Enviar JSON por MQTT permite intercambiar mensajes estructurados entre un ESP32 o ESP8266 y el resto del sistema.
MQTT se encarga del transporte del mensaje, mientras que JSON nos permite empaquetar varios campos en una sola carga: estados, medidas, identificadores, comandos o cualquier otro dato que queramos enviar.
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.
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.
El programa principal queda, esencialmente, idéntico al ejemplo anterior. La única diferencia, es que hemos añadido la dependencia a la librería ArduinoJson.
#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);
}
Lo que sí ha cambiado es el fichero MQTT.hpp, donde agrupamos la funcionalidad específica de nuestro proyecto en cuanto a MQTT.
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.
#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);
}
Resultado
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.
Con esto ya podemos enviar información más rica por MQTT, sin limitarnos a cadenas sueltas o valores individuales. Es una base muy útil para dashboards, automatizaciones y comunicación entre dispositivos.
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

