In this tutorial, we will learn how to make HTTP POST requests with ESP32 and Arduino IDE. For demonstration, we will send HTTP POST requests to APIs like ThingSpeak and IFTTT. The ESP32 Dev board is quite powerful and also has built-in WiFi capability, which makes it an ideal choice for IoT projects. When working on IoT projects, we need to integrate a web server into our project to facilitate communication, simplify automation, or even control devices remotely. Web services and APIs are crucial in IoT projects, and we will show how we can incorporate ThingSpeak and IFTTT into our project with this tutorial.
This tutorial is adaptable to any other web service or API other than the ones discussed here. We just have to change the server’s name and parameters according to the service API documentation.
Prerequisites
We will program our ESP32 board in the Arduino IDE. Thus, make sure to have the latest version of the Arduino IDE. We will also require some ESP 32 plugins. If your Arduino IDE does not have the plugins installed and you are not familiar with the plugin installation process, please check this tutorial below:
Installing ESP32 library in Arduino IDE and upload code
What is HTTP POST Request?
HTTP (Hyper-Text Transfer Protocol) is a very common request-response-based protocol between a server and a client. This protocol ensures smooth communication between the server and the client. The HTTP protocol has many methods, but the two most widely used are GET and POST. HTTP is a fundamental protocol used to facilitate communication between networked systems. It plays a vital role in the World Wide Web, allowing users to access and interact with various resources across the internet.
The client, typically a web browser, sends a request to a server for a specific resource using the GET or POST method. The GET method is used to retrieve data from the server. It is commonly used when requesting a webpage or an API endpoint. The server processes the request and sends back the requested data in the response. This method is generally considered safe and idempotent, meaning it can be repeated without causing undesirable effects.
On the other hand, the POST method is used to send data to the server for processing or storage. It is commonly used when submitting forms, sending data to be saved, or performing any action that modifies resources on the server. Unlike the GET method, the POST method can have side effects and is not idempotent. It is important to handle and process POST requests with caution, ensuring proper validation and security measures are in place. With the widespread usage of the internet and web applications, understanding HTTP and its methods is crucial for developers and users alike. By utilizing the appropriate method based on the intended operation, the HTTP protocol ensures efficient and secure communication between servers and clients.
HTTP function | Working of function |
---|---|
GET | The HTTP GET method requests data from a specified resource, this resource is indicated by a URL. |
POST | The HTTP POST method sends data to be processed on a specified resource on the web server. |
In this user guide, we will focus on the POST method of the HTTP protocol. We can use it to send information to the server or to update a resource. The request body of the HTTP POST protocol will include this information, but it will not show this information on the URL. This makes the HTTP POST protocol more secure in terms of security for IoT projects. For example:
POST /Updating Sensor Readings HTTP/1.1 Host: electronicshub.com sensor_reading1=value1&sensor_reading2=value2
For learning more about HTTP GET method you can check our following tutorial: HTTP GET using ESP32 and Arduino IDE
Some Key Features of POST Requests
Here we will discuss some of the key features of HTTP POST request.
- The HTTP POST request has no restrictions on the data length; this is due to the fact that data is submitted to the server through the body of the HTTP request.
- This method will not cache or save our HTTP request in the browser’s history; hence, it is secure.
- The values of the request body are not visible in the browser’s URL, which keeps the data private.
- This method obtains input from the request body and the query string.
- The request body can have different data types that are sent to the server.
- The request cannot be bookmarked.
Required Components
- ESP32 Development Board
Since this is a server-based tutorial, we won’t be requiring other components and modules in this project.
ESP32 HTTP POST Request Examples
Now, moving on to our project, we will learn how to send JSON objects and URL-encoded data from our ESP32 development board to the following APIs:
Working Process
This project works in a three-step process: These steps are listed here to understand the complete working:
- At first, the client (ESP32) will submit an HTTP request to the server (ThingSpeak or IFTTT).
- Then, after receiving the request, the server will return a response to the client.
- On the last step, the ESP32 will receive a response that will contain the status information and the requested content from the server.
ESP32 HTTP POST Request to ThingSpeak API
In this section, we will look at how to send HTTP POST data using ESP32 to the ThingSpeak API. ThingSpeak is an open-source API that stores or retrieves data using the HTTP or MQTT protocols. This takes place over the Internet or through a LAN connection. We will use this API to publish random values for simplicity’s sake.
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 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-encoded.
Using ThingSpeak API
The ThingSpeak API is free to use, but we will have to create a MathWorks account. Follow the steps below to successfully create a MathWorks account.
1. First, open the following website using this link: https://thingspeak.com/
2. The following window will appear: Click on the ‘Get Started for Free’ button.
3. Now ThingSpeak will redirect us to the login window. If you already have an existing MathWorks account, you can use it to log in. Otherwise, follow the tutorial to create a new one. Click the Create One!’ option to make a new MathWorks account.
4. When we have successfully signed in, we will receive the following notification, click the ‘OK’ button.
5. Now go to the ‘New Channel’ button and click it.
6. After creating the channel, go to the API key tab and click it. We will now be able to access our unique API key. Save it and keep it secure, as we will need it later in the program code.
ThingSpeak Example Arduino Sketch
Open the Arduino IDE and go to File > New to open a new file. Copy the code given below into that file. This code will work with any ESP32 development board. You will just have to replace the network credentials and the API key according to your configuration.
#include <WiFi.h>
#include <HTTPClient.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;
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(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
In the first part, we will import the relevant libraries that are necessary for this project. We are using two libraries: WiFi.h and HTTPClient.h.
The WiFi.h library connects our ESP32 module with the local WiFi network. Also, HTTPClient.h will help us make HTTP POST requests easily.
#include <WiFi.h>
#include <HTTPClient.h>
Setting Network Credentials
Next, we will create two global variables to save the SSID and password of our wireless network. You have to replace both of them with your network credentials to successfully connect to your wireless router. Otherwise, the ESP32 will not be able to connect to the network and send requests to the server.
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 that we are going to use.
const char* server = "http://api.thingspeak.com/update";
Configuring the API key
Now, we will create a string variable to hold the unique API key we got from the ThingSpeak website. A quick reminder: this is the key that you saved previously after creating a new channel on the ThingSpeak website.
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 ESP32 board with the local network whose network credentials we already specified above using the WiFi.begin() function. After the connection is established, the IP address of the ESP32 board will be printed on the serial monitor of the Arduino IDE.
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");
Here we will use the randomSeed() function to initiate a random number from a given starting point, which is known as the seed. The analogRead() function will be set to GPIO 23; this GPIO is not connected, and we will use it as a reference for the 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 (ESP32 to ThingSpeak).
if ((millis() – last_time) > timer_delay) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(server);
The following section of code shows the URL-encoded data that is sent to the server. Inside the message body, we will send our API key and a random number between 0 and 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 the previous block of code.
/* 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’s response code on the serial monitor of our Arduino IDE.
Serial.print("HTTP Response code is: ");
Serial.println(httpResponseCode);
Demonstration
After we have uploaded the code to the ESP32 development board, we will press its ENABLE/RESET button.
Now, open the serial monitor of the Arduino IDE, and we will be able to see the IP address of our ESP module. Additionally, the time delay message will also be displayed. Now, if successful client-server communication takes place, the server will send the response code 200. This code corresponds to ‘OK’ from the server, which means the connection is successful. We can view our connection status on the serial monitor.
Next, open the ThingSpeak API, and we will see that different random values are updating after 10 seconds on our dashboard.
ESP32 HTTP POST Request to IFTTT API
Now, we will look at how to send HTTP POST data from ESP32 to IFTTT. In return, we will trigger the IFTTT API to send us email notifications about our data.
IFTTT means ‘If This, Then That.’ It is an open-source service that gives its users the freedom to program a response to an event according to their preferences. Here, we can create an applet. Applets are the series or chains of conditional statements formed by the combination of several app services and triggering parameters.
In this project, whenever the ESP32 makes a request to the server, the IFTTT applet will send three random values to our provided email address. In practical situations, these values can be read from a sensor such as the BME280.
To work with this web service, you will need to follow the steps provided below to set up its proper functionality.
Creating an Account
Although the IFTTT service is a free to use service, we will have to create an account.
1. Open the following website using this link: https://ifttt.com/.
2. The following window will appear: Click on the ‘Get Started’ button.
3. The website will redirect us to the sign-in or sign-up page shown below. We can select any one of these options (Apple, Google, or Facebook) to connect to this service. Or we can simply ‘sign up’ with our own email. We will be following this scheme.
4. Click on the ‘sign up’ tag, and you will see the following window pop up: Enter your email address and password and click the ‘Sign Up button to start working with IFTTT.
Note: This process is free only for the first 3 applets using IFTTT, and we will have to subscribe to their plan for creating more applets.
Creating an Applet:
After creating our account, the website will again redirect us to another page (see the figure below), where we will create our applet. Click on the ‘Create’ button.
The following window will open up: Click on the ‘Add‘ button in the ‘If This’ section.
Another page will open where we will have to choose our service. There are a lot of options to choose from. Write down ‘webhooks’ in the search menu, and the webhooks icon will appear:
Next, set the trigger to ‘Receive a web request’ by clicking on it. Now, whenever webhooks receive a web request, it will perform some action. We will define this action in ‘Then That’ section.
After clicking the Receive a web request, the following window will open up: We will write down the event name as “sensor_readings” for the web request. You can use any other name of your choice. Now, click on the Create Trigger’ button.
After the trigger is created, we are redirected to the web page where we first added the service for the ‘IF THIS’ section. Now we will click on the ‘ADD’ button for the ‘THEN THAT’ section.
Setting up the Service
Now, IFTTT will ask us to select a service that takes place when a web request is received. We will choose this service as an email. Thus, we will type ‘email’ in the search menu 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 the ‘Send me an email’ button as highlighted in the red box below.
Click on the ‘Connect’ button as shown in the figure below.
Next, write down the email address and click on the ‘Send Pin’ button as shown below:
After successfully entering the PIN, a new window will open up. Fill in all the entries as given below and then click on the ‘Create Action’ button.
Subject:
The event named “your_event_name_here” occurred on the Maker Webhooks service.
Body:
What: “your_event_name_here”<br>Time Stamp: OccurredAt <br> Readings: Value_1, Value_2, Value_3,
After the action is successfully created, the IFTTT website will direct us to the initial web page. Click on the ‘Continue’ button to proceed.
After this, click on the ‘Finish button’. Make sure to turn on the notifications when the applet is running.
The following message indicates that we have successfully created the applet, as shown below.
Testing the Applet
Go to the Applet and select “My Services” or open a webpage with this link: https://ifttt.com/my_services. The following window will appear: Now, click on the Webhooks option.
This will take us to the following web page: Click on the ‘Documentation’ button.
We will receive a key; this key secures our applet. Next, enter the details as shown in the figure below to trigger the event. We will give hypothetical values for the three variables for now. Our setup is complete; now click on the ‘Test it’ button at the end.
We will get a notification at the top of the web page: Event has been triggered. Now go to the email account provided during setup and check for any notifications that came from the IFTTT service. Open the message, and it will display the dummy values we have entered above.
If you also received a message with the same readings that you entered in the optional JSON body, then this means that your applet is running successfully.
IFTTT Example Arduino Sketch
We have provided a simple sketch to connect the ESP32 board with the IFTTT service. Open the Arduino IDE and go to File > New to open a new file. Copy the code given below into that file. This code will work with any ESP32 development board. You just have to replace the network credentials and server name.
#include <WiFi.h>
#include <HTTPClient.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;
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(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 to the one we previously did for ThingSpeak.
Setting Network Credentials
Next, we will create two global variables to save the SSID and password values of the network. You have to replace both of them with your own network credentials in order to successfully connect the ESP32 to your router. Otherwise, the ESP32 will not be able to connect with the IFTTT service.
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 enter 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 for this. To get access to your event name and API key, go to Documentation at 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";
We will enter the domain name as shown above. Make sure to replace your event name and API key in the specified places. 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. Every 10 seconds, the URL-encoded data will be sent to the IFTTT service.
if ((millis() – last_time) > timer_delay) {
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
http.begin(server_name);
The following section of code shows the URL-encoded data that will be sent. Inside the message body, we will send three values with random numbers between 0 and 49. For practical purposes, these values can be replaced with proper readings from a sensor such as BME280.
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 we have uploaded the code to the ESP32 development board, We will press its ENABLE or RESET button.
Now, we will open the serial monitor of the Arduino IDE, and we will look for the IP address of the ESP module. Additionally, the time delay message will also be displayed. Now, if successful client-server communication takes place, the server will send the response code 200. This code corresponds to ‘OK’ from the server, which means the connection is successful. We can view this connection status on the serial monitor.
Next, open your email account and refresh it. Wait for a new email from IFTTT. This email will include three random values. After every 10 seconds, a new email will be sent from the IFTTT service with a set of readings available to us in our email.
Conclusion
To summarize everything we have learned in this tutorial, a list is provided below.
- Introduction to ThingSpeak and the IFTTT API
- How to setup ThingSpeak and the IFTTT Web service for our projects
- How to send HTTP POST requests from our ESP32 board to commonly used web services (ThingSpeak and IFTTT)
We can easily integrate our ESP32 development board with a temperature sensor such as the BME280 to get more insightful results from these two web services.
You may also like to read our previous post on posting sensor data to IFTTT with email notifications using ESP32 and MicroPython:
- HTTP GET using ESP32 and Arduino IDE (OpenWeatherMap.org and ThingSpeak)
- MicroPython: Send Sensor Readings via Email (IFTTT) with ESP32 and ESP8266
- ESP32 HTTPS Requests using Arduino IDE
- ESP32/ESP8266 with HTTPS and SSL/TLS Encryption Introduction
- ESP8266 NodeMCU HTTP POST using Arduino IDE (ThingSpeak and IFTTT)