Need Help! How to parse Jason on Arduino

I have been able to parse the data in the file jason if it like this:

{"led":"1","stat":"on"}

but when I try to parse the data such as the following, the parse is always fail

[{"led":"1","stat":"on"},{"led":"2","stat":"off"},{"led":"3","stat":"on"},{"led":"4","stat":"off"}]

the program looks like this

    String section="header";
    while(client.available()){
    String line = client.readStringUntil('\r');
     //Serial.print(line);
    // we’ll parse the HTML body here
    if (section=="header") { // headers..
      //Serial.print("");
      if (line=="\n") { // skips the empty space at the beginning 
        section="json";
      }
    }
    else if (section=="json") {  // print the good stuff
      section="ignore";
      String result = line.substring(1);

      
      // Parse JSON
      int size = result.length() + 1;
      char json[size];
      result.toCharArray(json, size);
      StaticJsonBuffer<500> jsonBuffer;
      JsonObject& json_parsed = jsonBuffer.parseObject(json);
      if (!json_parsed.success())
      {
        Serial.println("parseObject() failed");
        return;
      }
      

       // Fetch values.
  //
  // Most of the time, you can rely on the implicit casts.
  // In other case, you can do root["time"].as<long>();
  const char* led = json_parsed["led"];
  const char* stat = json_parsed["stat"];
  
  Serial.print("Led = ");
  Serial.println(led);
  Serial.print("Status = ");
  Serial.println(stat);

Can someone help me please.. :sob:
sorry my english is not so good..

wow - never seen so much use of The String class, even yours state machine is done using Strings... hopefully you are running this code on a very large modern arduino with tons of RAM ...

especially since you duplicate your string just to get rid of the first char, then duplicate that again in a stack allocated char array and then building a huge json buffer for decoding... (c_str() on the string object would give you the pointer to the buffer, so char * result = line.c_str() +1; would be saving some memory already)

Seriously I would recommend to trash all that code with the String object, use an enum and byte for state management especially if you are on a standard arduino and use char arrays, strtok, etc for parsing. Not sure about your Json library, but this one is pretty effective

If you already use that library see why parsing fail

And for building up knowledge you should also read The Evils of Arduino Strings so that you understand what you do with all those Strings. (There are no good or wrong tools, just need to use them when they are appropriate, in the right context, and in full understanding of benefits/drawbacks)

GitHub - zserge/jsmn: Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket looks nice (I haven't used it.)

Option 1) Google "arduino JSON library" and use one that someone has already written.

Option 2) Go to Uni, do a CS degree, learn about LALR(1) parsing.

Thanks for all the responses.. :smiley:
This takes some time for me to understand, because I am new to raduino, and this is the progress that I get..
I read why parsing fail from j-m-l .. and got a hint that if I use the array, the sample code used is like this :

[{"hello":"world"}]

JsonArray& root = jsonBuffer.parseArray(json);
const char* world = root[0]["hello"];

and this was previous led program, which has now been edited..

// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!

#include <ArduinoJson.h>
;

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    // wait serial port initialization
  }

char json[] = "[{\"led\":\"1\",\"stat\":\"on\"},{\"led\":\"2\",\"stat\":\"off\"},{\"led\":\"3\",\"stat\":\"on\"},{\"led\":\"4\",\"stat\":\"off\"}]";

//
// Step 1: Reserve memory space
//
StaticJsonBuffer<200> jsonBuffer;

//
// Step 2: Deserialize the JSON string
//
JsonArray& root = jsonBuffer.parseArray(json);

if (!root.success())
{
  Serial.println("parseObject() failed");
  return;
}

//
// Step 3: Retrieve the values
//

      if (strcmp(root[0]["led"], "1") == 0) {
        const char* led    = root[0]["led"];
        const char* stat   = root[0]["stat"];
        Serial.print ("LED = ");
        Serial.println (led);
        Serial.print ("Status = ");
        Serial.println (stat);
      }      
      if (strcmp(root[1]["led"], "2") == 0) {
        const char* led    = root[1]["led"];
        const char* stat   = root[1]["stat"];
        Serial.print ("LED = ");
        Serial.println (led);
        Serial.print ("Status = ");
        Serial.println (stat);
      }
      
      if (strcmp(root[2]["led"], "3") == 0) {
        const char* led    = root[2]["led"];
        const char* stat   = root[2]["stat"];
        Serial.print ("LED = ");
        Serial.println (led);
        Serial.print ("Status = ");
        Serial.println (stat);
      }      
      if (strcmp(root[3]["led"], "4") == 0) {
        const char* led    = root[3]["led"];
        const char* stat   = root[3]["stat"];
        Serial.print ("LED = ");
        Serial.println (led);
        Serial.print ("Status = ");
        Serial.println (stat);
      }
      
      else {
        Serial.println("No Data");
      }

}

void loop() {
  // not used in this example
}

output from serial monitor :

LED = 1
Status = on
LED = 2
Status = off
LED = 3
Status = on
LED = 4
Status = off
;

WTF?

Why did you feel it necessary to copy/paste code 4 times, when the only difference is the array index?

Do you still have a problem?

I do not know, but when I remove ;
This error appears

exit status 1
'ArduinoJson' does not name a type

yes PaulS I still have a problem, I still do not know how to do looping, so I still use manual way by writing it four times.

Can you give me an example, how to do it ..
Thank you in advance..

I do not know, but when I remove ;
This error appears

exit status 1
'ArduinoJson' does not name a type

If that is truly the case, there is something wrong with the header file. Post a link to the library you are using.

yes PaulS I still have a problem, I still do not know how to do looping, so I still use manual way by writing it four times.

Can you give me an example, how to do it ..

for real?

This is the library that I use

https://github.com/bblanchon/ArduinoJson

no, I mean I still don't understand how to pointing the order of objects in its array. so what variables should I use to pointing the order of objects in the array, and is used for looping.

I mean I still don't understand how to pointing the order of objects in its array

And I have no idea what you mean by "pointing the order of objects in its array". First, what array are you talking about?

here is an example on how to parse exactly your structure - IT EXPECTS YOUR STRUCTURE AS IS (number of leds can vary)

#include <ArduinoJson.h>

void setup() {
  Serial.begin(115200);
  char json[] = "[{\"led\":\"1\",\"stat\":\"on\"},{\"led\":\"2\",\"stat\":\"off\"},{\"led\":\"3\",\"stat\":\"on\"},{\"led\":\"4\",\"stat\":\"off\"}]";

  //
  // Step 1: Reserve memory space
  //
  StaticJsonBuffer<200> jsonBuffer;

  //
  // Step 2: Deserialize the JSON string
  //
  JsonArray& root = jsonBuffer.parseArray(json);  //parseArray() returns a reference to a JsonArray

  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  }

  //
  // Step 3: Retrieve the values
  //
  Serial.println("--------------------------");
  for (int i = 0; i < sizeof(root); i++) {

    Serial.println(i);

    // extracting strings
    Serial.print("\tled "); Serial.print(root[i]["led"].as<char*>());
    Serial.print(" is "); Serial.println(root[i]["stat"].as<char*>());

    // or extracting numerical data
    int led = root[i]["led"].as<long>();
    byte ledStatus;
    if (!strcmp(root[i]["stat"].as<char*>(), "on")) ledStatus = HIGH; else ledStatus = LOW;
    Serial.print ("\tled "); Serial.print (led); Serial.print (" is "); Serial.println (ledStatus);

    Serial.println("--------------------------");
  }
}



void loop() {}

I print things twice, one by extracting the value from a given key as a c string (char*) and the second time for the led as a number + I use the strcmp() function to build out a value if my LED is HIGH or LOW

that will print out the following: (need to set your console at 115200 bauds)

--------------------------
0
	led 1 is on
	led 1 is 1
--------------------------
1
	led 2 is off
	led 2 is 0
--------------------------
2
	led 3 is on
	led 3 is 1
--------------------------
3
	led 4 is off
	led 4 is 0
--------------------------

does this help?

as a side note, your JSON (assuming you can control its format):

YoungZy:

[{"led":"1","stat":"on"},{"led":"2","stat":"off"},{"led":"3","stat":"on"},{"led":"4","stat":"off"}]

is pretty wordy, no?

seems to me that the led# is somewhat superfluous, you're using arrays already...

{"ledStatus":[1,0,1,0]}