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

In this tutorial, we will learn how to make HTTP GET requests in ESP8266 NodeMCU to commonly used APIs such as ThingSpeak and OpenWeatherMap.org. Firstly, we will see how to decode JSON format data received from OpenWeatherMap.org. Secondly, we will learn to update sensor values to Thingspeak with HTTP Get request.

ESP8266 NodeMCU HTTP GET request with Arduino IDE ThingSpeak and openweathermap

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.

In this tutorial, we will learn the following:

  • HTTP GET Request Introduction
  • HTTP GET Request Examples
  • ESP8266 HTTP GET to OpenWeatherMap.org (Acquiring JSON Object)
  • ESP8266 HTTP GET to ThingSpeak API

We have a similar guide with ESP32:

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

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.

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 with ESP8266 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 with ESP8266 to ThingSpeak

Working Process

  1. Firstly, the client (ESP8266) 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 ESP8266 board in Arduino IDE. Thus, you should have the latest version of Arduino IDE. Additionally, you also need to install the ESP8266 plugin. If your IDE does not have the plugin installed you can visit the link below:

Installing ESP8266 library in Arduino IDE

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

ESP8266 HTTP GET from 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 ESP8266 (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 ESP8266 OpeanWeatherMap 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”:”01n”}],”base”:”stations”,”main”:{“temp”:299.14,”feels_like”:299.14,”temp_min”:296.21,”temp_max”:299.14,”pressure”:1004,”humidity”:38},”visibility”:7000,”wind”:{“speed”:4.63,”deg”:330},”clouds”:{“all”:0},”dt”:1635165094,”sys”:{“type”:1,”id”:7585,”country”:”PK”,”sunrise”:1635124368,”sunset”:1635164421},”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 ESP8266 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 <ESP8266WiFi.h>
#include <ESP8266HTTPClient.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;
WiFiClient wifiClient;

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(wifiClient,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: ESP8266WiFi.h, ESP8266HTTPClient.h and Arduino_JSON.h
ESP8266WiFi.h library is used to connect our ESP8266 module with the local WIFI network. Also, the ESP8266HTTPClient.h will help us to make the HTTP GET requests easily and the Arduino_JSON.h will be used for the JSON script.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.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 ESP8266 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 ESP8266 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 GET 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 ESP8266 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(wifiClient,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 display 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 ESP8266 development board press its RST button.

ESP8266 NodeMCU reset button
Press RST 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 ESP8266 OpeanWeatherMap 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 ESP8266 OpeanWeatherMap Serial monitor demo2
Serial Monitor Display

ESP8266 HTTP GET from ThingSpeak (Updating Values)

Now, we will look at how to make a request through our ESP8266 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 ESP8266 board.

Our ESP8266 (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 ESP8266 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 ESP8266 board. You just have to replace the network credentials and your API key.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.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;
WiFiClient wifiClient;

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(wifiClient,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: ESP8266WiFi.h and ESP8266HTTPClient.h
ESP8266WiFi.h library is used to connect our ESP8266 module with the local WIFI network. Also, the ESP8266HTTPClient.h will help us to make the HTTP GET requests easily.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.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 ESP8266 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 ESP8266 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 (ESP8266 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 ESP8266 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 ESP8266 development board press its RST button.

ESP8266 NodeMCU reset button
Press RST 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 ESP8266 Thinkspeak 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 ESP8266 Thinkspeak dashboard demo
Random Values updating on Dashboard

Conclusion

To conclude it all, we have learned how to make HTTP GET requests with ESP8266 NodeMCU module to ThingSpeak (updating values) and OpenWeatherMap.org (weather review).

2 thoughts on “ESP8266 NodeMCU HTTP GET with Arduino IDE (OpenWeatherMap.org and ThingSpeak)”

  1. Hi!
    I’m using webmos D1R1 which contains Esp8266EX in it, itself.
    I run the code as same as yours, even the city name.
    However, it says
    example:37:17: error: extended character – is not valid in an identifierexit status 1extended character – is not valid in an identifier
    Could u help me to find what is the problem?
    Thank you.

    Reply

Leave a Comment