HTTP GET using ESP32 and Arduino IDE (OpenWeatherMap.org and ThingSpeak)

In this tutorial, we will learn how to make HTTP GET requests in ESP32 to commonly used APIs such as ThingSpeak and OpenWeatherMap.org.

This tutorial is adaptable with any web service/API other than the ones which we will follow here. You just have to change the server’s name and parameters accordingly to the service API documentation.

ESP32 HTTP GET request ThingSpeak and openweathermap

We have a similar guide with ESP8266:

ESP8266 NodeMCU HTTP GET with Arduino IDE (OpenWeatherMap.org and ThingSpeak)

In this tutorial, we will learn the followings:

HTTP GET Request

The Hypertext Transfer Protocol (HTTP) works as a request-response protocol between a server and a client. It enables smooth communication between them. The two most widely used HTTP methods are GET and POST. Through GET, data is requested from a specified resource whereas POST sends data to create a resource.

Recommended Reading: ESP32 HTTP POST using Arduino IDE (ThingSpeak and IFTTT)

In this user guide, we will focus on the GET request in HTTP. GET is commonly used to request data and retrieves it. We will use GET requests to obtain values (JSON object) from OpenWeatherMap.org. Moreover, we will also show you how to use GET requests to update values to ThingSpeak API. These requests are highly favorable to use when the data in question does not have any security concerns(passwords) or does not consist of images.

An example of an HTTP GET request is as follows:

GET/UpdatingSensorReadings?sensor_reading1=value1&sensor_reading2=value2

GET Requests Features

Data is visible in the browser URL and not sent in the message body

  • The length of the browser URL is limited to approximately 255 characters
  • Only the string data type is allowed
  • Data remains in the browser history hence it is not secure
  • Extremely easy to bookmark the data
  • Only used to retrieve data from the address bar
  • Data is easily stored and cacheable
  • Performance is significantly greater than POST due to the simplified nature of the request

HTTP GET Request Examples

We will learn how to request JSON data with HTTP GET request performs with ESP32 development board to OpenWeatherMap.org to access the weather parameters of our city. Additionally, we will also update readings by making an HTTP GET request performs with ESP32 to ThingSpeak

Working Process

  1. Firstly, the client (ESP32) will submit an HTTP request to the server (ThingSpeak/OpenWeatherMap.org).
  2. Secondly, the server will return a response to the client.
  3. Lastly, the response will be received which will contain the status information and the requested content of the request.
ESP32 HTTP  project overview

Prerequisites

We will program our ESP32 board in Arduino IDE. Thus, you should have the latest version of Arduino IDE. Additionally, you also need to install the ESP32 plugin. If your IDE does not have the plugins installed you can visit the link below:

• Installing ESP32 library in Arduino IDE and upload code.

Installing Arduino_JSON Library

You will also have to install the Arduino_JSON library as we will be dealing with JSON script. Open your Arduino Library Manager by clicking Sketch > Include Library > Manage Libraries. Type ‘Arduino_JSON’ in the search tab and press enter. Install the library which is highlighted below.

HTTP GET in Arduino_JSON library
Arduino_JSON Library

ESP32 HTTP GET in OpenWeatherMap.org (Acquiring JSON Object)

First, we will look at how to use the OpenWeatherMap.org API to request data regarding the weather parameters of a city. OpenWeatherMap is an online webpage that gives the user information about the weather parameters for any set location. These include temperature, precipitation, humidity, pressure, wind and even forecasts to name a few. It has accurate and fast APIs which performs this functionality. In our project, we will be requesting the weather forecast for our set location through this API.

Our ESP32 (client) will make an HTTP GET request to the server which is OpenWeatherMap API in this case. As a response, we will receive a string consisting of the JSON object with details regarding the weather for our set location.

HTTP GET OpenWeatherMap working process
Working Process

Setting up OpenWeatherMap API

Before we proceed further, first we have to set up an account in the OpenWeatherMap.

Go to the following webpage: https://openweathermap.org/appid/ to open the API. You will see the following window when the web page loads. Click ‘here’ as shown in the red box to sign up.

OpenWeatherMap signup page

You will be shown a page where you will have to add your username, password and some other details to create your account. Complete all the details, tick the relevant fields and then click on the ‘Create Account’ button.

OpenWeatherMap Create account

The webpage will send a confirmation link to the email address you provided. After confirmation, the following appears:

OpenWeatherMap get API key

Now, go to the ‘API keys’ tab and the following window will appear, carrying your unique API key. Likewise, you can go to https://home.openweathermap.org/api_keys to access your unique API key.

HTTP GET OpenWeatherMap API key

The key in the grey box is your unique key which we will be using later. Save this key and for security reasons do not share it with anyone.

Obtaining the Weather Update

Now as we have set up our account with OpenWeatherMap and have also obtained our key let see look into how to get weather update for a location of our choice. You will have to type the following URL in a new tab:

http://api.openweathermap.org/data/2.5/weather?q=city_code,
country_code&APPID=your_API_key

There are three parameters which we are specifying in the URL. First ‘q=city_code’ is the name of the city whose weather update you are acquiring. Second, ‘country_code’ specifies the two-digit country code of the city you specified before. Third, you will enter your unique API key which we just saved before.
Let us take a simple example. For example, if we want to know the weather update of the city Lahore in Pakistan, we will enter the following URL:

http://api.openweathermap.org/data/2.5/weather?q=Lahore,
PK&APPID=68de4b6c1e6fe13a39b55bf36b42****

Copy the following URL in a new window and the following parameters pop up. This is the current weather update of Lahore, Pakistan (same time report).

{“coord”:{“lon”:74.3436,”lat”:31.5497},”weather”:[{“id”:800,”main”:”Clear”,”description”:”clear sky”,”icon”:”01d”}],”base”:”stations”,”main”:{“temp”:307.14,”feels_like”:308.07,”temp_min”:306.21,”temp_max”:307.14,”pressure”:1003,”humidity”:38},”visibility”:6000,”wind”:{“speed”:6.17,”deg”:70},”clouds”:{“all”:5},”dt”:1622811705,”sys”:{“type”:1,”id”:7585,”country”:”PK”,”sunrise”:1622764679,”sunset”:1622815452},”timezone”:18000,”id”:1172451,”name”:”Lahore”,”cod”:200}

As you see above, the information is given in JSON script. Now we will decipher this data in an easily readable format through our Arduino Sketch.

Arduino Sketch

Open your Arduino IDE and go to File > New to open a new file. Copy the code given below in that file. For this code to work with your ESP32 board you will have to replace the following with your parameters in the program code:

  • Network credentials
  • API key
  • City and Country code
  • The server (domain name) for the URL path
#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";

String my_Api_Key = "68de4b6c1e6fe13a39b55bf36b42****";

String my_city = "Lahore"; //specify your city
String my_country_code = "PK"; //specify your country code

unsigned long last_time = 0;
unsigned long timer_delay = 10000;

String json_array;

void setup() {
  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI...");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("First set of readings will appear after 10 seconds");
}

void loop() {
  
  if ((millis() – last_time) > timer_delay) {
  
    if(WiFi.status()== WL_CONNECTED){
      String server = "http://api.openweathermap.org/data/2.5/weather?q=" + my_city + "," + my_country_code + "&APPID=" + my_Api_Key;
      
      json_array = GET_Request(server.c_str());
      Serial.println(json_array);
      JSONVar my_obj = JSON.parse(json_array);
  
      if (JSON.typeof(my_obj) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(my_obj);
      Serial.print("Temperature: ");
      Serial.println(my_obj["main"]["temp"]);
      Serial.print("Pressure: ");
      Serial.println(my_obj["main"]["pressure"]);
      Serial.print("Humidity: ");
      Serial.println(my_obj["main"]["humidity"]);
      Serial.print("Wind Speed: ");
      Serial.println(my_obj["wind"]["speed"]);
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    last_time = millis();
  }
}

String GET_Request(const char* server) {
  HTTPClient http;    
  http.begin(server);
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  http.end();

  return payload;
}

How the Code Works?

Now, let us understand how each part of the code works.

Importing Libraries

Firstly, we will import the relevant libraries which are necessary for this project. We are using three libraries: WiFi.h, HTTPClient.h and Arduino_JSON.h
WiFi.h library is used to connect our ESP32 module with the local WIFI network. Also, the HTTPClient.h will help us to make the HTTP GET requests easily and the Arduino_JSON.h will be used for the JSON script.

#include <WiFi.h>
#include <HTTPClient.h>
#include <Arduino_JSON.h>

Setting Network Credentials

Next, we will create two global variables to save the SSID and the password values. You have to replace both of them with your network credentials to successfully connect with your router.

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";

Configuring your API key

Now, we will create a string variable to hold our unique API key. This is the key that we saved previously.

String my_Api_Key = "68de4b6c1e6fe13a39b55bf36b42****";

Setting City and Country Code

Next, we will create two string variables. The first variable will hold the name of the city whose weather update we want. The second variable will hold the two-digit country code for that particular city. In our case, we will access the current weather parameters for the city Lahore located in Pakistan (PK).

String my_city = "Lahore"; //specify your city
String my_country_code = "PK"; //specify your country code

Setup() function

Inside the setup() function, we will open a serial connection at a baud rate of 115200.

Serial.begin(115200);

Next, we will connect our ESP32 board with the local network whose network credentials we already specified above using the WiFi.begin() function. After the connection will be established, the IP address of the ESP32 board will get printed on the serial monitor.

WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI...");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("First set of readings will appear after 10 seconds");

loop() function

Inside the infinite loop() function we will make the HTTP POST request.
We will create another variable named ‘server’ which will hold the URL path of the HTTP GET request which we will use.

String server = "http://api.openweathermap.org/data/2.5/weather?q=" + my_city + "," + my_country_code + "&APPID=" + my_Api_Key;

After every 10 seconds, the ESP32 module will make a request to the API by calling the GET_Request() function.

 json_array = GET_Request(server.c_str());
 Serial.println(json_array);

The following section of code defines the Get_Request() function. This function takes in the server URL as the parameter. We then create an instance of HTTPClient library called ‘http’ and request the API for a weather update. This information (‘payload’) is saved in string data type with a JSON object. The JSON object contains the complete information regarding the weather parameters for your set location.

String GET_Request(const char* server) {
  HTTPClient http;    
  http.begin(server);
  int httpResponseCode = http.GET();
  
  String payload = "{}"; 
  
  if (httpResponseCode>0) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode);
  }
  http.end();

  return payload;
}

The following section of code will help us to transform the JSON script into a readable format and displays it on our serial monitor. This data will get stored in the string variable ‘json_array’. We will then create an object ‘my_obj’ of JSONVAR and use it to access individual temperature, pressure, humidity and wind speed.

JSONVar my_obj = JSON.parse(json_array);
  
      if (JSON.typeof(my_obj) == "undefined") {
        Serial.println("Parsing input failed!");
        return;
      }
    
      Serial.print("JSON object = ");
      Serial.println(my_obj);
      Serial.print("Temperature: ");
      Serial.println(my_obj["main"]["temp"]);
      Serial.print("Pressure: ");
      Serial.println(my_obj["main"]["pressure"]);
      Serial.print("Humidity: ");
      Serial.println(my_obj["main"]["humidity"]);
      Serial.print("Wind Speed: ");
      Serial.println(my_obj["wind"]["speed"]);
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    last_time = millis();
  }

Demonstration

After you have uploaded your code to the ESP32 development board press its ENABLE button.

ESP32 enable reset button
Press ENABLE Button

In your Arduino IDE, open up the serial monitor and you will be able to see the IP address of your ESP module. Additionally, the time delay message will also be displayed.
Now, if a successful client-server communication took place, then the server would send the response code 200. This code corresponds to ‘OK’ which means successful. This will get printed on your Serial Monitor.
Then you will receive the weather update for your city in the form of JSON data as shown below:

HTTP GET OpenWeatherMap Serial Monitor demo1
Serial Monitor Display

This data also gets decoded into individual temperature, pressure, humidity and wind speed values as seen in the red rectangle. After every 10 seconds, you will receive a new set of readings for all the parameters.

HTTP GET OpenWeatherMap Serial Monitor demo2
Serial Monitor Display

ESP32 HTTP GET in ThingSpeak (Updating Values)

Now, we will look at how to make a request through our ESP32 board to ThingSpeak to update some random values. ThingSpeak is an open-source API that is used to store or retrieve data using HTTP or MQTT protocol. This takes place over the Internet or through the LAN. We will use this API to publish random values for simplicity purposes. For practicality, the same procedure can be used to publish sensor values e.g., data readings from the BME280 temperature sensor integrated with the ESP32 board.

Our ESP32 (client) will make an HTTP GET request to send different random values to the server which is ThingSpeak in this case. We will be able to view the different values in the ThingSpeak dashboard in the form of a graph that will keep updating.

HTTP GET ThingSpeak working process
Working Process

Using ThingSpeak API

ThingSpeak API is free to use but we will have to create a MathWorks Account.

First go to the following website: https://thingspeak.com/
The following window will appear. Click on the ‘Get Started for Free’ button.

ESP32 HTTP  ThingSpeak get started

Now you will be redirected to the account window. If you already have an existing MathWorks account you can use that to log in. Otherwise, you will have to create a new one. Click ‘Create One!’ to make a new MathWorks account. When you have successfully signed in you will receive the following notification:

ESP32 HTTP ThingSpeak account

Click ‘OK’.

ESP32 HTTP ThingSpeak account successful

Now go to ‘New Channel’.

ESP32 HTTP ThingSpeak new channel

After creating your channel go to the API key tab and click it. You will now be able to access your unique API key. Save it and keep it secure as you will need it later in the program code.

HTTP GET ThingSpeak API key

ThingSpeak Arduino Sketch

Open your Arduino IDE and go to File > New to open a new file. Copy the code given below in that file. This code will work with your ESP32 board. You just have to replace the network credentials and your API key.

#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";


String server = "http://api.thingspeak.com/update?api_key=Your_API_Key";

unsigned long last_time = 0;
unsigned long timer_delay = 10000;

void setup() {
  Serial.begin(115200); 

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI..");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("The first reading will display after 10 seconds");
  
  // Random number generator
  randomSeed(analogRead(23));
}

void loop() {
  if ((millis() – last_time) > timer_delay) {
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      String server_path = server + "&field1=" + String(random(50));
      http.begin(server_path.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String data = http.getString();
        Serial.println(data);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
  
      http.end();
    }
    else {
      Serial.println("WiFi is Disconnected!");
    }
    last_time = millis();
  }
}

How the Code Works?

Now, let us understand how each part of the code works.

Importing Libraries

Firstly, we will import the relevant libraries which are necessary for this project. We are using two libraries: WiFi.h and HTTPClient.h
WiFi.h library is used to connect our ESP32 module with the local WIFI network. Also, the HTTPClient.h will help us to make the HTTP GET requests easily.

#include <WiFi.h>
#include <HTTPClient.h>

Setting Network Credentials

Next, we will create two global variables to save the SSID and the password values. You have to replace both of them with your network credentials to successfully connect with your router.

const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";

Setting server

After importing all the necessary libraries and configuring your network credentials you will have to give your server’s name. We will create a string variable and call it ‘server’. We will include the API key that we saved before in our server as shown below.

String server = "http://api.thingspeak.com/update?api_key=Your_API_Key";

Make sure to replace your API key in the place specified. For example, our key is S7JL1OFE7U******

Hence, we will specify the server as:

String server = "http://api.thingspeak.com/update?api_key= S7JL1OFE7U******";

Setup() function

Inside the setup() function, we will open a serial connection at a baud rate of 115200.

Serial.begin(115200);

Moreover, we will connect our ESP32 board with the local network whose network credentials we already specified above using the WiFi.begin() function. After the connection will be established, the IP address of the ESP32 board will get printed on the serial monitor.

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WIFI..");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("The first reading will display after 10 seconds");

We will use the randomSeed() function to initiate a random number from a given starting point which is known as the seed. This will be set to analogRead(23) which we are using as an argument inside the function. The GPIO23 is unconnected thus through analogRead(23) it will read the value of the unconnected analog input and then use it as a starting point.

randomSeed(analogRead(23));

loop() function

Inside the infinite loop() function we will make the HTTP GET request. After every 10 seconds, a random number will be sent from the client to the server (ESP32 to ThingSpeak) through the GET request. Inside the ‘server_path’ we will send our server which we configured above with an API key and a random number between 0-49. The server path will hold the domain name for the GET request.

if ((millis() – last_time) > timer_delay) {
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      String server_path = server + "&field1=" + String(random(50));
      http.begin(server_path.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();

As an example, we will show you how to make a GET request where we will be updating a value. The ESP32 will make an HTTP GET request in a URL shown below:

http://api.thingspeak.com/update?api_key=Your_API_Key&field1=12

In the above GET request, we are updating the field1 with a new value which is 12.

The following section of the code will print the response code and the random number in the serial monitor.

if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String data = http.getString();
        Serial.println(data);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
  
      http.end();
    }
 

Demonstration

After you have uploaded your code to the ESP32 development board press its ENABLE button.

ESP32 enable reset button
Press ENABLE Button

In your Arduino IDE, open up the serial monitor and you will be able to see the IP address of your ESP module. Additionally, the time delay message will also be displayed. Now, if a successful client-server communication took place, then the server would send the response code 200. This code corresponds to ‘OK’ which means successful. This will get printed on your Serial Monitor. You can also view the random number being displayed after the response code.

HTTP GET ThingSpeak serial monitor demo
Serial Monitor display

Next, open the ThingSpeak API and you will be able to see different random values updating after 10 seconds in your dashboard.

HTTP GET ThingSpeak dashboard demo
Random Values updating on Dashboard

Conclusion

To conclude it all, we learnt how to make HTTP GET requests from our ESP32 module to ThingSpeak (updating values) and OpenWeatherMap.org (weather review).

2 thoughts on “HTTP GET using ESP32 and Arduino IDE (OpenWeatherMap.org and ThingSpeak)”

  1. Both of these worked after I replaced the minus operator in the line:
    if ((millis() – last_time) > timer_delay) {

    Also, why are the temperature #s so high? It’s 303.14 in your example. I got similar #s.

    In the ThinkSpeak example, are the random #s plotted the same #s shown in the serial output? It doesn’t seem so.

    Reply

Leave a Comment