How to parse different JSON string ?

In my recent project, I am working with JSON and Arduino. Here, I have to parse incoming JSON string in Arduino and parsing successfully done. But only for one constant JSON string. If suppose incoming JSON string changed then I faced a problem.

For example, if my incoming JSON string like:

{"TPS":"0.40","MAP":"0.95","LOAD":"14"}

And Arduino code for parsing this data is below:

#include <LiquidCrystal.h>
#include <ArduinoJson.h>

LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

String response = "";
bool begin = false;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
}

void loop()
{ 
  StaticJsonBuffer<100> jsonBuffer;

  while(Serial.available() || !begin)
  {
    char in = Serial.read();

    if (in == '{')
    {
      begin = true;
    }

    if(begin)
    {
      response += (in);
    }

    if(in == '}')
    {
        break;
    }
    delay(1);
  }

  JsonObject& root = jsonBuffer.parseObject(response);

  String TPS = root["TPS"];
  String MAP = root["MAP"];
  String LOAD = root["LOAD"];

  lcd.setCursor(0, 0);
  lcd.print(TPS);

  lcd.setCursor(8, 0);
  lcd.print(MAP);

  lcd.setCursor(0, 1);
  lcd.print(LOAD);  
}

Then Output looks like:

TPS  : 0.40
MAP  : 0.95
LOAD : 14

That’s all fine, but when incoming JSON string change.

Means suppose, if incoming JSON string like:

{"LOAD":"2.40","RPM":"4200","INJECTION_TIME":"4.87"}

Then what should I do? Because I can’t find out any way to parse different JSON string.

in order to parse and take action, you need to know what you expect... if not the only thing you can do is analyse what you have received, JSON is structured, so you can display the JSON payload

why wouldn't you know what to expect? what's the project for? what's the data source for the JSON?

In your sketch you use a class "JsonObject". What kind of class is it and where does it come from?

Strange is that you get all your json values ​​(int, float, etc) as a string. that's unusual.

I am working with json too.
I would recommend you to parse the data itself. It is not so hard. At json you always have a key value pair. Where value can be of type string, number, bool, array or json object.

In that case you know exactly how your data will be parsed by the arduino.

If you need a very simple parser (without value is an array or json objects), then you only have to pay attention to {} at the beginning and end and the intermediate values ​​you can easily parsen.

Parsing program
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
DynamicJsonBuffer jsonBuffer(bufferSize);

const char* json = "{"LOAD":"2.40","RPM":"4200","INJECTION_TIME":"4.87"}";

JsonObject& root = jsonBuffer.parseObject(json);

const char* LOAD = root["LOAD"]; // "2.40"
const char* RPM = root["RPM"]; // "4200"
const char* INJECTION_TIME = root["INJECTION_TIME"]; // "4.87"

Information obtained from Arduinojson website using the assistant link

https://bblanchon.github.io/ArduinoJson/assistant/index.html

G

J-M-L:
why wouldn't you know what to expect? what's the project for? what's the data source for the JSON?

I recently work on ECU for auto-rikshaw. And now I have to make Software for this. And this software made using node js. Now, the software sends data which is JSON data.

so you know what data is sent? why would you be surprised by any field?

DrDooom:
In your sketch you use a class "JsonObject". What kind of class is it and where does it come from?

"JsonObject" hold the incoming JSON data.

DrDooom:
Strange is that you get all your json values (int, float, etc) as a string. that's unusual.

Ohhh... Thank you for that. It's my mistake.

DrDooom:
I am working with json too.
I would recommend you to parse the data itself. It is not so hard.

Means we don't need to store our JSON data to a particular string. Am I right?

DrDooom:
At json, you always have a key value pair. Where value can be of type string, number, bool, array or json object.

Ok, that's fine.

DrDooom:
In that case, you know exactly how your data will be parsed by the arduino.

If you need a very simple parser (without value is an array or json objects), then you only have to pay attention to {} at the beginning and end and the intermediate values you can easily parsen.

What is meant here simpler parser? Already ArduinoJson library provide simple way to parse the data.

Zardof:
Parsing program
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
DynamicJsonBuffer jsonBuffer(bufferSize);

const char* json = “{“LOAD”:“2.40”,“RPM”:“4200”,“INJECTION_TIME”:“4.87”}”;

JsonObject& root = jsonBuffer.parseObject(json);

const char* LOAD = root[“LOAD”]; // “2.40”
const char* RPM = root[“RPM”]; // “4200”
const char* INJECTION_TIME = root[“INJECTION_TIME”]; // “4.87”

Information obtained from Arduinojson website using the assistant link

https://bblanchon.github.io/ArduinoJson/assistant/index.html

G

I already tried out this thing and this only for particularly one constant string. What if the string changed then what we do? And suppose two JSON string simultaneously comes then which approach you follow?

J-M-L:
so you know what data is sent? why would you be surprised by any field?

Yes, I know what data is sent. Here data comes in form of string. I am able to parse data if the string is constant means when I have a particular string.

String like:

{"TPS":"0.40","MAP":"0.95","LOAD":"14"}

Suppose my string now changed and its likes:

{"LOAD":"2.40","RPM":"4200","INJECTION_TIME":"4.87"}

Now, I have this two strings and suppose it's coming simultaneously then how can I parse this.

Well, I think this question is less a programming question than an organizational question or a request to your program. thats why programs are compatible to other programs only in Version xyz (Program A Version 1.00 <> JSON <> Program B Version 1.01).

Program A expects the data in format xyz and program B sends it in format abc.

I understand now what you mean. If it is not known which data is transmitted (which “key’s”), it will be difficult to know what the data is for.

The class ArduinoJson has, as far as I have seen, only the function containsKey to check if a key was specified. I have not seen any function to go through all the included Json keys!

Offtopic:
In my program I work with different json inquiries and answers.
Any inquiry has …
Type = e.g. “Type”: “command_xyz”
And other data. Depending on what I get for a type, I read more “expected” keys.

If a key is not present, but this is needed, I return an error message.

These are usually programmed interfaces.

Further, it may be necessary e.g. Fields such as “sid” (security session) or tid (transaction id) necessary to check the security. This is important for me eg. Without these fields the data will not be processed further.

You can also specify a field “version”. When in the “version” field, e.g. 0.99, you expect the data with the keys abc, if “version” e.g. 1.00, you expect the data with the keys xyz!

DrDooom:
Well, I think this question is less a programming question than an organizational question or a request to your program. thats why programs are compatible to other programs only in Version xyz (Program A Version 1.00 <> JSON <> Program B Version 1.01).

Program A expects the data in format xyz and program B sends it in format abc.

I understand now what you mean. If it is not known which data is transmitted (which “key’s”), it will be difficult to know what the data is for.

The class ArduinoJson has, as far as I have seen, only the function containsKey to check if a key was specified. I have not seen any function to go through all the included Json keys!

Offtopic:
In my program I work with different json inquiries and answers.
Any inquiry has …
Type = e.g. “Type”: “command_xyz”
And other data. Depending on what I get for a type, I read more “expected” keys.

If a key is not present, but this is needed, I return an error message.

These are usually programmed interfaces.

Further, it may be necessary e.g. Fields such as “sid” (security session) or tid (transaction id) necessary to check the security. This is important for me eg. Without these fields the data will not be processed further.

You can also specify a field “version”. When in the “version” field, e.g. 0.99, you expect the data with the keys abc, if “version” e.g. 1.00, you expect the data with the keys xyz!

Ok, it’s necessary to have particular key for particular JSON string. Am I right?

It is important in any case to know what data (keys) are arriving and what "meaning" they have.

If you want to send different data for different tasks, I would e.g. Proceed as follows:

1. Json String
{
"action":"login",
"user":"admin",
"password":"gehHeim"
}

2. Json String
{
"action":"data_transmission",
"TPS":0.40,
"MAP":0.95,
"LOAD":14
}

So you have the key "action" in both / all your Json strings!

So you only have to read the key "action" first and then decide what additional data belongs to the respective action.

If action = "login", read the keys "user", "password", try Login the user
If action = "data_transmission", read the keys "TPS", "MAP", "LOAD", Display data to Screen, etc

So u can expand ur program later with new Actions.

The arduino must of course support all your actions and in your program code all needed keys should be known so that you know what they mean and what you want to do with the values.

like any communication, if one party starts to use a word or phrase that the other doesn't understand, communication fails to happen.

It is your API.... send useful data that 1) your arduino expects to see and 2) does something with it.

DrDooom:
It is important in any case to know what data (keys) are arriving and what "meaning" they have.

If you want to send different data for different tasks, I would e.g. Proceed as follows:

1. Json String
{
"action":"login",
"user":"admin",
"password":"gehHeim"
}

2. Json String
{
"action":"data_transmission",
"TPS":0.40,
"MAP":0.95,
"LOAD":14
}

So you have the key "action" in both / all your Json strings!

So you only have to read the key "action" first and then decide what additional data belongs to the respective action.

If action = "login", read the keys "user", "password", try Login the user
If action = "data_transmission", read the keys "TPS", "MAP", "LOAD", Display data to Screen, etc

So u can expand ur program later with new Actions.

The Arduino must, of course, support all your actions and in your program code all needed keys should be known so that you know what they mean and what you want to do with the values.

Ok, got it. Let me try it out. Thank you for this.