ESP8266: Parsing JSON

About: I'm busy building machines.

As promised in my previous instructable, I will be covering more about the ArduinoJson library in detail, in this instructable. JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write, and easy for machines to parse and generate. JSON objects are written in key/value pairs and it's a must for keys to be of the string data type while values can be a string, number, object, array, boolean or null. A vast majority of APIs that are now being used will return JSON data when called, and knowing how to parse them will definitely benefit you.

In this instructable, we will be using the ArduinoJson library for the ESP8266 to help us parse JSON data and extract values based on keys. The ArduinoJson library is also capable of serializing JSON, meaning you could generate your own JSON data using data from sensors connected to your ESP8266 or Arduino for example (will be covering more about JSON serialization, in detail, in another instructable). So, let's get started.

Step 1: Install the ArduinoJson Library

Before you can use the ArduinoJson library, you have to make sure the library is installed on your computer. To do a quick check, head over to the library manager in the Arduino IDE (Sketch -> Include Library -> Manage Libraries...) and type "ArduinoJson" in the text box, if you see a green coloured "INSTALLED" label beside the name of the library, that means you are all good to go and you can proceed on to the next step. If you don't see the label, click on the box/division once and you will see the "Install" button. Hit install and you are all set for the next step.

Step 2: Performing a GET Request

Before we can start parsing, we need to have the JSON data in the first place and to obtain our data, we perform a GET request. A GET request, as the name suggests, gets the data for us from a particular location using a specific URL. The boilerplate code to perform the GET request can be found below. For this example, we will be performing a GET request using the http://jsonplaceholder.typicode.com/users/1 URL. You can call any API you like.

#include <ESP8266WiFi.h><br>#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

// WiFi Parameters
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }
}

void loop() {
  // Check WiFi Status
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;  //Object of class HTTPClient
    http.begin("http://jsonplaceholder.typicode.com/users/1");
    int httpCode = http.GET();
    //Check the returning code                                                                  
    if (httpCode > 0) {
      // Get the request response payload
      String payload = http.getString();
      // TODO: Parsing
    }
    http.end();   //Close connection
  }
  // Delay
  delay(60000);
}

The data that we are going to parse is contained in the payload variable. We don't actually need this variable when we are parsing our data later on.

Step 3: Using the ArduinoJson Assistant

The developers who developed the ArduinoJson library are so kind that they've even created an Assistant that writes the parser program for us using any JSON data as an input. To use the ArduinoJson assistant, you first need to know how your JSON is formatted and to do that, type in the URL that we used to perform the GET request earlier on into the browser of your choice and hit enter. Copy the JSON and head over to the ArduinoJson Assistant's web page and paste it into the text box below the label named "Input". Then scroll down to take a look at the parsing program generated by the Assistant. Copy the whole program or just a section of it.

Step 4: Completing the Code and the Result

Copying and pasting the parsing program generated by the Assistant into the boilerplate code that we used to perform a GET request earlier on would look like this:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>

// WiFi Parameters
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }
}

void loop() {
  // Check WiFi Status
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;  //Object of class HTTPClient
    http.begin("http://jsonplaceholder.typicode.com/users/1");
    int httpCode = http.GET();
    //Check the returning code                                                                  
    if (httpCode > 0) {
      // Parsing
      const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(5) + JSON_OBJECT_SIZE(8) + 370;
      DynamicJsonBuffer jsonBuffer(bufferSize);
      JsonObject& root = jsonBuffer.parseObject(http.getString());
      // Parameters
      int id = root["id"]; // 1
      const char* name = root["name"]; // "Leanne Graham"
      const char* username = root["username"]; // "Bret"
      const char* email = root["email"]; // "Sincere@april.biz"
      // Output to serial monitor
      Serial.print("Name:");
      Serial.println(name);
      Serial.print("Username:");
      Serial.println(username);
      Serial.print("Email:"); 
      Serial.println(email);
    }
    http.end();   //Close connection
  }
  // Delay
  delay(60000);
}

Since we are only interested in the name, email and username of the user, we just used a section of the parsing program generated by the assistant. You can use the serial monitor to view the output. If you don't see anything, press the reset button on your ESP8266 and *boom* you should see the output there. Note: The last line of code in the code above introduces a delay of 1 minute or 60,000 ms into the loop. This means that the API is only called once every minute. The number of times an API can be called within a specified timeframe varies and you are strongly encouraged to follow the guidelines specified by your API provider.

Share

    Recommendations

    • Big and Small Contest

      Big and Small Contest
    • First Time Author

      First Time Author
    • PCB Contest

      PCB Contest

    9 Discussions

    0
    None
    agoodchild1

    3 months ago

    Thanks for this, super helpful.

    I did have to change:
    JsonObject& root = jsonBuffer.parseObject(http.getString());
    to:
    JsonObject& root = jsonBuffer.parseObject(http.getStream());

    Not sure why but now it works great.

    0
    None
    VothneaS

    4 months ago

    Thank you very much :)

    1
    None
    bblanchon

    12 months ago

    Hi!

    Nice work on this tutorial!

    Remark that you can avoid the "payload" string by passing "http.getStream()" to "parseObject()".

    [delete]

    1 reply
    0
    None
    DavidR946bblanchon

    Reply 4 months ago

    Would be possible adapt the code to use it with https?

    0
    None
    RaíL1

    Question 6 months ago

    Thanks for the article!

    Could you please provide us the wiring diagram to connect esp8266 with arduino??

    0
    None
    UygarP

    7 months ago

    Hey, thanks a lot for the article. I'm trying to apply this to http://www.reddit.com/r/Showerthoughts/top.json (I'm trying to get the titles of posts) and for some reason nothing returns (even though httpCode returns as 301). I pasted my code here: https://paste.ofcode.org/m7MZhnr7B6LW9g74qmQrXU I used ArduinoJson assistant and changed the relevant parts in your code. I tried the suggestions in the "Why Parsing Fails" page of arduinojson.org to no avail. Can it be a memory problem, given that Reddit's JSON is considerably larger than the one in your example? I'm a beginner and still trying to wrap my mind around all of this. Thanks in advance.

    0
    None
    nikhilraghavaedris279

    Reply 11 months ago

    Hi, there seems to be a problem with the server's SSL certificate, it's either too large or they could have blocked off non-browser agents from accessing the API. I tried connecting to the service using HTTPS and the SHA1 fingerprints don't match every time I run it. The certificate size could be to blame. I will try again and will let you know if it works.