ArduinoJSON

I have created two functions to parse two different JSON inputs using the ArduinoJSON library. Both functions run fine when run alone. But when I parse the station data in loadStationData followed by BinData in loadBinData. The station data become corrupted. I have placed Serial.println(station.msg); before and after the parseObject() call. Here is the Serial output …

ln0001/ws00001. Message: {“tackid”:1,“principal”:“FA20307”,“msg”:“start”}
JSONString parsed
ln0001/ws00001/sb000001. Message: {“part_number”:“FA21208”,“amount”:1,“state”:“pick”}
Before: 8",“amount”:1,“state”:“pick”}
After: ount
JSONString parsed

Lines 4 and 5 contain the before and after values of station.msg. This value should be “start” but it is part of the JSON string currently being parsed. Why is this happening? How can I fix it?

I have included the functions below…

struct StationData {
int tackid;
const char* principal;
const char* msg; //waiting, start, stopped
};

struct BinData {
const char* part_number;
int amount;
const char* state; //guard, pick, done, off
};

struct BinData bin = {
0, // part_number
0, // amount
“off”, // state
};

struct StationData station = {
0, // tackid
“”, // principal
“stopped”, // msg
};

boolean loadStationData(StationData& data, char* json){
StaticJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
if (root.success()){
data.tackid= root[“tackid”]|0;
data.principal = root[“principal”]|"";
data.msg = root[“msg”]|"";
return true;
} else {
return false;
}
}

boolean loadBinData(BinData& data, char* json){
Serial.print(“Before “);
Serial.println(station.msg);
StaticJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
Serial.print(“After “);
Serial.println(station.msg);
if (root.success()){
data.part_number = root[“part_number”]|””;
data.state = root[“state”]|””;
data.amount = root[“amount”]|0;
return true;
} else {
return false;
}
}

struct StationData {
   int     tackid;
   const char*   principal;
   const char*   msg; //waiting, start, stopped
};

having the size of the char * within stationdata undefined may have something to do with it.

Deva_Rishi:

struct StationData {

int    tackid;
  const char*  principal;
  const char*  msg; //waiting, start, stopped
};


having the size of the char * within stationdata undefined may have something to do with it.

That isn't the problem.

OP, you are using pointers in your structs. You are pointing to parts of the json data structure that goes out of scope when the loadStationData() function ends.

Think of a pointer as saying "The data that you want is in the 4th drawer of the fifth file cabinet in room 12." This is fine, until facilities comes along and removes all the file cabinets from room 12, and puts in a bunch of tables, instead.

Then, you go into room 12, and where your data used to be is Gary's lunch.

You should have arrays, not pointers, in your structs, and you should be using strcpy() or strcat() in your functions to COPY the data, not pointers to point to it.

Thanks, your solution worked my variables are no longer being overwritten. But I still don’t understand why the original code didn’t work. I created the bin and station data structures globally, so I though I should have two different sets of pointers, the first for station and a second for bin. When I call the loadBinData() with the reference to the bin data struct it should change the pointers for only the bin variable and it shouldn’t affect the station variables. To use your analogy, I though there are two rooms, room 12 for the station and room 13 for bin. Why would changing room 13 affect room 12?

Here is the code after applying PaulS solution. This code works correctly.

struct BinData {

char part_number[32];

int amount;

char state[24]; //guard, pick, done, off

};

struct BinData bin = {

“”, // part_number

0, // amount

“off”, // state

};

struct StationData station = {

0, // tackid

“”, // principal

“stopped”, // msg

};

boolean loadStationData(StationData& data, char* json){

StaticJsonBuffer jsonBuffer;

JsonObject& root = jsonBuffer.parseObject(json);

if (root.success()){

data.tackid= root[“tackid”]|0;

strcpy(data.principal,root[“principal”]|"");

strcpy(data.msg,root[“msg”]|"");

return true;

} else {

return false;

}

}

boolean loadBinData(BinData& data, char* json){

Serial.println(station.msg);

StaticJsonBuffer jsonBuffer;

JsonObject& root = jsonBuffer.parseObject(json);

Serial.println(station.msg);

if (root.success()){

strcpy(data.part_number, root[“part_number”]|"");

strcpy(data.state, root[“state”]|"");

data.amount = root[“amount”]|0;

return true;

} else {

return false;

}

}

so I though I should have two different sets of pointers, the first for station and a second for bin.

You DO have two different sets of pointers. But, they point to memory that gets overwritten.

Go back and read reply #2 again.

And, CODE TAGS, damn it. Use code tags when posting code.