Regarding JSON parse

I am trying to get 3 values from JSON string from the server and I have my code is here :

 #include <ArduinoJson.h>
 #include <MQTT.h>
char  json[] = "{\"x\":\"upper\",\"y\":\"lower\",\"z\":\"gap\"}";

int refresh=1
float tempC,upperlimit=5.0,lowerlimit=2.0;

StaticJsonBuffer<200> jsonbuffer; 

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
    String message(p);
    
  JsonObject& root = jsonbuffer.parseObject(json); 
   
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     int x = root["x"];
     int y = root["y"];
     int z = root["z"];

     upperlimit = x;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = y;
     EEPROM.write(2004,lowerlimit);
     
     refresh = z;
     EEPROM.write(2005,refresh);
     
     Serial.println(x);
     Serial.println(y);
     Serial.println(z);
     delay(2000);
}

This is my MQTT callback function, where I am parsing the JSON string and copying to 3 different variables.
So the issue is when I send values from CLI in Ubuntu as -->

mosquitto_pub -h 174.138.116.138 -t 240027001747343337363432 -m “{“x”:“33”,“y”:“24”,“z”:“5”}”

the latest values are not being updated in my code.So what may be the problem and where I need to change the code.

Please help me

What have you tried so far?
Try printing the raw JSON before parsing to make sure if it arrives in a sensible format.
Try to make it parse correctly with hard-coded JSON.
Then combine the two?

I am unaware of this JSON dont know from where to start so I am finding difficulty.I just need in my project so.

{}parseObject() failed

I tried to print to Serial and I got this error so I realized my string is not being printing.So where can I change my code.

Serial.println(p);
Serial.println(json);

w.r.t above code I added these 2 lines to check whats being stored and I got the result on Serial monitor as
{“x”:“33”,“y”:“24”,“z”:“5”} // this is for , Serial.println§;
x // this is for , Serial.println(json);
parseObject() failed

Could you share the entire code with a link from the web IDE so we can see what’s going on?

Also, try making a minimal viable example, removing everything but the absolutely necessary parts (the parsing of JSON).

https://build.particle.io/build/5a44f906be1dd1e3930009ee

ok i will do that

That’s not the share link I was hoping for, and is rather useless.

https://go.particle.io/shared_apps/5a704fb9f3bd1e124d0003dd

// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <MQTT.h>

const char* myID;
char json[] = "{\"upper\":\"30\",\"lower\":\"20\",\"space\":\"1\"}";
float upperlimit=5.0,lowerlimit=2.0;
int refresh=1;
String macID;

StaticJsonBuffer<200> jsonbuffer; 

//-------------------------------MQTT callback function--------------------------------------//

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
    String message(p);
    
  JsonObject& root = jsonbuffer.parseObject(json); 
   
   
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     int up = root["upper"];
     int low= root["lower"];
     int space = root["gap"];

     upperlimit = up;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = low;
     EEPROM.write(2004,lowerlimit);
     
     refresh = space;
     EEPROM.write(2005,refresh);
     
     Serial.println(up);
     Serial.println(low);
     Serial.println(space);
     delay(1000);
}



void setup() {
    
Serial.begin(9600);  
if (client.isConnected()) 
  client.subscribe(myID);
  
  upperlimit=EEPROM.read(2003);
  lowerlimit=EEPROM.read(2004);
  refresh=EEPROM.read(2005);

}

void loop() {
 macID=System.deviceID();
 myID=macID.c_str();   
 client.connect(System.deviceID());   
 if (client.isConnected()) 
  {
    client.subscribe(myID);
  }
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(1000);     
}

This is how I am parsing the JSON string.

The upper,lower and space values may change based on the user choice on the web application

This minimal example seems to work fine:
https://go.particle.io/shared_apps/5a70558ef3bd1e0514000433

Now it’s up to you to combine that with your other code :wink:

Sir my requirement is different .

I am using MQTT so I need to subscribe to the topic and receive that JSON string from CLI of Ubuntu.

I am using the parse in my MQTT callback function.I will again send my code

// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <MQTT.h>

const char* myID;
char json[] = "{\"upper\":\"30\",\"lower\":\"20\",\"gap\":\"1\"}";
float upperlimit=5.0,lowerlimit=2.0;
int refresh=1;
String macID;

StaticJsonBuffer<200> jsonbuffer; 

//-------------------------------MQTT callback function--------------------------------------//

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
    String message(p);
    
  JsonObject& root = jsonbuffer.parseObject(json); 
   
  Serial.println("Topic subscribed in callback function");  
   
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     int up = root["upper"];
     int low= root["lower"];
     int space = root["gap"];

     upperlimit = up;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = low;
     EEPROM.write(2004,lowerlimit);
     
     refresh = space;
     EEPROM.write(2005,refresh);
     
     Serial.println(up);
     Serial.println(low);
     Serial.println(space);
     delay(1000);
}



void setup() {
    
Serial.begin(9600);  
if (client.isConnected()) 
  client.subscribe(myID);
  
  upperlimit=EEPROM.read(2003);
  lowerlimit=EEPROM.read(2004);
  refresh=EEPROM.read(2005);

}

void loop() {
 macID=System.deviceID();
 myID=macID.c_str();   
 client.connect(System.deviceID());   
 if (client.isConnected()) 
  {
      client.loop();
      Serial.println("Topic subscribed"); 
      client.subscribe(myID);
  }
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(1000);     
}

I know that, but seeing as the parsing part is working, it’s a matter of making sure the MQTT message arrives in the same format as the example. If so, then there’s no reason why that shouldn’t work either.
Try comparing the data you receive from the MQTT subscription with that in the example, and try to figure out what you have to change?

Yes sir when I tried to send the JSON string from CLI I got my message in the terminal where I subscribed to the same topic.

But the issue is those three values are not being copied to my

  • float variables — upperlimit,lowerlimit and
    -int variable— refresh.

This is what I am facing the problem.

// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <MQTT.h>

const char* myID;
char json[] = "{\"upper\":\"30\",\"lower\":\"20\",\"gap\":\"1\"}";
float upperlimit=5.0,lowerlimit=2.0;
int refresh=1;
String macID;

StaticJsonBuffer<200> jsonbuffer; 

//-------------------------------MQTT callback function--------------------------------------//

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
    String message(p);
    
  JsonObject& root = jsonbuffer.parseObject(json); 
   
  Serial.println(json);
  Serial.println(p);
  Serial.println("Topic subscribed in callback function");  
   
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     int up = root["upper"];
     int low= root["lower"];
     int space = root["gap"];

     upperlimit = up;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = low;
     EEPROM.write(2004,lowerlimit);
     
     refresh = space;
     EEPROM.write(2005,refresh);
     
     Serial.println(up);
     Serial.println(low);
     Serial.println(space);
     delay(1000);
}



void setup() {
    
Serial.begin(9600);  
if (client.isConnected()) 
  client.subscribe(myID);
  
  upperlimit=EEPROM.read(2003);
  lowerlimit=EEPROM.read(2004);
  refresh=EEPROM.read(2005);

}

void loop() {
 macID=System.deviceID();
 myID=macID.c_str();   
 client.connect(System.deviceID());   
 if (client.isConnected()) 
  {
      client.loop();
      Serial.println("Topic subscribed"); 
      client.subscribe(myID);
  }
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(1000);     
}

And when I tried to print to Serial whats being stored in ‘json’ the answer was only ‘upper’

Try reading the docs again on EEPROM and make sure the addresses and sizes involved are correct. Take care not to overlap them.

Currently, you're not doing anything with the data you send over MQTT, you're still parsing the hard-coded string. As such, you can try my minimalist sketch first to ignore any complications due to MQTT.

Try approaching the project in steps. Make sure JSON parsing works correctly. Then, try sending a string over and make sure it arrives the way it's supposed to. Then combine those.

I see in your code you are still not applying the hints you got a long time ago when I commented about EEPROM.write() not being the way to store float variables.
I wonder why we answer questions when our answers aren't really taken into consideration.

2 Likes
// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <MQTT.h>

const char* myID;
char json[] = "{\"upper\":\"30\"}"; //,\"lower\":\"20\",\"gap\":\"1\"}";
int upperlimit=5,lowerlimit=2;
int refresh=1;
String macID;

StaticJsonBuffer<200> jsonbuffer; 

//-------------------------------MQTT callback function--------------------------------------//

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
    String message(p);
    
     
    Serial.println("Topic subscribed in callback function"); 
    Serial.print("Before = ");
    Serial.println(p);
    
    //JsonObject& root = jsonbuffer.parseObject(json); 
   
    
    Serial.print("After = ");
    Serial.println(p);
    
    JsonObject& root = jsonbuffer.parseObject(p); 
    
    delay(5000);
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     
     int up = root["upper"];
     int low= root["lower"];
     int space = root["gap"];

     upperlimit = up;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = low;
     EEPROM.write(2004,lowerlimit);
     
     refresh = space;
     EEPROM.write(2005,refresh);
     
     Serial.println(up);
     Serial.println(low);
     Serial.println(space);
     //delay(1000);
}



void setup() {
    
Serial.begin(9600);  
if (client.isConnected()) 
  client.subscribe(myID);
  
  upperlimit=EEPROM.read(2003);
  lowerlimit=EEPROM.read(2004);
  refresh=EEPROM.read(2005);

}

void loop() {
 macID=System.deviceID();
 myID=macID.c_str();   
 client.connect(System.deviceID());   
 if (client.isConnected()) 
  {
      client.loop();
      Serial.println("Topic subscribed"); 
      client.subscribe(myID);
  }
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(1000);     
}

Right now I was working with this updated code Sir.

I have tried your suggestions and satisfied with that and it has helped me during my other project.I am thankful to you Sir.

But right now I am facing this issue when I use CLI of ubuntu and send my JSON string using MQTT publish command where I am subscribing that topic in my code.

The message is being copied as it is in String ‘p’ but error in parsing that string.Since I dont even know the abc of JSON the reason why I am so troubled.
Sorry _

Divide the project into small steps:

  • figuring out what JSON is (Google is your friend here)
  • Transmitting JSON data over MQTT, and making sure it’s formatted correctly on the receiving end. Don’t check this by subscribing on your computer, but have the Photon print it so you can compare it to something you know is working.
  • Parsing JSON. You’ve got a working example. As long as the data you’re receiving matches that, there’s no reason why that wouldn’t work.
  • Saving that parsed JSON to variables. Make sure the data types are chosen correctly.
  • Saving data to EEPROM. Again, mind you datatypes and addresses. Give the docs a good read or two.

Don’t try to do everything at once, but break it up into manageable steps.
Also, don’t keep on repeating the same question over and over again, hoping one of us will spoon-feed you the answer. You’re going to have to put in some effort on your own. You’ve repeatedly mentioned you don’t know anything about JSON; why not go read up on that first then?

3 Likes
// This #include statement was automatically added by the Particle IDE.
#include <ArduinoJson.h>

// This #include statement was automatically added by the Particle IDE.
#include <MQTT.h>

const char* myID;
char json[] = "{\"upper\":\"50\",\"lower\":\"20\",\"gap\":\"1\"}";
int upperlimit=5,lowerlimit=2;
int refresh=1;
String macID;

StaticJsonBuffer<200> jsonbuffer; 

//-------------------------------MQTT callback function--------------------------------------//

byte server[] = { 174,138,116,138 };//the IP of broker
void callback(char* topic, byte* payload, unsigned int length);
MQTT client(server, 1883, callback);


void callback(char* topic, byte* payload, unsigned int length)
  {
    char p[length + 1];
    memcpy(p, payload, length);   
    p[length] = NULL;
   // String message(p);
    
     
    Serial.println("Topic subscribed in callback function"); 
    
    Serial.print("Before = ");
    Serial.println(p);
    
    JsonObject& root = jsonbuffer.parseObject(p);   
    
    Serial.print("After = ");
    Serial.println(p);
    
    
    
    delay(5000);
     
    if (!root.success()) 
    {
      Serial.println("parseObject() failed");
      return;
     }
     
     
     int up = root["upper"];
     int low= root["lower"];
     int space = root["gap"];
     
     upperlimit = up;
     EEPROM.write(2003,upperlimit);
     
     lowerlimit = low;
     EEPROM.write(2004,lowerlimit);
     
     refresh = space;
     EEPROM.write(2005,refresh);
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(1000);
     
     System.reset();
}



void setup() {
    
Serial.begin(9600);  
if (client.isConnected()) 
  client.subscribe(myID);
 
  
  upperlimit=(int8_t) EEPROM.read(2003);
  lowerlimit=(int8_t) EEPROM.read(2004);
  refresh=(int8_t) EEPROM.read(2005);

}

void loop() {
 macID=System.deviceID();
 myID=macID.c_str();   
 client.connect(System.deviceID());   
 if (client.isConnected()) 
  {
      client.loop();
      Serial.println("Connected"); 
      client.subscribe(myID);
  }
     
     Serial.println(upperlimit);
     Serial.println(lowerlimit);
     Serial.println(refresh);
     delay(2000);     
}

I found the solution for my problem,
the issue was --> JsonObject& root = jsonbuffer.parseObject§; I replaced the parsing object as ‘p’ instead of json.

Also while reading the negative values I used (int8_t) typecasting to get the negative numbers stored in EEPROM.

But one bad thing is I want to use System.reset() function whenever I update new values from CLI.So is there any ways that I can remove that System.reset() part so my code runs without resetting the device.