How to extract payload from a topic

I am using an arduino UNO WIFI Rev.2. I am doing an experiment where I would like to extract a value of type FLOAT from a payload and store that value inside a variable that can be used else where in the program. I am not so advanced with JSON as I am still learning. How would you suggest I extract the value from the 'Value' field from the JSON doc which is getting measurements from a DHT sensor? Any help is appreciated.

#define BROKER_IP    "iop.test.kamk.gv"
#define BROKER_PORT  1883
#define DEV_NAME     "mqttdevice"
#define MQTT_USER    ""
#define MQTT_PW      ""

// WiFi settings for Visitor  -  
const char ssid[] = "freevisitor";  // Network SSID
const char pass[] = "123visitor";  // Password




// Library functions
#include <ArduinoJson.h>    // Library ArduinoJson by Benoit Blanchon ver. 6.16.1
#include <DHT.h>            // DHT sensor library by Adafruit ver. 1.3.10
#include <MQTT.h>           // Library MQTT by Joel Gaehwiler ver. 2.4.7
#include <WiFiNINA.h>       // Library WiFiNINA by Arduino ver. 1.7.0

WiFiClient Network;         // Creates a client to the internet
MQTTClient client;          // Creates MQTT client

const char topic_out[]  = "KAMK/students/sensor/y";   // MQTT message topic  -  
const char topic_in[]  = "KAMK/students/sensor/y";   // MQTT message topic

// Delay variables and settings
unsigned long currentMillis;
unsigned long lastTemperature = 0;
unsigned long lastHumidity = 0;

StaticJsonDocument<200> JsonDoc;  // Reserves memory for JSON document



// DHT sensor settings
#define DHTTYPE DHT11
#define DHT11Pin 2
#define TEMPTYPE 0        // Celsius degrees

DHT dht(DHT11Pin, DHTTYPE); // Connection for the sensor

void setup() 
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN,OUTPUT);
  WiFi.begin(ssid, pass);
  client.begin(BROKER_IP, BROKER_PORT, Network);
  client.onMessage(messageReceived);
  
  connect();
  dht.begin();
}

void loop() 
{
  char AdString[200];
   
  client.loop();
  if (!client.connected()) 
  {
    connect();
  }
  currentMillis = millis();

  if (currentMillis - lastTemperature > 6000) 
  {
    lastTemperature = currentMillis;
    // Blink LED to indicate message leaving
    if ( digitalRead(LED_BUILTIN) )
      digitalWrite(LED_BUILTIN,LOW);
    else
      digitalWrite(LED_BUILTIN,HIGH);
    
    // Json format
    JsonDoc.clear();
    JsonDoc["Sensor"] = "room_1a";
    JsonDoc["Type"] = "temperature";
    JsonDoc["Value"] = dht.readTemperature(TEMPTYPE);
    serializeJson(JsonDoc, AdString);
    client.publish(topic_out, AdString); //
    Serial.print("Temperature sent.");
  }  
//  if (currentMillis - lastHumidity > 10000) 
//  {
//    lastHumidity = currentMillis;
//    // Json format
//    JsonDoc.clear();
//    JsonDoc["Sensor"] = "room_1b";
//    JsonDoc["Type"] = "humidity";
//    JsonDoc["Value"] = dht.readHumidity();
//    serializeJson(JsonDoc, AdString);
//    client.publish(topic_out, AdString); // 
//    Serial.println("Humidity sent.");
//  }  
}
void connect() 
{
  Serial.print("Checking WiFi...");
  while (WiFi.status() != WL_CONNECTED) 
  {
    Serial.print(".");
    delay(1000);
  }

  Serial.print("\nConnecting MQTT server...");
  while (!client.connect(DEV_NAME, MQTT_USER, MQTT_PW)) 
  {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("\nConnected!");
  // Creat Topic
  client.subscribe(topic_in); 
}

String messageReceived( String &topic, String &payload) //String &topic, 
{
  Serial.println("incoming: " + topic + " - " + payload);
  Serial.println(payload);
  return(payload);
}

Have you tried using a JSON library?

Hmm, I don't think I get it...

You want to put a value in a JSON object and extract that same value within one program?

Anyway, you probably want to deserialise a JSON object. There is an example on the homepage of the library you are using.

Hey, ultimately I want to subscribe to another topic coming from somewhere else, but i am testing how I will do it inside the program first by publishing to a topic then extracting from the same topic. If that makes sense.

I see.

Did you succeed in deserialising the payload?

I don't think I can do that deserialising yet because in one of the parameters I need an input.
deserializejson(doc, input) where input is the json doc to parse. The payload needs to be accessible but in this current state it is not because it is in the function.

Does your sketch compile? If I look at the MQTT library documentation, I see that the callback function (messageReceived in your case) should be of type void(*)(int), not String(*)(String&, String&) as you have.

I am looking at this example by the way.

I must be looking at the wrong library then.

Anyway, would something like this be what you are looking for?

void messageReceived(String& topic, String& payload) {
  Serial.println("incoming: " + topic + " - " + payload);
  Serial.println(payload);

  deserializeJson(JsonDoc, payload);
  float value = JsonDoc["Value"];
}

I can not test this code myself at the moment.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.