Arduino TutorialsESP8266 Projects

Retrieve & decode JSON with ArduinoJson

Decode / parse JSON with ESP8266 or ESP32

If you are on the internet with your ESP8266 or ESP32*, there is a reason for that. You may want to retrieve data from an API and use it in your project. In this tutorial you will learn how to load data in JSON format and decode (or parse) it using the ArduinoJson library.

Here we use an ESP8266* – but with a few adjustments in the code you can also use any other microcontroller you can get on the internet with. In this tutorial on Pollux Labs you will learn how to connect your ESP8266 to the internet.

Then you will contact an API and download JSON data containing the current number of people in space. You will decode (or parse) this data locally and display it on your serial monitor.

The ArduinoJson Library

Before you can start, you need the latest version of the ArduinoJson library. This is a really handy extension that does most of the work with JSON for you.

So open your library manager in the Arduino IDE and search for ArduinoJson there. Install the latest version.

ArduinoJson library

Now include the library at the top of your sketch:

#include <ArduinoJson.h>

The API Call

To find out how many astronauts are in space right now, we query an API from open-notify.org – at the following URL

  http://api.open-notify.org/astros.json

If you copy this URL and open it in your browser, you will already see the raw data in JSON format. Right at the beginning you find “number” and behind it the current number of astronauts in space. Today – August 2, 2020 – this is 5.

To get this string on your ESP8266, you need the following code:

HTTPClient http; //Instance of HTTPClient
http.begin("http://api.open-notify.org/astros.json"); //URL for the request
int httpCode = http.GET(); //Answer of the Server
    if (httpCode == 200) { 
      String payload = http.getString(); //Save data in variable
      }

Now the raw data you loaded from the API is in the variable payload. That’s fine, but to be able to process this data – e.g. to show the current number of astronauts on a display – you first have to decode it. And here again the library ArduinoJson comes into play.

Decoding with ArduinoJson

With this library you can grab specific data from the JSON string (the raw data) and store it in variables of your choice. However, in order for it to do its job, it first needs to know how large the raw data is in order to reserve enough memory for itself.

There is a practical assistant for this. First open the URL of the API and copy all characters with Ctrl + A and Ctrl + C.

Then open the ArduinoJson Assistant and paste it into the left field.

Afterwards you will see the section Parsing program below the input field – here you will find all commands and information you need now. In the first line you can see the amount of memory in the constant capacity. In our case this is

const size_t capacity = JSON_ARRAY_SIZE(5) + 5*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;

Note: If the JSON string gets longer (e.g. because a whole bunch of astronauts are going into space), you will need more memory for ArduinoJson. Otherwise you would get a corresponding error message.

The next command you have to adjust now is this one:

deserializeJson(doc, payload);

Here you find the variable payload, which contains the raw data from the API. The function deserializeJson() decodes the raw data.

Then you can assign them to your own variables. We limit ourselves here to the number of astronauts in space, so we only need one variable. The ArduinoJson Assistant already suggests one, whose name is based on the key (“number”) in the JSON data.

int number = doc["number"];

To check if everything works, you now output this variable to your serial monitor:

Serial.println(number);

We have a 5 standing here today – what number do you have? Here is the whole sketch for copying and reuse:

#include <ESP8266WiFi.h> //WiFI
#include <ArduinoJson.h> //JSON
#include <ESP8266HTTPClient.h> //API request

// WIFI-Zugangsdaten
const char* ssid = "NETWORK";
const char* password =  "PASSWORD";

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password); //Connect to WiFi

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  delay(1000);
  Serial.println("Hello, world!");
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {

    HTTPClient http; //Instance of HTTPClient
    http.begin("http://api.open-notify.org/astros.json"); //URL for request
    int httpCode = http.GET(); //Answer of the server

    if (httpCode == 200) {
      String payload = http.getString(); //Save data in variable
      const size_t capacity = JSON_ARRAY_SIZE(5) + 5 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
      DynamicJsonDocument doc(capacity);
      deserializeJson(doc, payload);
      int number = doc["number"];
      Serial.println(number);
    }
  }
  delay(10000);
}

What next?

Now that you know how to access and use data in JSON format, you have a whole new world of possibilities. For example, how about a LEGO ISS that lights up when the real ISS flies over it?

You may also like

Comments are closed.