como-usar-mqtt-y-json-en-el-esp32

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.

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, 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.

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.

esp32-mqtt-json-serial

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.

github-full

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

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