In this tutorial, we will learn how to make HTTP POST requests with ESP8266 NodeMCU and Arduino IDE to commonly used APIs such as ThingSpeak and IFTTT.
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.
We have a similar guide with ESP32:
ESP32 HTTP POST using Arduino IDE (ThingSpeak and IFTTT)
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
HTTP POST 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 POST request in HTTP. It is used to send information from the client to the server to create or update a resource. This information is included in the request body of the HTTP request. For example:
POST /Updating Sensor Readings HTTP/1.1 Host: electronicshub.com sensor_reading1=value1&sensor_reading2=value2
Some Key Features of POST Requests
- Having no restrictions on data length as the data is submitted through the body of the HTTP
- Does not get saved in your browser history hence it is secure
- is not cached
- Values are not visible in the browser URL
- Obtains input from the request body and query string
- Different data types can be included
- Cannot be bookmarked
- Data is kept private
Project Overview
We will learn how to send JSON object and URL encoded data from our ESP8266 development board to two APIS namely:
Working Process
- Firstly, the client (ESP8266) will submit an HTTP request to the server (ThingSpeak/IFTTT).
- Secondly, the server will return a response to the client.
- Lastly, the response will be received which will contain the status information and the requested content of the request.
ESP8266 NodeMCU HTTP POST Request to ThingSpeak
First, we will look at how to send HTTP POST data in ESP8266 to ThingSpeak. 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 POST request to send different random values to the server which is ThingSpeak in this case. We will send both types of data inside the HTTP POST request body: URL encoded and JSON script.
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.
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:
Click ‘OK’.
Now go to ‘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.
ThingSpeak Example 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 = "ENTER_YOUR_WIFI_NAME";
const char* password = "ENTER_YOUR_PASSWORD";
// Domain Name with full URL Path for HTTP POST Request
const char* server = "http://api.thingspeak.com/update";
String my_Api_key = "EnterYourApiKey";
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("After 10 seconds the first reading will be displayed");
//initialize a random number
randomSeed(analogRead(23));
}
void loop() {
//Send an HTTP POST request every 10 seconds
if ((millis()-last_time) > timer_delay) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(wifiClient,server);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Data to send with HTTP POST
String httpRequestData = "api_key=" + my_Api_key + "&field1=" + String(random(50));
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
/*
http.addHeader("Content-Type", "application/json");
// JSON data to send with HTTP POST
String httpRequestData = "{\"api_key\":\"" + my_Api_Key + "\",\"field1\":\"" + String(random(50)) + "\"}";
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);*/
Serial.print("HTTP Response code is: ");
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 POST 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 = "ENTER_YOUR_WIFI_NAME";
const char* password = "ENTER_YOUR_PASSWORD";
Setting Server
Also, we will create another global variable named ‘server’ which will hold the URL path of the HTTP POST request which we will use.
const char* server = "http://api.thingspeak.com/update";
Configuring your API key
Now, we will create a string variable to hold your unique API key. This is the key that you saved previously when creating a new channel in ThingSpeak.
String my_Api_key = "EnterYourApiKey";
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");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("After 10 seconds the first reading will be displayed");
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 POST request. After every 10 seconds, the URL encoded data will be sent from the client to the server (ESP8266 to ThingSpeak).
if ((millis()-last_time) > timer_delay) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(wifiClient,server);
The following section of code shows the URL encoded data being sent. Inside the message body we will send our API key and a random number between 0-49.
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String httpRequestData = "api_key=" + my_Api_key + "&field1=" + String(random(50));
int httpResponseCode = http.POST(httpRequestData);
If you want to send the data in JSON format then uncomment the following block of code and comment on the one above it.
/* http.addHeader("Content-Type", "application/json");
String httpRequestData = "{\"api_key\":\"" + my_Api_Key + "\",\"field1\":\"" + String(random(50)) + "\"}";
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
*/
Difference between URL encoded message and JSON format
Example URL encoded POST:
POST /update HTTP/1.1
Host: api.thingspeak.com
api_key=api&field1=12
Content-Type: application/x-www-form-urlencoded
Example JSON POST:
POST /update HTTP/1.1
Host: api.thingspeak.com
{api_key: "api", field1: 12}
Content-Type: application/json
Displaying Response Code
The following lines of code will print the server response code on our serial monitor.
Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);
Demonstration
After you have uploaded your code to the ESP8266 development board press its 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.
Next, open the ThingSpeak API and you will be able to see different random values updating after 10 seconds in your dashboard.
ESP8266 NodeMCU HTTP POST Request to IFTTT
Now, we will look at how to send HTTP POST data in ESP8266 to IFFT. In return, we will trigger the IFTTT API to send us email notifications regarding our data.
IFTTT means ‘If this, then that.’ It is an open-source service that gives the user the freedom to program a response to an event according to their likes. We can create an applet which are chains of conditional statements by a combination of several app services and add triggering parameters.
In this project whenever our ESP8266 will make a request to the server, the IFTTT applet will send three random values to our email. In practical situations, these values can be readings from a sensor.
To work with this web service, we will have to follow a series of steps to ensure the proper functionality.
Creating an Account
Although the IFTTT service is free to use, we will have to create an account. First go to the following website: https://ifttt.com/
The following window will appear. Click on the ‘Get Started’ button.
The following window will appear. You can select any one from these three options (Apple, Google or Facebook) to connect. Or you can simply ‘sign up’ with your own given email. We will be following this scheme.
Click the ‘sign up’ tag. You will see the following window pop up. Enter your email address and password to start working in IFTTT. This whole process is free of cost for the first three applets.
Creating an Applet:
After you have created your account, we will be directed to the page where we will create our applet. Click on ‘Create.’
The following window opens up. Click the following Add button in the ‘If This’ section.
Another page will open in which we will have to choose our service. There is a lot of options to choose from. Write down ‘webhooks’ in the search option and its icon will appear:
Next, choose the trigger as: ‘Receive a web request’ by clicking on it. Whenever webhooks will receive a web request, some action will take place. This we will define in the ‘THAT’ section.
After clicking the Receive a web request, the following window will open up. We will write down sensor_readings as the event name for the web request. You can use any other name of your choice. Click ‘Create Trigger’ button.
After the trigger is created, we are taken back to the web page where we first added the service for the ‘IF THIS’ section. Now we will click the ADD button for the ‘THEN THAT’ section.
Setting up Service
Now we will choose the service. We have to choose what will happen if a web request is received. Thus, we will type ‘email’ in the search option and click on its icon. This is because we want to send an email whenever a POST request is received.
The following window opens up. We will click on ‘Send me an email’ as highlighted in the red box.
Click on the ‘Connect’ button as shown below.
Next, write down your email address and click ‘Send Pin’ as shown below:
After you successfully enter the PIN, a new window will open up. Fill in all the entries as given below and then click on the ‘Create Action’ button.
After we have created the action, we will be guided towards the initial web page of IFTTT. Click ‘Continue’ to proceed.
After this click the Finish button. Make sure to turn ON the notifications when the applet is running.
You have successfully created the applet as shown below.
Testing the Applet
Go to your and select “My Services” or open a webpage with the link: ifttt.com/my_services. The following windows will appear. Afterwards, click on Webhooks.
This will take you to the following web page. Click on ‘Documentation.’
You will receive a key which should be secure with you. Next, enter the details as shown to trigger the event. We will give hypothetical values for the three variables for now. At the end click, ‘Test it.’
You will get a notification on top of the web page: Event has been triggered. Now go to your email account and check for any notification that came from the IFTTT service. Open the message and it will display the dummy values you entered before.
If you also received a message with the same readings that you entered then it means that your applet is running successfully.
IFTTT Example 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 server name.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";
const char* server_name = "http://maker.ifttt.com/trigger/Replace_with_your_eventName/with/key/Replace_With_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("After 10 seconds the first set of readings will be displayed");
// initialize a pseudorandom number
randomSeed(analogRead(23));
}
void loop() {
//Send an HTTP POST request every 10 seconds
if ((millis()-last_time) > timer_delay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(wifiClient,server_name);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Data to send with HTTP POST
String httpRequestData = "value1=" + String(random(50)) + "&value2=" + String(random(50))+ "&value3=" + String(random(50));
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
/*
http.addHeader("Content-Type", "application/json");
String httpRequestData = "{\"value1\":\"" + String(random(50)) + "\",\"value2\":\"" + String(random(50)) + "\",\"value3\":\"" + String(random(50)) + "\"}";
int httpResponseCode = http.POST(httpRequestData);
*/
Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
last_time= millis();
}
}
How the Code Works?
The code works similarly like the one which we previously did for ThingSpeak.
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 own network credentials in order to successfully connect with your router.
const char* ssid = "Write_your_WIFI_name";
const char* password = "Write_your_password";
Configuring API Key
After importing all the necessary libraries and configuring your network credentials you will have to give your server’s name. This part is a little different and the URL path for the HTTP POST request has to be carefully given. We will create a global variable of type char and call it server_name. The server_name will hold the domain name for the POST request. You will need your event name and your API key. To get access to your event name and API key, go to Documentation in https://ifttt.com/maker_webhooks
const char* server_name = "http://maker.ifttt.com/trigger/Replace_with_your_eventName/with/key/Replace_With_Your_Api_Key";
You will give the domain name as shown above. Make sure to replace your event name and API key in the places specified. For example our event name is sensor_readings and our key is gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_********
Hence, we will specify the server_name as:
const char* server_name = "http://maker.ifttt.com/trigger/sensor_readings/with/key/ gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_********";
loop() function
Inside the infinite loop() function we will make the HTTP POST request. After every 10 seconds the URL encoded data will be sent.
if ((millis() – last_time) > timer_delay) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(wifiClient,server_name);
The following section of code shows the URL encoded data being sent. Inside the message body we will send three values with random numbers between 0-49. In practical purposes these values can be proper readings from a sensor.
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String httpRequestData = "value1=" + String(random(50)) + "&value2=" + String(random(50))+ "&value3=" + String(random(50));
int httpResponseCode = http.POST(httpRequestData);
If you want to send the data in JSON format then uncomment the following block of code and comment the one above it.
/*
http.addHeader("Content-Type", "application/json");
String httpRequestData = "{\"value1\":\"" + String(random(50)) + "\",\"value2\":\"" + String(random(50)) + "\",\"value3\":\"" + String(random(50)) + "\"}";
int httpResponseCode = http.POST(httpRequestData);
*/
Difference between URL encoded message and JSON format
Example URL encoded POST
POST /trigger/sensor_readings/with/key/gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_******** HTTP/1.1
Host: maker.ifttt.com
value1=10&value2=13&value3=6
Content-Type: application/x-www-form-urlencoded
Example JSON POST
POST /trigger/sensor_readings/with/key/gkb_HtIpE-FeOWMH20obLTvUR7_fPipDyj_******** HTTP/1.1
Host: maker.ifttt.com
{value1: 10, value2: 13, value3: 6}
Content-Type: application/json
Displaying Response Code
The following lines of code will print the server response code on our serial monitor.
Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);
Demonstration
After you have uploaded your code to the ESP8266 development board press its 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.
Next, open your email and check for a new email from IFTTT. Inside it, you will be able to view three random values. After every 10 seconds a new set of readings will be available to us in our email.
Conclusion
To summarize everything, we learnt how to send HTTP POST requests from our ESP8266 board to commonly used web services such as ThingSpeak and IFTTT. We can easily integrate our development board with a temperature sensor such as BME280 to get more insightful results
You may also like to read our previous post on posting sensor data to IFTTT with email notification using ESP8266 and MicroPython: