ESP8266: Parsing JSON Arrays

The objective of this post is to explain how to parse simple JSON Arrays on the ESP8266, using the ArduinoJson library.


Introduction

In this post, we will create a simple program to parse a JSON string that includes an array of integers. We assume that the ESP8266 libraries for the Arduino IDE were previously installed. You can check how to do it here.

Also, for a more detailed explanation on how to use this library to parse simple JSON name/value pairs, check this previous post.


Setup

First of all, we will include the library that implements the parsing functionality. The library can be obtained via library manager of the Arduino IDE.

#include <ArduinoJson.h>

For debugging purposes, we start a serial communication in the setup function.

void setup() {

  Serial.begin(115200);
  Serial.println();

}


Main loop

We will implement the rest of the functionality on the main loop.

In this case, we will parse a slightly more complex JSON string that we did on the previous post. In this case, we will have a sensor type and an array of values associated with that sensor.

char JSONMessage[] = "{\"SensorType\":\"Temperature\", \"Value\": [20,21,23]}";

For the sake of readability, the structure is shown bellow without escaping characters.

{
"SensorType" : "Temperature",
"Value" : [20,21,23]
}

Then, we need to declare an object of class StaticJsonBuffer, that will contain the object tree. We specify a size value that is big enough for the structure we want to parse (in this case, we defined 300 bytes).

StaticJsonBuffer<300> JSONBuffer;

Next, we call the parseObject method on the StaticJsonBuffer object, passing the JSON string as argument. This method will return a reference to an object of class JsonObject.

JsonObject&  parsed= JSONBuffer.parseObject(JSONMessage);

Since the procedure to get a parsed value from a simple name/value pair was explained in the previous post, we will jump right to how to obtain the values in the array.

The procedure is very similar to the one used before. So, we still use square brackets and the name of the parameter to obtain the values, but we add an extra pair of square brackets with the value of the index we want to retrieve. Just to use the correct terminology, using the square brackets corresponds to using the subscript operator [1].

int value0=parsed["Value"][0];
int value1=parsed["Value"][1];
int value2=parsed["Value"][2];

As an alternative, we can declare a reference to an object of type JsonArray and manipulate it. To get it, we just use the first pair of square brackets and we don’t specify the array index.

JsonArray& values= parsed[“Value”];

Because the memory of a JsonArray is located in a JsonBuffer, we always manipulate it through reference [2] (which corresponds to the “&” after the name of the class). This class has some useful methods that can be seen here. Naturally, one of the available methods allows us to retrieve an element of a specific index [3].

But, to keep things simple, we will maintain the method of access mentioned first, by using the subscript operator. Since we may not know the size of the array in compile time, we can get it using the size method and then iterate through each value.

int arraySize =  parsed["Value"].size();

  for (int i = 0; i< arraySize; i++){

  int sensorValue=parsed["Value"][i];
  Serial.println(sensorValue);

}

Important: If we wanted to directly print the value of the array without previously storing it in an integer variable, we would need to add a cast, as seen below:

Serial.println(parsed[“Value”][i].as<int>());

Otherwise we would get the error shown in figure 1. The documentation of the library has more information about casting values.

ArduinoJSON cast error

Figure 1 – Error when casting is not done.

So, to summarize, we present the final code, which includes some more prints and error checking.

void loop() {

  Serial.println("—————— -");
  char JSONMessage[] = " {\"SensorType\": \"Temperature\", \"Value\": [20, 21, 23]}";
  Serial.print("Message to parse: ");
  Serial.println(JSONMessage);

  StaticJsonBuffer<300> JSONBuffer; //Memory pool
  JsonObject& parsed = JSONBuffer.parseObject(JSONMessage);   //Parse message

  if (!parsed.success()) {      //Check for errors in parsing

    Serial.println("Parsing failed");
    delay(5000);
    return;

  }

  const char * sensorType = parsed["SensorType"]; //Get sensor type value
  Serial.print("Sensor type: ");
  Serial.println(sensorType);

  int arraySize = parsed["Value"].size();   //get size of JSON Array
  Serial.print("\nSize of value array: ");
  Serial.println(arraySize);

  Serial.println("\nArray values without explicit casting");
  for (int i = 0; i < arraySize; i++) { //Iterate through results

    int sensorValue = parsed["Value"][i];  //Implicit cast
    Serial.println(sensorValue);

  }

  Serial.println("\nArray values with explicit casting");
  for (int i = 0; i < arraySize; i++) {  //Iterate through results

    Serial.println(parsed["Value"][i].as<int>());//Explicit cast

  }

  Serial.println();
  delay(5000);

}

The final result is shown in figure 2.

ArduinoJSON Array parse

Figure 2 – Output of the program in the Arduino IDE serial console.


References

[1] https://msdn.microsoft.com/en-us/library/th52k9c8.aspx

[2] https://github.com/bblanchon/ArduinoJson/wiki/API-Reference#jsonarray

[3] https://github.com/bblanchon/ArduinoJson/wiki/API-Reference#jsonarrayget


Related posts


Technical details

  • ESP8266 libraries: v2.3.0.
  • ArduinoJson library: v5.1.1.

11 thoughts on “ESP8266: Parsing JSON Arrays”

  1. Thanks for writing this, it helped me. 2 suggestions: Update it to ArduinoJson 6. Mostly just use StaticJsonDocument parsed; //Memory pool
    auto error = deserializeJson(parsed, JSONMessage);
    if ( error ) { //Check for errors in parsing
    and don’t use size() in the for loop as this increases memory use, instead use iterators as described in https://arduinojson.org/v6/api/jsonarray/size/. -Frank

Leave a Reply

Discover more from techtutorialsx

Subscribe now to keep reading and get access to the full archive.

Continue reading