ESP32 Part 2 - Wireless

E10. HTTP Client, JSON and Cloud APIs

Ask a free weather website for today's temperature, print the reply, then pick the temperature out of the JSON.

Estimated time 4 hours

Learning outcomes

  • Explain the difference between a web server and a web client
  • Fetch data from a website and check the status code
  • Read a JSON reply and find a value inside it
  • Pick out one number with ArduinoJson

Parts and preparation

ESP32 DevKit, USB, Wi-Fi with internet access. Library: ArduinoJson by Benoit Blanchon. Optional for the challenge: LED + resistor on GPIO 2.

Before power: inspect wiring, confirm supply voltage and ensure all connected circuits share GND.

Libraries for this lesson

In Arduino IDE 2 open Tools → Manage Libraries…. Search by the Library Manager name and install the package by the exact author below. Similar names from other authors can use different APIs and will break the example.

IncludeLibrary Manager nameAuthorInstall note
WiFi.hWiFiEspressifBuilt into the esp32 Arduino core.
HTTPClient.hHTTPClientEspressifBuilt into the esp32 Arduino core.
ArduinoJson.hArduinoJsonBenoit BlanchonInstall ArduinoJson by Benoit Blanchon via Library Manager.

What you will do

Open-Meteo is a free weather website that answers in a format called JSON. It needs no account.

Sketch 1 asks for the current temperature and prints the whole reply. Sketch 2 picks the temperature number out of the reply.

ESP32 HTTP GET JSON parse to control an LED
Ask a website, get JSON back, pick out the value you need.

Server and client

In ESP32 Lesson 09 the ESP32 was the server: your browser asked it for a page. Now the ESP32 is the client: it asks another website, just like a browser does.

Status codes

Every reply starts with a number that says how it went. Only read the reply when the code is 200.

CodeMeaning
200OK - the reply holds your data
404Not found - check the web address
Below 0 (e.g. -1)No connection - check Wi-Fi and the address

Reading JSON

JSON is text made of names and values inside curly brackets. Here is a shortened Open-Meteo reply:

{ "latitude": 51.5, "current": { "time": "2026-10-07T09:45", "temperature_2m": 14.2 } }

The temperature sits inside current. With ArduinoJson you write the path in square brackets: doc["current"]["temperature_2m"] gives 14.2.

More on JSON: ESP32 Reference - JSON for IoT.

You wantYou write
latitudedoc["latitude"]
temperature_2m inside currentdoc["current"]["temperature_2m"]

Your location

The web address in the sketches asks about London (latitude 51.5, longitude -0.12). Change the two numbers to your own town - search the web for your town's latitude and longitude.

http, not https

Most websites use https, which needs extra security setup on the ESP32. Open-Meteo also answers on plain http, so this lesson can focus on JSON.

Wiring and safe build sequence

  1. USB only
  2. Wi-Fi network with internet access
  3. Challenge only: GPIO 2 -> 220-330 ohm -> LED -> GND
Power rule: switch off before moving wires. Arduino I/O pins are control signals; high-current loads require a driver and suitable external supply.

Worked sketch 1: Ask a website for the weather

Download .ino

What this sketch is for: Upload and read the reply in Serial. Press EN (reset) to ask again.

#include <WiFi.h>                         // the Wi-Fi commands
#include <HTTPClient.h>                   // the commands for asking websites

String ssid = "YOUR_WIFI_SSID";           // your Wi-Fi network name
String password = "YOUR_WIFI_PASSWORD";   // your Wi-Fi password

// the question: current temperature at latitude 51.5, longitude -0.12 (London)
String url = "http://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12&current=temperature_2m";

void setup() {                            // runs once
  Serial.begin(115200);                   // start Serial at the ESP32 speed

  WiFi.begin(ssid, password);             // start joining the network
  Serial.print("Connecting");             // tell the user we are trying
  while (WiFi.status() != WL_CONNECTED) { // repeat until we have joined
    delay(500);                           // wait half a second
    Serial.print(".");                    // print a dot each time
  }
  Serial.println(" connected");           // we are on the network

  HTTPClient http;                        // something that can ask websites
  http.begin(url);                        // the address to ask
  int code = http.GET();                  // ask, and keep the status code
  Serial.print("Status code: ");          // a label
  Serial.println(code);                   // 200 means OK
  Serial.println(http.getString());       // print the whole reply
  http.end();                             // finished with this request
}

void loop() {                             // nothing to repeat in this sketch
}

How the code works

  1. http.GET() sends the question and waits for the reply.
  2. Look for temperature_2m inside "current" in the printed reply - sketch 2 picks it out.

Worked sketch 2: Pick out the temperature

Download .ino

What this sketch is for: Same question, but now ArduinoJson finds the temperature in the reply. Install ArduinoJson by Benoit Blanchon first.

#include <WiFi.h>                         // the Wi-Fi commands
#include <HTTPClient.h>                   // the commands for asking websites
#include <ArduinoJson.h>                  // the commands for reading JSON

String ssid = "YOUR_WIFI_SSID";           // your Wi-Fi network name
String password = "YOUR_WIFI_PASSWORD";   // your Wi-Fi password

// the question: current temperature at latitude 51.5, longitude -0.12 (London)
String url = "http://api.open-meteo.com/v1/forecast?latitude=51.5&longitude=-0.12&current=temperature_2m";

void setup() {                            // runs once
  Serial.begin(115200);                   // start Serial at the ESP32 speed

  WiFi.begin(ssid, password);             // start joining the network
  Serial.print("Connecting");             // tell the user we are trying
  while (WiFi.status() != WL_CONNECTED) { // repeat until we have joined
    delay(500);                           // wait half a second
    Serial.print(".");                    // print a dot each time
  }
  Serial.println(" connected");           // we are on the network

  HTTPClient http;                        // something that can ask websites
  http.begin(url);                        // the address to ask
  int code = http.GET();                  // ask, and keep the status code

  if (code == 200) {                      // only read the reply if it is OK
    JsonDocument doc;                     // a place to keep the decoded JSON
    deserializeJson(doc, http.getString()); // decode the reply into doc
    float temperature = doc["current"]["temperature_2m"]; // find the number
    Serial.print("Temperature: ");        // a label
    Serial.print(temperature);            // the number, e.g. 14.20
    Serial.println(" C");                 // the unit
  } else {                                // anything else went wrong
    Serial.print("Request failed, code "); // say so
    Serial.println(code);                 // and show the code
  }

  http.end();                             // finished with this request
}

void loop() {                             // nothing to repeat in this sketch
}

How the code works

  1. deserializeJson turns the reply text into something you can look inside.
  2. doc["current"]["temperature_2m"] follows the path: inside current, find temperature_2m.
  3. Change latitude and longitude in the url line for your own town.

Test and record evidence

Expected result: Sketch 1: Status code: 200, then one long line of JSON that includes "temperature_2m". Sketch 2: Temperature: followed by today's temperature in Celsius.

Practical evidence checklist

Common faults and checks
  • Status code -1 or another negative number: check Wi-Fi has internet, and the url is typed exactly.
  • ArduinoJson.h not found: install ArduinoJson by Benoit Blanchon in Library Manager.
  • Temperature: 0.00: the path is wrong - compare it with the JSON printed by sketch 1.
  • School or office network blocks it: try a phone hotspot.
Challenge (extension - optional): Add an LED on GPIO 2 and turn it on when the temperature is 15 C or more. Harder: move the request into loop() and ask again every 60 seconds.

Check your understanding

Q1. In this lesson, is the ESP32 a server or a client?

Show answer

A client - it asks another website.

Q2. What status code means OK?

Show answer

200.

Q3. Why check the status code before reading the reply?

Show answer

If the request failed, there is no JSON to read.

Q4. What is JSON?

Show answer

Text made of names and values, used to send data between devices and websites.

Q5. How do you read temperature_2m inside current?

Show answer

doc["current"]["temperature_2m"].

Q6. Which library reads JSON?

Show answer

ArduinoJson by Benoit Blanchon.

Q7. Why does this lesson use http and not https?

Show answer

https needs extra security setup on the ESP32.