Regarding JSON parse

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.

Which one is it?

// 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);     
}

this code Sir.The code is working fine as expected but the drawback is when I change my values from CLI the device forcibly needs to be reset inorder to reflect the changes in my code.So I used System.reset() function.

I found this by removing System.reset() and tested but the parsing used to failed for the second time when I tried to change my values from CLI ,so the alternate I found was to reset the device.Hence the above code was final.

So any suggestions on this.

If device is to be reset the memory values are lost in EEPROM.So I want to eliminate that resetting but if removed I cannot parse the fresh values from CLI.

this part

I solved this part Sir.

I used ‘(int8_t)’ which worked for me to retrieve negative values from EEPROM.

upperlimit=(int8_t) EEPROM.read(2003);
lowerlimit=(int8_t) EEPROM.read(2004);
refresh= EEPROM.read(2005);

The whole idea of EEPROM is that the values are retained even when power is lost. So, if that isn’t the case, then there’s most likely something wrong with the way you’re using EEPROM.

if, during the callback, you write to your global variables, they should be available in the entire program. Have you tried breaking this thing up in pieces yet? Rather than doing everything at once, make sure the separate pieces work as intended trying to do it all?

Nope I tried by breaking the code and after analyzing only I changed the code.

Yes values are retained in EEPROM,they are not affected.But I have a fear of losing stored data when I reset my device using software function.

So I am asking the suggestion.

Now my code is working fine as expected but I am trying to remove the ‘System.reset()’ part in my callback function.

If I remove that ‘System.reset()’ I can parse for the first time not for second or third…so on which means a trouble when user enters his own values from CLI those values are parsed only once and not beyond that.

So I sticked to use ‘System.reset()’ function in my code.So that when new changes are made in values from CLI.

If ‘System.reset()’ is removed I can confidently say that code is still better.

Hello Sir,

Happy to inform you that I found the solution for avoiding reset.

// 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;



//-------------------------------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)
  {
    StaticJsonBuffer<200> jsonBuffer; 
    char json[] = "{\"upper\":\"50\",\"lower\":\"20\",\"gap\":\"1\"}";
   // JsonObject& root = jsonbuffer.parseObject(json);   
    
    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= 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);   
     
     
}

The issue was just adding the line —> StaticJsonBuffer<200> jsonBuffer; inside my callback function.

After adding inside the callback function I solved my problem of resetting the device.

Now as I said “A BETTER CODE” on my device.

Thank you for supporting me Sir.
Thanks a lot

You had been given a solution to that System.reset() problem of yours already over a month ago - you just didn’t seem to care to think through provided suggestions.

BTW, you were also told how to format code in forum posts, we keep reformatting it to keep the threads tidy - spare us the extra work by doing it right, please.
Forum Etiquette
Forum Tips and Tricks


We don’t mean to discourage people from asking questions, but we also need to protect our own sanity.
Please don’t become a so called Help Vampire

3 Likes

Sir this was not the old problem.

The old problem is already solved.Now the problem was for MQTT callback function.

I have updated the code as per your suggestions and have not neglected them.I have used 100% of your suggestions which has built confidence to code.

I thank you for that.

And now even this new reset issue was solved by myself where I learnt the debugging skills and analyse the problem well with your valued suggestions on forum.

I would like to have a guide like you.
If any mistakes I have made or hurted you please forgive me.

1 Like

Hmm, how about that then

This I have applied already.Its working

I know, but that hint was provided over a month before you rose the question here again.

1 Like