Update LCD Display with ESP32 Web Server

Hello readers, I hope you all are doing great.

ESP32 is a powerful chip for Internet of Things applications. This tutorial is also based on one of the ESP32 applications in the field of IoT.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

Project Overview

In this tutorial, we will learn how to update LCD display with new data or input using a web server created with ESP32.

Fig. 1

To achieve the target, we will be using an HTML (Hypertext Markup Language) form to provide web input and then update the text displayed on LCD. The values or input received from the webserver will be further stored inside a variable in the code for further use (to display on LCD).

We have already posted a tutorial on LCD (Liquid Crystal Display) interfacing with ESP32. In that tutorial, we demonstrated how to display the hard-coded data (in the ESP32 module) on LCD.

ESP32 Web Server

A web server is computer software and hardware that accepts requests and responds to those requests using HTTP (Hypertext transfer protocol) or HTTPS (HTTP Secure) (HTTP is a network protocol for delivering online content to client user agents).

The ESP32 standalone web server is mobile-enabled and can be accessed from any device with a browser on the local network. B. Mobile phones, computers, laptops, tablets. However, all the devices must be connected to the same WiFi network to which the ESP32 is connected.

Software and Hardware requirements

  • ESP32 development board
  • 16*2 LCD display
  • 10K trim-pot
  • Breadboard or general-purpose PCB
  • Connecting Wires
  • Arduino IDE
  • h, ESPAsynchWenServer.h header files

Interfacing16*2 LCD with ESP32

There are basically two ways to connect the ESP32 to a 16 * 2 LCD display.

  1. Interface with I2C adapter
  2. Direct connection without using I2C adapter.

Connecting an LCD display without an I2C adapter is cheap, but this method requires more connection cables and is complicated to implement. On the other hand, using an I2C adapter reduces complexity but increases cost. In this tutorial, you will connect the ESP32 directly without using an I2C adapter.

Table: 1

Fig. 2: ESP32 and 16*2 LCD interfacing

For more details on interfacing 16*2 LCD with ESP32, follow our previous tutorial at www.theengineeringprojects.com

Programming ESP32

Installing ESP32 board manager in Arduino IDE:

We are using Arduino IDE to compile and upload code into ESP32 module. You must have ESP32 board manager installed on your Arduino IDE to program ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on ESP32 programming series. The link is given below:

https://www.theengineeringprojects.com/2021/11/introduction-to-esp32-programming-series.html

Installing necessary libraries:

ESP32 board manager doesn’t come with inbuilt libraries to create an asynchronous web server. So we need to download the library file from external sources and then add into Arduino IDE.

We need to install two library files:

  1. ESPAsynWebServer: Follow the link https://github.com/me-no-dev/ESPAsyncWebServer to download the respective library.
  1. AsyncTCP: You can download the AsyncTCP library from the following link https://github.com/me-no-dev/AsyncTCP

Once you have successfully downloaded the required libraries, next step it to install or add these libraries in Arduino IDE.

To add the libraries in Arduino IDE, go to Sketch >> Include Library >> Add .zip library and then select the downloaded library files.

Fig. 3: adding necessary libraries

Arduino IDE code

#include < WiFi.h >

#include < AsyncTCP.h >

#include < ESPAsyncWebServer.h >

#include < LiquidCrystal.h > // LCD header file

LiquidCrystal lcd (22, 23, 5, 18, 19, 21 );

AsyncWebServer server ( 80 );

// Enter your netwrok credentials

const char* ssid = "replace this with netwrok SSID";

const char* password = "replace this with Password";

const char* PARAM_INPUT_1 = "data_field1";

const char* PARAM_INPUT_2 = "data_field2";

// HTML web page to handle data input fields

const char index_html[] PROGMEM = R"rawliteral(

<!DOCTYPE HTML> <html> <head>

<title> ESP Input Form </title>

<meta name = " viewport" content="width=device-width, initial-scale=1 ">

<style>

html{ font-family: Times New Roman; display: inline-block; text-align: justify;}

</style>

</head> <body>

<form action="/get">

Data_field1: <input type="text" name="data_field1" >

<input type="submit" value="Post ">

</form> <br>

<form action="/get">

Data_field2: <input type="text" name="data_field2">

<input type="submit" value="Post">

</form><br>

</body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {

request->send(404, "text/plain", "Not found");

}

void setup() {

 

Serial.begin(115200);

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, password);

if (WiFi.waitForConnectResult() != WL_CONNECTED) {

Serial.println("WiFi Failed!");

return;

}

Serial.println();

Serial.print("IP Address: ");

Serial.println(WiFi.localIP());

//===set LCD

lcd.begin(16, 2);

lcd.clear();

lcd.setCursor(1,0);

server.onNotFound(notFound);

server.begin();

// Send web page with input fields to client

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)

{

request->send_P(200, "text/html", index_html);

});

server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {

String inputMessage;

String inputParam;

// GET input1 value

if (request->hasParam(PARAM_INPUT_1))

{

inputMessage = request->getParam(PARAM_INPUT_1)->value();

inputParam = PARAM_INPUT_1;

}

// GET input2 value

else if (request->hasParam(PARAM_INPUT_2))

{

inputMessage = request->getParam(PARAM_INPUT_2)->value();

inputParam = PARAM_INPUT_2;

}

else

{

inputMessage = " No message sent";

inputParam = " none";

}

Serial.println ( inputMessage );

delay( 1000);

lcd.clear();

lcd.print( inputMessage);

request-> send (200, "text/html", " HTTP GET request sent to ESP32("

+ inputParam + "): " + inputMessage +

"<br><a href=\"/\"> Back to Home Page </a>");

});

}

void loop( )

{

}

Code Description

  • The first step is adding the necessary header files.
  • Here we are using two libraries:
    • The first one is WiFi.h, which is used to enable the Wi-Fi module and hence wireless network connectivity.
    • LiquidCrystal.h is used to call the necessary functions required to interface and control LCD with ESP32.
    • ESPAsynchWenServer library file is responsible for creating an asynchronous web server.
    • AsyncTCP is used to enable a multi-connection network for ESP32 (Espressif’s) microcontroller unit.

Fig. 4: Adding header files

  • Define the data and control pins (of 16*2 LCD) to be interfaced with ESP32.

Fig. 5: LCD data and control pins

  • While creating a web server we also need to assign a port and usually port 80 is used for local web server.

Fig. 6: server port

  • Enter the network credentials in place of SSID and PASSWORD.

Fig. 7: Enter Network credentials

  • The next thing is the declaration of variables for input data fields.

Fig. 8

Creating HTML Form

  • !DOCTYPE html><html> is used to describe/indicate that we are transmitting HTML, this command should always be the first thing we send.
  • <title> tag is used to write a title for the web page.
  • The next line in the code is used to make the web page responsive in any web browser.
  • The <style> tag is used to style the webpage, which includes the type of font, alignment, display etc.

Fig. 9: HTML web page

  • Next comes the HTML form for user input. We are going to create two data input fields for user input and each filed is having a Post button to send the new data string to the ESP device and the variable declared to store the input will be updated.
  • <form> tag is used to create the HTML form. Here we are creating an HTML form with two input fields namely the Data_field2 and Data_filed2 and each field is having individual Post buttons to post the input from the web server to the client.
  • The action attribute is used to specify, where to send the data input provided in the input data fields after pressing the post
  • After pressing the post button a new web page will open, indicating the status whether the input string is successfully posted or not.

Fig. 10: HTML form for data input

  • The two attributes, type and value specifies a button and the text on the button respectively.

Fig. 11: Post button.

  • If we make an invalid request, the notFound() function will be called.
 

Setup

  • Initialize the serial monitor at 115200 baud rate for debugging purpose.
    • begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.
    • The While loop will continuously run until the ESP32 is connected to Wi-Fi network.

Fig. 12

  • If the device is connected to local Wi-Fi network then print the details on serial monitor.
  • localIP() function is used to fetch the IP address.
  • Print the IP address on serial monitor using println() function.

Fig. 13: Fetch/obtain the IP adrress

  • Initialize the 16*2 LCD using begin() function.
  • Clear the previous data from the LCD before printing or displaying the new one using clear() function.
  • Set the cursor position at row 1 and column 0 using setCursor() function.

Fig. 14: Set 16*2 LCD

  • begin() function is used to initialize the web server once ESP32 is connected with the Wi-Fi network.

Fig. 15: Initialize the server

Handling HTTP GET requests

  • The next part in the programming includes handling of HTTP GET requests.
  • When we access the route URL, we send the web page to client along with the data input fields.
  • We have defined a variable namely index_html to save the HTML text.

Fig. 16: Send web page to client

  • Next task is handling what happens when device receive a request on the /get routes.
  • To save input values, we have created two variables: inputPram and

Fig. 17

  • Next we need to check if HTTP get request contains the Data_input1 and Data_input1 These fields values are saved on PRAM_INPUT_1 and PRAM_INPUT2.
  • If the HTTP GET request contains inputs, then the inputMessage1 will be set to the value inserted in the data_field1.

Fig. read the input from HTML form

  • Else there will be no input for inputMessage.

Fig. 18

  • Print the input value saved on variable inputMessage using Serial.print command.
  • clear() command is used to clear the previous data printed on LCD.
  • New data or message received from the web server will be printed on the LCD display using print() function.

Fig. 19

  • After pressing the post button a new web page will open, indicating the status whether the input string is successfully posted or not.

Fig. 20

Testing

  • Open your Arduino IDE and paste the above code.
  • Change the network credentials, that is the SSID and PASSWORD as per you network setup.
  • Compile and upload the code into ESP32 development board.
  • Before uploading the code make sure that you have selected the correct development board and COM port.

Fig. 21: Select development board and COM port

  • Once the code is uploaded successfully, open the Serial monitor and select the 1115200 baud rate (as per your code instructions).
  • Make sure Wi-Fi to which your ESP device is supposed to connect is ON.
  • Once your ESP32 is connected to the internet, the IP address of the device will be printed on the Serial monitor.
  • Copy the IP address.
  • Open the browser and paste the IP address and press
  • A web page with HTML form containing two input fields will open as shown below:

Fig. 22: web Page

  • Enter the text in the HTML form you want to be printed on on the LCD display.
  • Press the Post

Fig. 23: Enter the Input to ESP32

  • After pressing the post button a new web page will open, indicating the status whether the input string is successfully posted or not.

Fig. 24: Input Updated

Fig. 25: IP address and Web Input on serial monitor.

Fig. 26: String input received from Web server, printed on LCD

This concludes the tutorial. We hope you found this of some help and also hope to see you soon with a new tutorial on ESP32.

Server-Sent Events with ESP32 and DHT11

Hello readers, I hope you all are doing great. In this tutorial, we will learn how to update a webpage using Server-Sent Events and the ESP32 web server.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

What is Server-Sent Events (SSE)?

It is a server push technology that enables the client devices to receive automatic updates from a server over HTTP (Hypertext Transfer Protocol) connection. SSE also describes how the server can initiate data transmission towards the client once an initial connection with the client has been established.

We have already posted a tutorial on how to implement Web socket protocol with ESP32 which is also a protocol used to notify events to a web client. Both the Server-Sent Events (SSE) and Web-Socket technologies seem to be quite similar but they are not.

The major difference between the two is that SSE is unidirectional, where the web client can only receive the updates from the ESP32 but it can’t send updates back to ESP32. On the other hand, the Web-socket protocol is bi-directional where both the web client and ESP32 can send and receive updates/events.

Fig. 1 Server-Sent event

How does the Server-Sent Event works?

The Server-Sent Event process initiates with an HTTP request from the web client or web page to the ESP32 web server. After that, the ESP32 is ready to send updates or events to the web client as they happen. But the web client can’t send any response or data to the ESP32 server after the initial handshake takes place.

Server-sent event technology can be used to communicate an event, GPIO states or to send sensor readings to the web client, whenever a new reading is observed.

Project Overview

For demonstration purpose, we are using a DHT11 sensor with the ESP32 module. ESP32 web server will display two things i.e., temperature and humidity observed using the DHT11 sensor. So, whenever a new reading is being observed, the ESP32 sends the reading to the Web Client over Server-sent events. After receiving the latest sensor reading the client updates the web page data.

Software and Hardware requirements

  • ESP32 development board
  • DHT11 sensor
  • Connecting Wires
  • Breadboard
  • Arduino IDE
  • Necessary Libraries

DHT11 (a Temperature and Humidity sensor)

Fig. 2 DHT11 sensor

DHT11 is a humidity and temperature sensor that measures its surrounding environment. It measures the temperature and humidity in a given area. It is made up of an NTC (negative temperature co-efficient) temperature sensor and a resistive humidity sensor. It also has an 8-bit microcontroller. The microcontroller is in charge of ADC (analog to digital conversion) and provides a digital output over the single wire protocol.

The DHT11 sensor can measure humidity from 20% to 90% with +-5 percent accuracy (RH or relative humidity) and temperature from 0 degrees Celsius to 50 degrees Celsius with +-2C accuracy.

DHT11 sensors can also be used to build a wired sensor network with a cable length of up to 20 meters.

Interfacing DHT11 with ESP32 module

Table 1

Note: Connect a 10K resistor between data and power (+5V) pin of DHT11 sensor module.

Fig. 3 ESP32 and DHT11 connections/wiring

Programming with Arduino IDE

We are using Arduino IDE to compile and upload code into the ESP32 module. You must have ESP32 board manager installed on your Arduino IDE to program the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on ESP32 programming series. The link is given below:

https://www.theengineeringprojects.com/2021/11/introduction-to-esp32-programming-series.html

Steps to add the necessary libraries in Arduino IDE:

  • Go to Tools >> Manage Libraries.

Fig. 4 manage libraries

  • Search for the necessary library in Library Manager and click Install.
  • We are attaching an image, where we are installing the DHT11 sensor library.

Fig. 5 Install DHT sensor library

  • Follow the similar procedure for rest of the libraries.
  • After successfully installing all the required libraries close the Library Manager tab.

ESP32 board manager doesn’t come with inbuilt libraries to create an asynchronous web server. So we need to download the library file from external sources and then add into Arduino IDE.

We need to install two library files:

  1. ESPAsynWebServer: Follow the link https://github.com/me-no-dev/ESPAsyncWebServer to download the respective library.
  1. AsyncTCP: You can download the AsyncTCP library from the following link https://github.com/me-no-dev/AsyncTCP

Once you have successfully downloaded the required libraries, next step it to install or add these libraries in Arduino IDE.

To add the libraries in Arduino IDE, go to Sketch >> Include Library >> Add .zip library and then select the downloaded library files.

Fig. 6 adding necessary libraries

Arduino Code

#include <WiFi.h>

#include <AsyncTCP.h>

#include <ESPAsyncWebServer.h>

#include "DHT.h"

#define DHTPIN 4 // Digital pin connected to the DHT sensor

#define DHTTYPE DHT11 // DHT 11

// Initializing the DHT11 sensor.

DHT dht(DHTPIN, DHTTYPE);

// Replace with your network credentials

const char* ssid = "SSID";

const char* password = "password";

// Create AsyncWebServer object on port 80

AsyncWebServer server(80);

// Create an Event Source on /events

AsyncEventSource events("/events");

// Timer variables

unsigned long lastTime = 0;

unsigned long timerDelay = 20000; //20 sec timer delay

//==== Creating web page

const char index_html[] PROGMEM = R"rawliteral(

<!DOCTYPE HTML><html>

<head>

<title>SSE with ESP32 Web Server</title>

<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

<link rel="icon" href="data:,">

<style>

html {font-family: Times New Roman; display: inline-block; text-align: justify;}

p { font-size: 1.2rem;}

body { margin: 0;}

.topnav { overflow: hidden; background-color: blue; color: white; font-size: 1rem; }

.content { padding: 20px; }

.card { background-color: #ADD8E6; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }

.cards { max-width: 600px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.reading { font-size: 1.4rem; }

</style>

</head>

<body>

<div class="topnav">

<h1>Server-Sent Events </h1>

<h2> DHT11 Sensor Data </h2>

</div>

<div class="content">

<div class="cards">

<div class="card">

<p> DHT11 Temperature</p><p><span class="reading"><span id="temp">%TEMPERATURE%</span> &deg;C</span></p>

</div>

<div class="card">

<p> DHT11 Humidity</p><p><span class="reading"><span id="hum">%HUMIDITY%</span> &percnt;</span></p>

</div>

</div>

</div>

<script>

if (!!window.EventSource)

{

var source = new EventSource('/events');

source.addEventListener('open', function(e)

{

console.log("Events Connected");

}, false);

source.addEventListener('error', function(e)

{

if (e.target.readyState != EventSource.OPEN)

{

console.log("Events Disconnected");

}

}, false);

source.addEventListener('message', function(e)

{

console.log("message", e.data);

}, false);

source.addEventListener('temperature', function(e)

{

console.log("temperature", e.data);

document.getElementById("temp").innerHTML = e.data;

}, false);

source.addEventListener('humidity', function(e)

{

console.log("humidity", e.data);

document.getElementById("hum").innerHTML = e.data;

}, false);

}

</script>

</body>

</html>)rawliteral";

 

void setup() {

Serial.begin(115200); //initialize serial monitor

//===set and initialize Wi-Fi

WiFi.mode(WIFI_STA);

WiFi.begin(ssid, password);

Serial.print("Connecting to WiFi ..");

while (WiFi.status() != WL_CONNECTED)

{

Serial.print('.');

delay(1000);

}

Serial.print("IP Address: ");

Serial.println(WiFi.localIP()); // print the IP address

//====Initialize DHT11 sensor

dht.begin();

//====Handle Web Server

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){

request->send_P(200, "text/html", index_html);

});

// Handle Web Server Events

events.onConnect([](AsyncEventSourceClient *client)

{

if(client->lastId())

{

Serial.printf("Client reconnected! Last message ID that it got is: %u\n",

client->lastId());

}

// send event with message "hello!", id current millis

// and set reconnect delay to 1 second

client->send("hello!", NULL, millis(), 10000);

});

server.addHandler(&events);

server.begin();

}

void loop()

{

delay(2000);

float humidity = dht.readHumidity();

// Read temperature as Celsius (the default)

float temperature = dht.readTemperature();

// Check if any reads failed and exit early (to try again).

if (isnan(humidity) || isnan(temperature))

{

Serial.println(F("Failed to read from DHT sensor!"));

return;

}

if ((millis() - lastTime) > timerDelay)

{

// Send Events to the Web Server with the Sensor Readings

events.send("ping",NULL,millis());

events.send(String(temperature).c_str(),"temperature",millis());

events.send(String(humidity).c_str(),"humidity",millis());

Serial.print(F("Humidity(%): "));

Serial.println(humidity);

Serial.print(F("Temp.: "));

Serial.print(temperature);

Serial.println(F("°C "));

}

}

Code Description

  • Here we are using four libraries:
    • The first one is WiFi.h, which is used to enable the Wi-Fi module and hence wireless network connectivity.
    • DHT.h is used to call the necessary functions required to interface DHT sensor with ESP32.
    • ESPAsynchWenServer library file is responsible for creating an asynchronous web server.
    • AsyncTCP is used to enable multi-connection network for ESP32 (Espressif’s) microcontroller unit.

Fig. 7 Header files

  • Next step is the declaration of variables for DHT11 sensor.
  • We are declaring 2 variables, the first one is the DHTPIN to store the GPIO number receiving input from DHT11 sensor and another variables is to define the type of DHT (i.e., whether DHT11 or DHT22).

Fig. 8 Global declarations

  • Next we are creating a DHT object called dht in the DHT sensor type (defined earlier) and the DHT pin.

Fig. 9

  • Enter the network credentials in place of SSID and PASSWORD.

Fig. 10 Enter Network credentials

  • While creating a web server we also need to assign a port and usually port 80 is used for local web server.

Fig. 11 Server port

  • Next step is creating a new event source(on /events).

Fig. 12 Event source

  • Timer variable declaration: the timerDelay and lastTime variables are declared to add delay using timer, instead of using delay() function. Here we are adding a delay of 20 seconds which means the web browser will be updated with new sensor reading in every 20 sec.

Fig. 13 Timer Variables

Creating the Web Page

  • !DOCTYPE html><html> is used to describe/indicate that we are transmitting HTML, this command should always be the first thing we send.
  • <title> tag is used to write title for the web page.

Fig. 14

  • The <style> tag is used to style the webpage, which includes the type of font, alignment, display, color, dimensions etc. You can make changes in the <style> tag as per your requirements.

Fig. 15

  • The content, which is to be displayed on the Web page is written inside the <body> tag. The <body> tag includes two headings h1 and h2 and sensor readings (temperature and humidity).

Fig. 16

Initializing an Event-Source connection

  • JavaScript is written inside the inside the <script> tag, which is responsible for initializing an event source connection with the web server and also to handle the events received from the web server.
  • An object EventSource is created and along with that the URL of the webpage sending the updates is also specified.
  • addEventListener() function is used to listen to the messages coming from the web server, once the event source is initiated successfully.

Fig. 17

  • Next task is adding an event listener for Whenever a new temperature reading is observed from the DHT11 sensor, ESP32 sends a “temperature” event to the web client.

Fig. 18

  • Similarly, another event is generated for It prints the latest readings on the web browser & puts the received data into the element with respective ID on the webpage.

Fig. 19

Setup

  • Initialize the serial monitor at a 115200 baud rate for debugging purposes.
    • begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.
    • The While loop will continuously run until the ESP32 is connected to the Wi-Fi network.

Fig. 20

  • If the device is connected to a local Wi-Fi network then print the details on the serial monitor.
  • localIP() function is used to fetch the IP address.
  • Print the IP address on the serial monitor using println() function.

Fig. 21 Fetch/obtain the IP address

 

Fig. 22 Initialize DHT sensor

Handling HTTP GET requests

  • The next part in the programming includes handling HTTP GET requests.
  • When we access the route URL, we send the web page to the client along with the data input fields.
  • We have defined a variable namely index_html to save the HTML text.

Fig. 23

Handling Server Event source

  • The next task is setting up the event source on the webserver.

Fig. 24 Handling server events

 

Initializing web server

  • Initialize the webserver using begin() function.

Fig. 24 initializing web server

 

Loop()

  • DHT11 is a very slow sensor. It takes almost 250ms to read temperature and humidity.
  • So it is preferred to wait a few seconds before a new measurement or updated sensor reading.
  • Next, we are defining a float type variable ‘h’ to store humidity measured from the DHT11 sensor.
  • readHumidity() function is used to observe the humidity value.
  • readTemperature() function is used to read the surrounding temperature with the DHT11 sensor.

Fig. 25

 
  • If somehow the sensor fails to read or observer temperature and humidity values, then the respective results will be printed on the serial monitor.

Fig. 26 If error occurs while reading data from DHT11

Sending Events to the server

  • Send the updated events or the latest observation from the DHT11 sensor the web browser over the local network.
  • The sensor readings will be updated in every 20 second as per the code instructions.

Fig. 27 Sending events to the server

  • Print the temperature and humidity readings (observer form the DHT11 sensor) on the Serial monitor.

Fig. 28 Print Sensor data on the Serial monitor

Testing

  • Open your Arduino IDE and paste the above code.
  • Change the network credentials, that is the SSID and PASSWORD as per you network setup.
  • Compile and upload the code into ESP32 development board.
  • Before uploading the code make sure that you have selected the correct development board and COM port.

Fig. 29 Select development board and COM port

  • Once the code is uploaded successfully, open the Serial monitor and select the 1115200 baud rate (as per your code instructions).
  • Make sure Wi-Fi to which your ESP device is supposed to connect is ON.
  • Once your ESP32 is connected to the internet, the IP address of the device will be printed on the Serial monitor.
  • Copy the IP address.
  • Open the browser and paste the IP address and press
  • A web page will appear, as shown below:

Fig. 30

  • The web page will be updated with new data every 20 seconds, as per the code instructions and we do not even need to refresh the web page for latest event updates due to SSE technology.

Fig. 31

This concludes the tutorial. I hope you found this of some help and also hope to see you soon with a new tutorial on ESP32.

ESP32 DHT11 Interfacing with ThingSpeak WebServer

ESP32 module comes with multiple inbuilt features and peripheral interfacing capability is one of those features. ESP32 module also consists of an inbuilt temperature sensor, but that can only measure the temperature of the ESP32 core not the temperature of the surrounding environment. So it is required to use a peripheral sensor to measure the temperature of the surrounding environment like home, garden, office etc.

Hello readers. I hope you all are doing great. In this tutorial, we will learn how to interface DHT11 (temperature and humidity sensor) with the ESP32. Later in this tutorial, we will discuss how to share the sensor readings obtained from the DHT11 sensor to a web server.

Before moving towards the interfacing and programming part, let’s have a short introduction to the DHT11 sensor, its working and its connections.

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

DHT11 (A Temperature and Humidity Sensor)

Fig. 1: DHT11 sensor

DHT11 is used to measure humidity and temperature from its surrounding. It monitors the ambient temperature and humidity of a given area. It consists of an NTC (negative temperature co-efficient) temperature sensor and a resistive type humidity sensor. It also consists of an 8-bit microcontroller. The microcontroller is responsible for performing ADC (analog to digital conversion) and provides a digital output over the single wire protocol.

DHT11 sensor can measure humidity from 20% to 90% with +-5% (RH or relative humidity) of accuracy and can measure the temperature in the range of 0 degrees Celsius to 50 degrees Celsius with +-2C of accuracy.

DHT11 sensors can also be used to implement a wired sensor system using a cable length of up to 20 meters.

There are two DHT modules (DHT11 and DHT22) available in the market to measure temperature and humidity. The purpose of both module are same but with different specifications. Like DHT22 sensor provides broader temperature and humidity sensitivity ranges. But DHT22 is costlier than DHT11. So you can prefer to use any of the module, as per your requirements.

Components required

  • ESP32 development board
  • DHT11 sensor
  • 10K resistor
  • Connecting wires
  • Breadboard

Interfacing DHT11 with ESP32 module

Table: 1

Note: Connect a 10K resistor between data and power (+5V) pin of DHT11 sensor module.

Fig. 2: ESP32 and DHT11 connections/wiring

Arduino Programming

We are using Arduino IDE to compile and upload code into ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on ESP32 programming series. Link is given below:

https://www.theengineeringprojects.com/2021/11/introduction-to-esp32-programming-series.html

Adding required libraries in Arduino IDE

DHT11 sensor uses single wire protocol to communicate data which requires a precise timing. In order to interface DHT11 sensor with ESP32 module it is required to add necessary libraries. To install the DHT11 sensor library;

  • Go to Tools >> Manage Libraries.

Fig. 3: manage libraries

 
  • Type DHT in the search bar and install the DHT sensor library as shown below.

Fig. 4: Install DHT sensor library

   

Arduino IDE code to interface DHT11 with ESP32

#include "DHT.h"

#define DHTPIN 4 // Digital pin connected to the DHT sensor

#define DHTTYPE DHT11 // DHT 11

// Initializing the DHT11 sensor.

DHT dht(DHTPIN, DHTTYPE);

void setup() {

Serial.begin(115200);

Serial.println(F("DHT test string!"));

dht.begin();

}

 

void loop() {

// Wait a few seconds between measurements.

delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!

// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)

float h = dht.readHumidity();

// Read temperature as Celsius (the default)

float t = dht.readTemperature();

// Read temperature as Fahrenheit (isFahrenheit = true)

float f = dht.readTemperature(true);

// Check if any reads failed and exit early (to try again).

if (isnan(h) || isnan(t) || isnan(f)) {

Serial.println(F("Failed to read from DHT sensor!"));

return;

}

// Compute heat index in Fahrenheit (the default)

float hif = dht.computeHeatIndex(f, h);

// Compute heat index in Celsius (isFahreheit = false)

float hic = dht.computeHeatIndex(t, h, false);

Serial.print(F("Humidity(%): "));

Serial.println(h);

Serial.print(F("Temp.: "));

Serial.print(t);

Serial.println(F("°C "));

Serial.print(F("Temp.: "));

Serial.print(f);

Serial.println(F("°F "));

Serial.print(F("Heat index: "));

Serial.println(hic);

Serial.println(" ");

Serial.print(F("°C "));

Serial.print(hif);

Serial.println(F("°F"));

}

Code Description

  • Add the necessary header files required to interface the DHT11 sensor.

Fig. 5: Add necessary libraries

  • The next step is the declaration of variables for the DHT11 sensor.
  • We are declaring 2 variables, the first one is the DHTPIN to store the GPIO number receiving input from the DHT11 sensor and another variable is to define the type of DHT (i.e., whether DHT11 or DHT22).

Fig. 6: Global declarations

  • Next, we are creating a DHT object called dht in the DHT sensor type (defined earlier) and the DHT pin.

Fig. 7

 

Setup()

  • Inside the setup function, the first task is initializing the serial monitor at a 115200 baud rate for debugging purposes.
  • Initialize the DHT sensor using begin() function.

Fig. 8

Loop()

  • DHT11 is a very slow sensor. It takes almost 250ms to read temperature and humidity.
  • So it is preferred to wait a few seconds before a new measurement or updated sensor reading.
  • Next, we are defining a float type variable ‘h’ to store humidity measured from the DHT11 sensor.
  • readHumidity() function is used to observe the humidity value.

Fig. 9

  • readTemperature() function is used to read the surrounding temperature with DHT11 sensor.

Fig. 10

  • If somehow the sensor fails to read or observer temperature and humidity values, then the respective results will be printed on the serial monitor.

Fig. 11

  • Another float type variable hif is defined to store the heat index value.
  • computeHeatIndex() function is used to calculate the heat index value.

Fig. 12: Heat index

Results

  • Open the Arduino IDE and paste the above code.
  • Compile and upload the program after selecting the correct development board and COM port.
  • Connect the DHT11 sensor with ESP32 board as per the given circuit instructions.

Fig. ESP32 and DHT11 interfacing

  • Open the serial monitor at 115200 baud rate and press the enable (EN) button from the ESP32 development board.
  • You should see the temperature, humidity, Heat index readings printed on the serial monitor.

Fig. 13: Readings observed from DHT11 sensor

Uploading DHT11 sensor reading to ThingSpeak Server

The IoT is the interconnection of physical objects or devices with sensors and software accessing capabilities to communicate data or information over the internet.

To build an IoT network, we need an interface medium that can fetch, control, and communicate data between sender and receiver electronics devices or servers.

Espressif Systems created the ESP32 Wi-Fi chip series. The ESP32 module is equipped with a 32-bit Tensilica microcontroller, 2.4GHz Wi-Fi connectivity, an antenna, memory, and power management modules, and much more. All of these built-in features of this ESP32 module make it ideal for IoT applications.

ThingSpeak web servie

It is an open data platform for the Internet of Things (Internet of Things). ThingSpeak is a MathWorks web service that allows us to send sensor readings/data to the cloud. We can also visualise and act on the data (calculate the data) sent to ThingSpeak by the devices. Data can be stored in both private and public channels.

ThingSpeak is commonly used for internet of things prototyping and proof of concept systems requiring analytics.

 

Getting Started with ThingSpeak

  • To create and account or log in to ThingSpeak (operated by MathWorks) server follow the link: https://thingspeak.com/
  • Click on Get Started for free.

Fig. 14: Getting started for free

  • Enter your details to create a MathWorks account as shown below:

Fig. 15: Create new account

  • If you have already created a MathWorks account, then click on Sign in.

Fig. 16: MathWorks Sign in

  • Create a channel on MathWorks server by clicking on the New Channel
  • ThingSpeak web service allows its user to create and save maximum of 4 channels for free.
  • If you are want access to more channels then you need to make payment for that.

Fig. 17: New Channel

  • Enter the respective details in the channel.

Fig. 18: Fill the channel details

  • Here we are creating two fields. First one represents the temperature and another one is to represent the humidity measured using DHT11 sensor. You can also add more fields as per your requirements.
  • A new URL containing the channel details and channel Stats will open, once you have successfully created the channel. On the same page/url, API keys are available for both read and write services.
  • Go to API Keys and copy the write API key and paste in your Arduino IDE code. So that ESP32 can send or write the DHT sensor readings to the MathWorks server.
  • In Private view your can also customize your chart. To edit the chart, click on the icon present on the top right corner of field chart.
  • Edit the details as per your requirements and click on the Save

Fig. 19: Field Chart Edit

 

Arduino IDE programming

Downloading and installing the required Library file:

    • Follow the link attached below to download the ThingSpeak Arduino library:

https://github.com/mathworks/thingspeak-arduino

  • Open the Arduino IDE.
  • Go to Sketch >> Include Library >> Add .ZIP Library and select the downloaded zip file.

Fig. 20: Adding ThingSpeak library

To check whether the library is successfully added or not:

  • Go to Sketch >> Include Library >> Manage Libraries

Fig. 21: manage libraries

  • Type thingspeak in the search bar.

Fig. 22: Arduino IDE Library manager.

  • The ThingSpeak library by MathWorks has been successfully downloaded.

Code

//------style guard ----

#ifdef __cplusplus

extern "C" {

#endif

uint8_t temprature_sens_read();

#ifdef __cplusplus

}

#endif

uint8_t temprature_sens_read();

// ------header files----

#include <WiFi.h>

#include "DHT.h"

#include "ThingSpeak.h"

//-----netwrok credentials

char* ssid = "replace this with your SSID"; //enter SSID

char* passphrase = "replace this with your password"; // enter the password

WiFiServer server(80);

WiFiClient client;

//-----ThingSpeak channel details

unsigned long myChannelNumber = 3;

const char * myWriteAPIKey = "replace this with your API key";

//----- Timer variables

unsigned long lastTime = 0;

unsigned long timerDelay = 1000;

//----DHT declarations

#define DHTPIN 4 // Digital pin connected to the DHT sensor

#define DHTTYPE DHT11 // DHT 11

// Initializing the DHT11 sensor.

DHT dht(DHTPIN, DHTTYPE);

 

void setup()

{

Serial.begin(115200); //Initialize serial

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, passphrase);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

// Print local IP address and start web server

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

server.begin();

//----nitialize dht11

dht.begin();

ThingSpeak.begin(client); // Initialize ThingSpeak

}

void loop()

{

if ((millis() - lastTime) > timerDelay)

{

delay(2500);

// Reading temperature or humidity takes about 250 milliseconds!

float h = dht.readHumidity();

// Read temperature as Celsius (the default)

float t = dht.readTemperature();

float f = dht.readTemperature(true);

if (isnan(h) || isnan(t) || isnan(f)) {

Serial.println(F("Failed to read from DHT sensor!"));

return;

}

Serial.print("Temperature (ºC): ");

Serial.print(t);

Serial.println("ºC");

Serial.print("Humidity");

Serial.println(h);

ThingSpeak.setField(1, h);

ThingSpeak.setField(2, t);

// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different

// pieces of information in a channel. Here, we write to field 1.

int x = ThingSpeak.writeFields(myChannelNumber,

myWriteAPIKey);

if(x == 200){

Serial.println("Channel update successful.");

}

else{

Serial.println("Problem updating channel. HTTP error code " + String(x));

}

lastTime = millis();

}

}

Code Description

  • The style guards are used at the beginning of the program to declare some function to be of “C” linkage, instead of “C++” Basically, to allow C++ code to interface with C code.

Fig. 22: Style guard

  • Add the required header files. In this example we are using three libraries, Wi-Fi.h, DHT.h, ThingSpeak.
  • We have already discussed above how to download and add the DHT and ThingSpeak library files to Arduino IDE.

Fig. 23: Libraries

  • Enter the network credentials (SSID and Password) of the access point to which your ESP device is supposed to connect for internet connectivity.

Fig. 24

  • To access the created web server we also need to assign a port and usually port 80 is used for local web server.

Fig. 25: server port

  • A Wi-Fi client is created to connect with ThingSpeak.

Fig. 26

  • Global declaration of timer variables.

Fig. 27: Timer variables

  • Add the channel number and API (Write) Key. If you have created only one channel then the channel number will be ‘1’.

Fig. 28

Setup()

 
    • Initialize the Serial monitor with a 115200 baud rate for debugging purposes.

Fig. 29

  • Set ESP32 Wi-Fi module in station mode using mode() function.
  • Enable ESP32’s Wi-Fi module using begin() function which is passing two arguments SSID and password.
  • Wait until the ESP32 is not connected with the wifi network.

Fig. 30: connect to wifi

  • Once ESP32 is successfully connected to Wi-Fi network, the localIP() function will fetch the IP address of the device.
  • begin() function is used to initialize the server.

Fig.31: Fetch and print IP address

  • Initialize the ThingSpeak server using begin() function that is passing client (globally created) as an argument.

Fig. 32

  • Set the number of fields you have created to the ThingSpeak server. We are adding only two fields. First one represents the humidity measured by the sensor from its surrounding and the 2nd field represents the temperature in degree Celsius.
  • You can also add further fields like for temperature in Fahrenheit, heat index etc.
  • ThingSpeak allow the user to add up to maximum of 8 fields for different readings.

Fig. 33

  • writeFields() function is used to write data to the ThingSpeak server. This function is using the channel number and API key as an argument.

Fig. 34

  • Return the code 200 if the sensor readings are successfully published to ThingSpeak server and print the respective results on the serial monitor.

Fig. 35

Results

  • Copy the above code and paste it into your Arduino IDE.
  • Make the required changes in the above code and the changes required includes, network credentials (SSID and Password), API key, Channel number etc.
  • Compile and upload the above program into ESP32 development after selecting the correct development board and COM port.
  • Make sure the Access Point (Wi-Fi) is ON to which your ESP device is supposed to connect.
  • Open the serial monitor at a 115200 baud rate and press the EN button from the ESP32 development board.

Fig. 35: Results on the Serial monitor

  • Open the channel you have created on the ThingSpeak server.
  • You should see the charts updated with the latest temperature and humidity readings.

Fig. 36: Displaying humidity on thingSpeak server

Fig. 37: Displaying Temperature on ThingSpeak server

This concludes the tutorial. I hope you found this of some help and also hope to see you soon with new tutorial on ESP32.

IoT Based Motion Detection with Email Alert using ESP32

The IoT is the interconnection of physical objects or devices with sensors and software accessing capabilities to communicate data or information over the internet.

To build an IoT network, we need an interface medium that can fetch, control, and communicate data between sender and receiver electronics devices or servers.

Espressif Systems created the ESP32 Wi-Fi chip series. The ESP32 module is equipped with a 32-bit Tensilica microcontroller, 2.4GHz Wi-Fi connectivity, an antenna, memory, and power management modules, and much more. All of these built-in features of this ESP32 module make it ideal for IoT applications.

Hello readers, I hope you all are doing great. In this tutorial, we will learn another application of ESP32 in the field of IoT (Internet of Things). We are using a PIR sensor to detect motion and an Email alert will be generated automatically whenever a motion is being detected.

Fig.1

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

Overview

The HCSR-501 sensor module is used with ESP32 to detect the motion. So whenever a motion is detected, the PIR sensor will generate a HIGH output signal which will act as an input to the ESP32 module. In the absence of motion, the output of the PIR sensor will remain LOW. If a HIGH input signal is generated from the PIR sensor module, the LED (either peripheral or inbuilt) will be turned ON and along with that, an Email will be generated to the receiver’s email address as per the program instructions.

Software and Hardware requirements

  • ESP32 development board
  • HCSR-501 PIR sensor module
  • LED
  • Resistor
  • Connecting Wires
  • Sender’s email account details
  • Receiver’s email address
  • ESP-Mail-Client Library

What is HCSR-502 PIR sensor module and how does it work?

Fig. 2 PIR Motion Sensor

PIR stands for Passive Infrared sensors. It detects heat energy in the surrounding environment using a pair of pyroelectric sensors. Both sensors are placed next to each other, and when motion is detected or the signal differential between the two sensors changes, the PIR motion sensor returns a LOW result (logic zero volts). It means that in the code, you must wait for the pin to go low. The desired function can be called when the pin goes low.

There are two potentiometers available in the HCSR-501 PIR motion sensor module. One of the potentiometers is to control the sensitivity to the IR radiations. Lower sensitivity indicates the presence of a moving leaf or a small mouse. The sensitivity can be changed depending on the installation location and project specifications.

The second potentiometer is to specify the duration for which the detection output should be active. It can be programmed to turn on for as few as a few seconds or as long as a few minutes.

PIR sensors are used in thermal sensing applications such as security and motion detection. They're commonly found in security alarms, motion detection alarms, and automatic lighting applications.

SMTP

The simple mail transfer protocol (SMTP) is an internet standard for sending and receiving electronic mail (or email), with an SMTP server receiving emails from email clients.

SMTP is also used to establish server-to-server communication.

Gmail, Hotmail, Yahoo, and other email providers all have their own SMTP addresses and port numbers.

Fig. 3 SMTP

How does SMTP work?

To send emails, the SMTP protocol, also known as the push protocol, is used, and IMAP, or Internet Message Access Protocol (or post office protocol or POP), is used to receive emails at the receiver end.

The SMTP protocol operates at the application layer of the TCP/IP protocol suite.

When the client wants to send emails, a TCP connection to the SMTP server is established, and emails are sent over the connection.

SMTP commands:

  • HELO – This command is sent only once per session and it is used to identify the qualified domain names and the client to the server.
  • MAIL – used to initiate a message
  • RCPT – Identifies the address
  • DATA – This command is responsible for sharing data line by line

SMTP server parameters for email service

There are various email service providers available like, Gmail, Yahoo, Hotmail, Outlook etc. and each service provider have unique service parameters.

In this tutorial, we are using the Gmail or Google Mail service.

Gmail is the email service provided by Google and Gmail SMTP server is free to access and anyone can access this service, who has a Gmail account.

  • SMTP server: smtp.gmail.com
  • SMTP port: 465
  • SMTP sender’s address: Gmail address
  • SMTP sender's password: Gmail Password

Create a new Gmail account (Sender)

It is recommended to create a new email account for sending emails using ESP32 or ESP8266 modules.

If you are using your main (personal) email account (for sending emails) with ESP and by mistake something goes wrong in the ESP code or programming part, your email service provider can ban or disable your main (personal) email account.

In this tutorial we are using a Gmail account.

Follow the link to create a new Gmail account : https://accounts.google.com

Fig. 4 create new gmail account

Access to Less Secure apps

To get access to this new Gmail account, you need to enable Allow less secure apps and this will make you able to send emails. The link is attached below:

https://myaccount.google.com/lesssecureapps?pli=1

Fig. 5 permission to less secure apps

Interfacing ESP32 and HCSR-501

Table 1

Fig. 6 ESP32 and HCSR-501 connections

Arduino IDE Programming

We are using Arduino IDE to compile and upload code into ESP32 module. To know more about ESP32 basics, Arduino IDE and how to use it, follow our previous tutorial i.e., on ESP32 programming series. Link is given below:

https://www.theengineeringprojects.com/2021/11/introduction-to-esp32-programming-series.html

Necessary Library

To enable the email service in ESP32 it is required to download the ESP-Mail-Client Library. This library makes the ESP32 able to send email over SMTP server.

Follow the steps to install the ESP-Mail-Client library:

  1. Go to the link and download the ESP-Mail-Client library:

https://github.com/mobizt/ESP-Mail-Client

  1. Open your Arduino IDE.
  2. Then to add the ZIP file go to Sketch >> Include Library >> Add.ZIP Library and select the downloaded ZIP file.

Fig. 7 Adding ESP-Mail-Client Library

  1. Click on

Arduino IDE Code

//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1

//----Add the header files

#include <WiFi.h>

#include <ESP_Mail_Client.h>

//-----define network credentials

#define WIFI_SSID "public"

#define WIFI_PASSWORD "ESP32@123"

//--add the Server address and port number with respect to a particular email service provider

#define SMTP_HOST "smtp.gmail.com"

#define SMTP_PORT esp_mail_smtp_port_587 //port 465 is not available for Outlook.com

 

//----The log in credentials

#define AUTHOR_EMAIL "techeesp697@gmail.com"

#define AUTHOR_PASSWORD "Tech@ESP123"

//----The SMTP Session object used for Email sending

SMTPSession smtp;

//---Declare the message class

SMTP_Message message;

//---Callback function to get the Email sending status

void smtpCallback(SMTP_Status status);

const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n"

"-----END CERTIFICATE-----\n";

int inputPin = 4; // connect with pir sensor pin

int pir_output = 0; // variable to store the output of PIR output

void setup()

{

pinMode(inputPin, INPUT);

pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(115200);

pir_output = digitalRead(inputPin);

Serial.println();

Serial.print("Connecting to AP");

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED)

{

Serial.print(".");

delay(200);

}

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

Serial.println();

/** Enable the debug via Serial port

* none debug or 0

* basic debug or 1

*

* Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h

*/

smtp.debug(1);

/* Set the callback function to get the sending results */

smtp.callback(smtpCallback);

/* Declare the session config data */

ESP_Mail_Session session;

/* Set the session config */

session.server.host_name = SMTP_HOST;

session.server.port = SMTP_PORT;

session.login.email = AUTHOR_EMAIL;

session.login.password = AUTHOR_PASSWORD;

session.login.user_domain = "mydomain.net";

/* Set the NTP config time */

session.time.ntp_server = "pool.ntp.org,time.nist.gov";

session.time.gmt_offset = 3;

session.time.day_light_offset = 0;

/* Set the message headers */

message.sender.name = "ESP Mail";

message.sender.email = AUTHOR_EMAIL;

message.subject = "Email Alert on Motion detection";

message.addRecipient("Anonymous",

"replace this with receiver email adderss");

String textMsg = "Motion Detected!!!!!";

message.text.content = textMsg;

message.text.charSet = "us-ascii";

message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;

/* Set the custom message header */

message.addHeader("Message-ID: <abcde.fghij@gmail.com>");

/* Connect to server with the session config */

if (!smtp.connect(&session))

return;

}

void loop()

{

if (pir_output == HIGH)

{

//----Start sending Email and close the session

if (!MailClient.sendMail(&smtp, &message))

Serial.println("Error sending Email, " + smtp.errorReason());

digitalWrite(LED_BUILTIN, HIGH);

Serial.println("Motion detected!");

Serial.println("Email sent");

}

else {

digitalWrite(LED_BUILTIN, LOW);

Serial.println("No Motion detected!");

}

delay(1000);

ESP_MAIL_PRINTF("Free Heap: %d\n", MailClient.getFreeHeap());

//to clear sending result log

smtp.sendingResult.clear();

}

/* Callback function to get the Email sending status */

void smtpCallback(SMTP_Status status)

{

/* Print the current status */

Serial.println(status.info());

/* Print the sending result */

if (status.success())

{

Serial.println("----------------");

ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());

ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());

Serial.println("----------------\n");

struct tm dt;

for (size_t i = 0; i < smtp.sendingResult.size(); i++)

{

/* Get the result item */

SMTP_Result result = smtp.sendingResult.getItem(i);

time_t ts = (time_t)result.timestamp;

localtime_r(&ts, &dt);

ESP_MAIL_PRINTF("Message No: %d\n", i + 1);

ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");

ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);

ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);

ESP_MAIL_PRINTF("Subject: %s\n", result.subject);

}

Serial.println("----------------\n");

//You need to clear sending result as the memory usage will grow up as it keeps the status, timstamp and

//pointer to const char of recipients and subject that user assigned to the SMTP_Message object.

//Because of pointer to const char that stores instead of dynamic string, the subject and recipients value can be

//a garbage string (pointer points to undefind location) as SMTP_Message was declared as local variable or the value changed.

smtp.sendingResult.clear();

}

}

Note: The exact code cannot be used. As a result, before uploading the code, you must make some changes such as replacing the SSID and password with your network credentials, email address of sender and receiver, SMTP setting parameters for respective email service providers, and so on. We'll go over these details as well during the code description.

Code Description

  • The first step is adding the required header files or libraries.
  • Here we are using two libraries:
    • The first one is h, which is used to enable the Wi-Fi module and hence wireless network connectivity.
    • Another library file required is the h to enable email service over SMTP (simple mail transfer protocol).

Fig. 8

  • Enter the network credentials in place of SSID and PASSWORD.

Fig. 9

  • Enter the SMTP parameter of the respective email service provider like, Gmail, Yahoo, Outlook, Hotmail etc. (In this tutorial we are using Gmail service).
  • Parameters used below are for Gmail.

Fig. 10

  • Enter the sender’s email login details (email address and password ).

Fig. 11

  • Insert recipient’s email address.

Fig. 12

  • SMTPSession object is used for sending emails.

Fig. 13

  • Next step is declaring a message

Fig. 14

  • This smtpCallback() function is used to get the email sending status.

Fig. 15

  • This function also includes printing the results like success and failure of email sent.

Fig. 16

  • Next we are defining a variable to store the GPIO pin number to which the PIR sensor is to be connected.
  • Next variable pir_output is used to store the current state of PIR output and initially it is fixed to zero.

Fig. 17 Variable for PIR sensor

Setup()

  • Initialize the serial monitor at 115200 baud rate for debugging purpose.
  • Set the mode as INPUT for the GPIO pin to which PIR module is to be connected i.e., GPIO 4.
  • We are using the built-in LED (LED turns ON when a motion is detected.
  • The digitalRead() function is used to read the output of PIR sensor module, by passing the GPIO pin (to which PIR sensor is connected) as an argument and results will be stored inside pir_output

Fig. 18

  • begin() function is used to initialize the Wi-Fi module with Wi-Fi credentials used as arguments.
  • The While loop will continuously run until the ESP32 is connected to Wi-Fi network.

Fig. 19

  • If the device is connected to local Wi-Fi network then print the details on serial monitor.
  • localIP() function is used to fetch the IP address.
  • Print the IP address on serial monitor using println() function.

Fig. 20

  • debug() is used to enable the debug via Serial port where ‘0’ and ‘1’ are used as arguments where;
    • 0 - none debug
    • 1 - basic debug
  • Inside ESP_Mail_FS.h header file, ESP_MAIL_DEFAULT_DEBUG_PORT can be used to change the Debug port.
  • Set the callback() function to get sending results.

Fig. 21

  • Setting session configuration includes, assigning the server address, port number of the server (here we are using Gmail services), email login details of the sender etc.

Fig. 22

  • Next step is setting the message header.
  • Message header will be set inside the setup() function which includes, sender’s name, subject, sender’s email address, receiver’s email address and name.
  • A string type variable textMsg is defined to to store the message to be transferred over email.

Fig. 23

  • connect() function.is used to connect to server with session configuration.

Fig. 24

Loop

  • ESP32 is continuously checking for the input from PIR sensor inside the loop function.
  • If the input received from pir sensor is HIGH the ESP32 will generate an email to the client for that sendMail() function is used and if mail transmission is failed then that will be printed on the serial monitor along with the reason.
  • The inbuilt LED on ESP32 will be turned ON and the respective results will be printed on the serial monitor.

Fig. 25 ‘If motion detected’

  • If the input received from the PIR sensor is LOW then the LED will remain LOW/OFF and no email alert will be generated.

Fig. 25 No motion detected

  • Finally, clear the email log to avoid excessive memory usage.

Fig. 26 Clear the email log

Testing

  • Open the Arduino IDE.
  • Paste the above code into your Arduino IDE.
  • Make the required changes in the code like, network credentials, email service parameters of the respective email service provider, sender and receiver email address and define the message you want to share over SMTP server.
  • Select the right development board and COM port for serial communication.

Fig. 27 select development board and COM port

  • Compile and upload the program into the ESP32 development board.
  • Connect the HCSR-501 module with the ESP32 as per the circuit/connect details given above.

Fig. 28 ESP32’s Inbuilt LED is turned ON when a motion is detected

  • Open the serial monitor with 115200 baud rate.

Fig. 29 Serial monitor

  • Check the receiver email account.

Fig.30 received email on motion detection

This concludes the tutorial. We hope you found this of some help and also hope to see you soon with a new tutorial on ESP32.

ESP32 with 16x2 LCD in Arduino IDE | Data Mode & I2C Mode

Hello readers, we hope you all are doing great. Welcome to the 1st lecture of Section 4 in the ESP32 Programming Series. In this section, we will interface the ESP32 module with common Embedded modules(i.e. LCD, Keypad, RTC etc.).

In today's tutorial, we will interface ESP32 with a 16x2 LCD and will display data using both Data Mode and I2C Mode. LCD is the most commonly used embedded module in IoT Projects. It is used to display different types of data i.e. sensor readings, warning messages, notifications etc.

Before going forward, let's first have a look at what is LCD and How it works:

Where To Buy?
No.ComponentsDistributorLink To Buy
1ESP32AmazonBuy Now

16x2 LCD Module

LCD(Liquid Crystal Display) is a type of electronic display module that is used in a wide variety of applications and devices such as calculators, computers, mobile phones, TVs, etc. There are different types of LCDs available for commercial use. Today, we are going to use the most simple one i.e. 16x2 LCD, shown in the below figure:

This 16x2 LCD has 16 columns and 2 rows, so in total of 32 blocks to display characters. Each Block can display a single character at a time. We can display text in different styles on this LCD i.e. blinking, scrolling etc. Another variant of this LCD is 20x4 LCD and as the name suggests, it has 20 columns and 4 rows and so can display 80 characters at a time. The operating principle of both of these LCDs is quite similar. So, if you are working with a 20x4 LCD, you can still follow this tutorial.

Let's have a look at the LCD pinout:

LCD Pinout

Both 16x2 and 20x4 LCDs have 16 pins each, used to control 7 write on these LCDs. Among these 16 pins, we have:

  • 8 Data Pins(Pin7-14)
  • 2 LCD Power Pins(Pin1 and 2)
  • 2 Backlight LED Power Pins(Pin15 and 16)
  • 1 Contrast Pin(Pin3)
  • 1 Enable Pin(Pin6)
  • 2 Selection Pins(Pin4 and 5)

LCD Pinout and its working is shown in the below table:

LCD Pinout
Pin No. Name Working
1
GND(Ground)
Connected to Ground Terminal.
2
Vcc(+5V)
Connected to +5V.
3
VE
To Control the LCD Contrast.
4
RS(Register Select) If RS=0(GND), LCD operates in Data Mode and we can write characters on the LCD.
If RS=1(+5V), LCD Command Mode gets activated and we can send commands to LCD i.e. erase, new line etc..
5
R/W(Read & Write) R/W=0(GND) enables the write operation on the LCD. (So, we normally keep this pin LOW, as we are interested in printing on the LCD).
R/W=1(+5V) enables the read operation on the LCD.
6
EN(Enable)
Enables the LCD to operate, so it should be kept HIGH.
7
Data Pin 0
LCD has a total of 8 Data Pins(D0-D7)
8
Data Pin 1
9
Data Pin 2
10
Data Pin 3
11
Data Pin 4
12
Data Pin 5
13
Data Pin 6
14
Data Pin 7
15
LED+
Connected to +5V. Turn on the backlight LED.
16
LED-
Connected to GND.

Now, let's interface the LCD with ESP32:

Interfacing LCD with ESP32

There are two methods to interface ESP32 with a 16x2 LCD:

  • Data Mode
  • I2C Mode

In the Data Mode, we use the LCD Data Pins and send data serially, while in the I2C mode, we solder an I2C adapter with the LCD, which acts as a bridge and maps I2C data coming from the microcontroller to the Data Pins. Let's first interface ESP32 and LCD via Data Pins:

LCD with ESP32 in Data Mode

As we discussed earlier, LCD has 8 Data Pins used to communicate with the Microcontroller. There are two ways to send data from the Microcontroller to the LCD:

  1. 4-Pin Method: In this method, we use 4 Data Pin of LCD(D0-D3) to get data from the microcontroller.
  2. 8-Pin Method: In this method, we use all the 8 Data Pins of LCD(D0-D7) to communicate with the microcontroller.

In complex projects, where you are dealing with multiple sensors & modules, its quite difficult to spare 8 Pins for LCD interfacing. So, normally 4-Pin method is preferred, which we are going to design next:

    Components Required

    Here are the components required to interface LCD with ESP32:

    1. ESP32 Development Board
    2. 16x2 LCD
    3. Potentiometer(To set the LCD Contrast)
    4. Jumper wires
    5. Breadboard

    Now, let's design the ESP32 LCD Circuit Diagram:

    Circuit Diagram

    • The circuit diagram of LCD interfacing with ESP32 via data pins is shown in the below figure:

    [Image]

    As you can see in the above figure:

    • Pin1 of the LCD is connected to the GND of ESP32.
    • Pin2 of the LCD is connected to the VIN of ESP32.
    • Pin3 of the LCD is connected to the Output Pin of the potentiometer,  the other two Pins of the Potentiometer are connected to Vcc and GND. So, we can change the voltage at this Pin3 from 0-5V by rotating the potentiometer's knob. You have to manually set its value to make the LCD text visible.

    Here's our hardware setup for ESP32 LCD Interfacing:

    [Image]

    Now let's design the Programming Code to print a simple message on the LCD:

    ESP32 Code for LCD

    We are using Arduino IDE to compile and upload code in the ESP32 module. If you haven't installed it yet, please read How to Install ESP32 in Arduino IDE. Here's the code to print a message on the LCD:

    #include 
    LiquidCrystal lcd(22,23,5,18,19,21);
    
    void setup()
    {
        lcd.begin(16, 2);
        lcd.clear();
    
        // go to row 0 column 5, note that this is indexed at 0
        lcd.setCursor(5,0);
        lcd.print("ESP32");
    
        // go to row 1 column 0, note that this is indexed at 0
        lcd.setCursor(0,1);
        lcd.print (" TheEnggProjects");
    }
    
    void loop()
    {
    }

    Code Description

    • The first step is to include the required library files. LiquidCrystal is the official Arduino Library to control the LCD.
    #include 
    • Next, we are initializing an "lcd" object of type "LiquidCrystal",  it takes the data and control pins as arguments.

    LiquidCrystal lcd(22,23,5,18,19,21);
    

    Setup() Function

    In the Setup() Function:

    • First of all, we initialized the 16x2 LCD using the begin() function. It takes the no of columns & rows of the LCD as an argument.

    lcd.begin(16, 2);
    

    So, if you are using a 20x4 LCD, you should change its arguments to 20 and 4, as shown below:

    lcd.begin(20, 4);
    • Next, we cleared the LCD screen, so if there's any garbage data printed on the LCD, it will be removed:

    lcd.clear();
    • setCursor command is used to set the LCD cursor at the specified position. Its first argument is "column position" and the second argument is "row position". In our case, we have set the Cursor at 6th Column and 1st Row. So, now when we print our message, it will be printed from this position.

    lcd.setCursor(5,0);
    • Finally, we printed our first message on the LCD using the print() command. The message string to be printed on the LCD is provided as an argument.

    lcd.print("ESP32");
    • At the end, we set the cursor.at 1st column & 2nd row, and printed the text:

    lcd.setCursor(0,1);
    lcd.print (" TheEnggProjects");
    

    As you can see, the LCD code is quite simple and I hope now you can easily print on the LCD. So, let's check the results:

    Results

    • Select the right development board from Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • IF everything goes fine, your text messages will get printed on the LCD at the specified locations, as shown in the below figure:

    Common Errors faced while working on 16*2 LCD:

    • Texts are not visible: Backlight is ON but the texts are not visible (after uploading the code) as shown in the image below. To resolve this issue:
      • Check the potentiometer, whether it is connected properly or not.
      • Adjust the value of potentiometer to control brightness of the display.

    Fig. 6

    Only a single row with dark blocks is visible.

    Sol. : Check the EN pin.

    Fig. 7

    This concludes the tutorial. We hope you found this of some help and also hope to see you soon with a new tutorial on ESP32.

    Motion Detection with ESP32 & PIR Sensor

    Hello readers, we hope you all are doing great. Welcome to the 4th lecture of Section 5(ESP32 Sensor) in the ESP32 Programming Series. So far, we have discussed the ESP32 built-in sensors in this section. Today, we are going to interface an external embedded sensor(i.e. PIR Sensor) with the ESP32 Microcontroller board. At the start, we will discuss the basics of a PIR Sensor(HC-SR501) i.e. its pinout and working. After that, we will design a simple project to detect the motion with a PIR sensor and ESP32. Finally, we will display the motion detection results on the ESP32 WebServer.

    We will use ESP32 interrupts to detect the motion. Interrupts are used when a microcontroller needs to continuously monitor an event while executing other tasks at the same time. We have already posted a tutorial on ESP32 Interrupts, which includes both software and hardware interrupts. In this tutorial, we are implementing the hardware interrupt(Hardware interrupts are the external interrupts that are caused by an external event). In our project, the hardware interrupt will be generated by the PIR sensor.

    PIR motion sensor is mostly used in home automation & security projects, used to enable the system to respond automatically over human presence. Appliances connected to ESP32 will respond automatically(as per the instructions provided) whenever an interrupt is triggered by the PIR motion sensor. Let's first have a look at the working of PIR Sensor:

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1ESP32AmazonBuy Now

    What is a PIR Motion Sensor?

    In today's project, we will use the HC-SR501 PIR Sensor to detect the motion. PIR stands for Passive Infrared sensors. It uses a pair of pyroelectric sensors to detect heat energy in the surrounding environment. Both the sensors sit beside each other, and when a motion is detected or the signal differential between the two sensors changes the PIR motion sensor will return a LOW result (logic zero volts). It means that you must wait for the pin to go low in the code. When the pin goes low, the desired function can be called.

    PIR Sensor Calibration

    PIR Sensor has two variable resistors on its back side, used to adjust the Sensitivity and Detection Range, explained below:

    • Low sensitivity ignores the small motions i.e. a moving leaf or a small mouse. The sensitivity can be adjusted based on the installation location and project requirements.
    • The second resistor is used to specify how long the detection output should be active. It can be set to turn on for as little as a few seconds or as long as a few minutes.

    PIR Sensor Applications

    Thermal sensing applications, such as security and motion detection, make use of PIR sensors. They're frequently used in security alarms, motion detection alarms, and automatic lighting applications.

    Now let's interface the PIR Sensor with ESP32:

    Interfacing PIR Sensor with ESP32

    As I mentioned earlier, in today's project, we will design a motion detection project with ESP32 and PIR Sensor. In the first example, we will turn "ON" the LED on motion detection, while in the second project, we will display the results in the ESP32 WebServer.

    Here's the list of the components for today's project:

    Components Required

    • ESP32 Development Board
    • PIR motion sensor (HC-SR501)
    • LED
    • 1k Ohm resistor
    • Jumper Wires
    • Breadboard

    Circuit Diagram

    Here's the circuit diagram for motion detection with ESP32 and PIR Sensor:

    Now let's design the programming code for motion detection:

    ESP32 Motion Detection Code

    We are using Arduino IDE to compile and upload code into the ESP32 module. You need to first Install ESP32 in Arduino IDE to get started. Here's the code for motion detection:

    //----Set GPIOs for LED and PIR Motion Sensor
    const int led = 23;
    const int PIRSensor = 4;
    
    // -----Timer: Auxiliary variables
    #define timeSeconds 10
    unsigned long now = millis();
    unsigned long lastTrigger = 0;
    boolean startTimer = false;
    
    //---Checks if motion was detected, sets LED HIGH and starts a timer
    void IRAM_ATTR detectsMovement()
    {
        Serial.println( " MOTION DETECTED " );
        Serial.println("Turning ON the LED");
        digitalWrite(led, HIGH);
        startTimer = true;
        lastTrigger = millis();
    }
    
    void setup()
    {
        Serial.begin( 115200 ); // Serial port for debugging purposes
        pinMode( PIRSensor, INPUT_PULLUP ); // PIR Motion Sensor mode INPUT_PULLUP
        pinMode( led, OUTPUT );
        digitalWrite( led, LOW );
        attachInterrupt( digitalPinToInterrupt( PIRSensor ), detectsMovement, FALLING ); // Set PIRSensor pin as interrupt, assign interrupt function and set RISING mode
    }
    
    void loop()
    {
        now = millis();
        if( startTimer && (now - lastTrigger > ( timeSeconds*500)))
        {
            Serial.println(" Turning OFF the LED " );
            digitalWrite( led, LOW );
            startTimer = false;
        }
    }
    

    Variables Declaration

    • The first step is to set up the GPIO pins for the LED and motion sensor(PIR).
    • LED is connected to GPIO23 and PIR sensor to GPIO4, as shown in the below code:
    //----Set GPIOs for LED and PIR Motion Sensor
    const int led = 23;
    const int PIRSensor = 4;
    • Next, we need variables to set the timer to count the time, after the interrupt is detected.
    • The variable "now" defines the current time
    • The variable "lastTrigger" defines the time when the interrupt is detected.
    • The variable "startTimer" is used to start the time when an interrupt is detected.
    //-----Timer: Auxiliary variables
    #define timeSeconds 10
    unsigned long now = millis();
    unsigned long lastTrigger = 0;
    boolean startTimer = false;

    ESP32 Interrupt Function "IRAM_ATTR"

    • The Function with the attribute "IRAM_ATTR" is executed inside the internal RAM.
    • We are assigning this attribute to our interrupt function because RAM (random access memory) operates faster than flash memory.
    • After the execution of the interrupt code or ISR, the normal code will be executed inside the flash memory.
    • It is recommended that the interrupt service routine should have the minimum possible execution time because it halts or blocks the normal program execution.
    //---Checks if motion was detected, sets LED HIGH and starts a timer
    void IRAM_ATTR detectsMovement()
    {
        Serial.println( " MOTION DETECTED " );
        Serial.println("Turning ON the LED");
        digitalWrite(led, HIGH);
        startTimer = true;
        lastTrigger = millis();
    }

    Setup() Function

    • Inside the setup() function we are initializing the serial communication with a baud rate of 115200.
    • Set the mode of pin GPIO23 (LED) as output.
    • Set the initial state of the LED as LOW.
    • Assigned the digital pin(connected to the PIR Sensor) to hardware interrupt using the attachInterrupt function.
    • The detectMovement function is passed as an argument inside this function.
    void setup()
    {
        Serial.begin( 115200 ); // Serial port for debugging purposes
        pinMode( PIRSensor, INPUT_PULLUP ); // PIR Motion Sensor mode INPUT_PULLUP
        pinMode( led, OUTPUT );
        digitalWrite( led, LOW );
        attachInterrupt( digitalPinToInterrupt( PIRSensor ), detectsMovement, FALLING ); // Set PIRSensor pin as interrupt, assign interrupt function and set RISING mode
    }

    Loop() Function

    We have activated the interrupt in the Setup Function, so when the PIR Sensor detects the motion, it will automatically execute the interrupt function, which will turn the LED ON and start the timer.

    • In the loop function, we are comparing the current time with the last triggered time.
    • LED will turn off after a delay of 5sec (once an interrupt is detected).
    • The variable “now” will be updated with the current time in each iteration.
    void loop()
    {
        now = millis();
        if( startTimer && (now - lastTrigger > ( timeSeconds*500)))
        {
            Serial.println(" Turning OFF the LED " );
            digitalWrite( led, LOW );
            startTimer = false;
        }
    }

    Motion Detection Results/Testing

    • Select the right development board from Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Open the serial monitor with a 115200 baud rate as defined in the Arduino code.
    • Press the EN button on the ESP32 development board.

    This concludes the tutorial. I hope you find this tutorial helpful. Thanks for reading. See you soon with a new tutorial on ESP32. Take care !!!

    Servo Motor Control with ESP32 WebServer

    Hello readers, we hope you all are doing great. In this tutorial, we are going to demonstrate how to interface and control a servo motor using an ESP32 board. After that, we will demonstrate how to create a webserver to control the servo motor’s shaft position with the ESP32 board.

    Servo Motors are among the most important actuators in robotics, with applications ranging from RC planes to automated door locks.

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1ESP32AmazonBuy Now

    Hardware components required

    • A servo motor
    • ESP32 development board
    • Connecting wires
    • Breadboard

    Servo Motor

    There are several specific types of electric motor applications in which the motor must rotate only at a specific angle. For such applications, we need a special type of motor with such a special arrangement that causes the motor to rotate at a specific angle for a given electric signal (input). The servo motor comes into effect for this purpose.

    A servo motor is a linear or rotary actuator that enables accurate control of linear or angular position, acceleration, and velocity. It is made up of a motor and a sensor for position feedback. It also necessitates a fairly sophisticated controller, which is frequently a dedicated module designed specifically for use with servo motors.

    Fig. Servo Motor

    The primary reason to use a servo motor is that it offers angular precision, which means that it will only rotate as far as we want it to before stopping and waiting for the next signal to take action. The servo motor, unlike a standard electric motor, begins to turn as soon as we apply input power to it and continues to rotate until we turn off the power. We cannot restrict the rotational progress of an electric motor, but we can control its speed and turn it on and off. Small servo motors are included in numerous beginner Arduino launcher kits since they are simple to use in small electronic projects and applications.

    Interfacing Servo Motor with ESP32

     

    Fig. Interfacing Servo motor with ESP32

    When compared to an Arduino, interfacing a servo motor to the ESP32 is extremely difficult because it does not support analogWrite(). However, it employs a variety of frequencies and timers, allowing all digital pins to be used as PWM pins and to send signals much faster than any Arduino.

    Connections:

    Servo motor consists of three wires;

    Table 1 ESP32 and servo motor interfacing

    Controlling servo motor

    A servo motor is controlled by sending a PWM or pulse width modulated signal. A servo motor can only turn for a total of 180-degree movement (90 degrees in either direction).

    The PWM signal sent to the motor specifies the position of the shaft, and the rotor will turn to the desired position depending on the duration of the pulse sent through the control wire.

    Arduino IDE programming

    We are using Arduino IDE to compile and upload code into the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on the ESP32 programming series.

    • Installing Required Libraries
    • Download the library from the given link:

    https://github.com/RoboticsBrno/ServoESP32

    • Open the Arduino IDE.
    • Go to Sketch >> Include Library >> Add .ZIP library.
    • Select the zip file you have downloaded from the above link.

    Fig. Adding Library file

    Arduino IDE Code

    • We are using the example code that comes with the library file we have downloaded for the above link.
    • To access the example code, go to Files >> Examples >> Servo ESP32 and select the required example code.
    • In this tutorial, we are using a simple servo example code.

    #include <Servo.h>

    static const int servoPin = 4;

    Servo servo1;

    void setup()

    {

    Serial.begin( 115200 );

    servo1.attach( servoPin);

    }

    void loop() {

    for(int posDegrees = 0;

    posDegrees <= 180;

    posDegrees++)

    {

    servo1.write( posDegrees );

    Serial.println( posDegrees );

    delay( 20);

    }

    for(int posDegrees = 180;

    posDegrees >= 0;

    posDegrees--)

    {

    servo1.write( posDegrees);

    Serial.println( posDegrees);

    delay(20);

    }

    }

    Code Description

      • The first task is adding the required library files or header files.

    Fig. header file

    • Define the GPIO pin which you are going to use for controlling the servo motor.

    Fig. Defining Variables

    • Create an object Servo, which is called

    Setup()

    • Inside the setup() function, the first task is to initialize the serial monitor with a 115200 baud rate for debugging purposes.
    • Attach the GPIO pin you have assigned to the variable servoPin (in the global declaration) to the servo object.

    Fig. setup function

    Loop()

    • As we mentioned earlier, a servo motor can only rotate between 0 to 180 degrees. So in this code, we are changing the position of the servo motor from 0 degree to 180 degrees and then back to 0 degree from 180 degrees.
    • We have defined a variable postDegree to store the position or angle of the servo motor.
    • We are using the for() loop, which will change the position of servo motor from 0 to 180 degrees.

    Fig.

    • Another for() loop is used to change the position back to 0 degrees from 180 degrees.

    Testing

    • Select the right development board from Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Open the serial monitor with a 115200 baud rate as defined in the Arduino code.
    • Press the EN button from the ESP32 development board.
    • Now you should see the servo motor’s shaft rotating as per the instructions provided.
    • You can observe the variation on shaft’s angle on the serial monitor as well, as shown below:

    Fig. Serial monitor output

    Fig. ESP32 and servo motor

    Creating a web server to control servo motor with ESP32

    Let’s create a web server to control the position of the servo motor. We will create a web page containing a slider to control the angle/position of the servo motor’s shaft.

    We have also created a tutorial on creating a simple web server with ESP32.

    Arduino IDE Code

    #include <WiFi.h>

    #include <Servo.h>

    Servo servo1; // create servo object to control a servo

    // twelve servo objects can be created on most boards

    // GPIO the servo is attached to

    static const int servoPin = 13;

    // Replace with your network credentials

    const char* ssid = "SSID";

    const char* password = "PASSWORD";

    // Set web server port number to 80

    WiFiServer server(80);

    // Variable to store the HTTP request

    String header;

    String valueString = String(5);

    int angle_x = 0;

    int angle_y = 0;

    // Current time

    unsigned long currentTime = millis();

    // Previous time

    unsigned long previousTime = 0;

    // Define timeout time in milliseconds (example: 2000ms = 2s)

    const long timeoutTime = 2000;

    void setup() {

    Serial.begin(115200);

    servo1.attach(servoPin); // attaches the servo on the servoPin to the servo object

    // Connect to Wi-Fi network with SSID and password

    Serial.print("Connecting to ");

    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

    }

    // Print local IP address and start web server

    Serial.println("");

    Serial.println("WiFi connected.");

    Serial.println("IP address: ");

    Serial.println(WiFi.localIP());

    server.begin();

    }

     

    void loop(){

    WiFiClient client = server.available(); // Listen for incoming clients

    if (client) { // If a new client connects,

    currentTime = millis();

    previousTime = currentTime;

    Serial.println("New Client."); // print a message out in the serial port

    String currentLine = ""; // make a String to hold incoming data from the client

    while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected

    currentTime = millis();

    if (client.available()) { // if there's bytes to read from the client,

    char c = client.read(); // read a byte, then

    Serial.write(c); // print it out the serial monitor

    header += c;

    if (c == '\n') { // if the byte is a newline character

    // if the current line is blank, you got two newline characters in a row.

    // that's the end of the client HTTP request, so send a response:

    if (currentLine.length() == 0) {

    // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)

    // and a content-type so the client knows what's coming, then a blank line:

    client.println("HTTP/1.1 200 OK");

    client.println("Content-type:text/html");

    client.println("Connection: close");

    client.println();

    // Display the HTML web page

     

    client.println("<!DOCTYPE html><html>");

    client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");

    client.println("<link rel=\"icon\" href=\"data:,\">");

    // CSS to style the slider

    // Feel free to change the background-color and font-size attributes to fit your preferences

    client.println("<style>body { text-align: justify; font-family: \"Trebuchet MS\", Arial; margin-left:auto; margin-right:auto;}");

    client.println(".slider { width: 600px; }</style>");

    client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");

    // Styling Web Page

    client.println("</head><body><h1>Control Servo via ESP32</h1>");

    client.println("<p>Angle: <span id=\"servoPos\"></span></p>");

    client.println("<input type=\"range\" min=\"0\" max=\"180\" class=\"slider\" id=\"servoSlider\" onchange=\"servo(this.value)\" value=\""+valueString+"\"/>");

    client.println("<script>var slider = document.getElementById(\"servoSlider\");");

    client.println("var servoP = document.getElementById(\"servoPos\"); servoP.innerHTML = slider.value;");

    client.println("slider.oninput = function() { slider.value = this.value; servoP.innerHTML = this.value; }");

    client.println("$.ajaxSetup({timeout:2000}); function servo(pos) { ");

    client.println("$.get(\"/?value=\" + pos + \"&\"); {Connection: close};}</script>");

    client.println("</body></html>");

    //GET /?value=180& HTTP/1.1

    if(header.indexOf("GET /?value=")>=0) {

    angle_x = header.indexOf('=');

    angle_y = header.indexOf('&');

    valueString = header.substring(angle_x+1, angle_y);

    //Rotate the servo

    servo1.write(valueString.toInt());

    Serial.println(valueString);

    }

    // The HTTP response ends with another blank line

    client.println();

    // Break out of the while loop

    break;

    } else { // if you got a newline, then clear currentLine

    currentLine = "";

    }

    } else if ( c != '\r' ) { // if you got anything else but a carriage return character,

    currentLine += c; // add it to the end of the currentLine

    }

    }

    }

    // Clear the header variable

    header = "";

    // Close the connection

    client.stop();

    Serial.println("Client disconnected.");

    Serial.println(" ");

    }

    }

    Code Description

    • Replace SSID and PASSWORD with your network credentials.

    Fig. Variables to store Network credentials

    • As we are creating a web server, we need to assign a port to it and normally we use port 80 for a local webserver.
    • So, in the below code, we have assigned port 80 to the web server and then initialized a few variables:

    Fig.

    • header variable is used to store the HTTP requests.
    • Variables angle_x and angle_y are used to store the position/angle of servo motor’s shaft.

    Fig.

    • Variables to store timer values for a delay of 2sec or 2000ms.

    Fig.

    Setup()

    • Inside the setup() function, servoPin is being attached to the servo1 object.

    Fig.

    • Wi-Fi.begin() is used to initialize the ESP32’s wi-fi module.
    • IP address of the device will be fetched once ESP32 is successfully connected to the wi-fi network.
    • begin() function is used to initialize the webserver mode in ESP32.

    Loop()

    • After the webserver has been initialized successfully, the ESP32 server will be continuously waiting for the client connection.

    Fig

    • Once the connection is established between the access point and the client device, the access point will wait for the data input.
    • A string type variable called currentLine has been defined to hold the incoming data from the client.
    • If there is a byte to be read from the client, then it will be stored inside the char type variable

    HTML to display a web page

    • The ESP32 will respond to your browser with HTML (hypertext markup language) code that will be used to construct the web page.
    • HTTP header always starts with a response code e.g.: HTTP/1.1 200 ok
    • An HTML page will be created on the client’s browser, from where the client device can control the position of the servo motor.

    Fig.

    • The next line, which signals that we are transmitting HTML, should always be the first thing we send.
    • Make the web page responsive in any web browser.
     

    Fig.

    • The next task is styling the webpage and the slider.
    • The maximum and minimum angles are 180 and 0 degrees respectively.
    • valueString variable is containing the current angle/position of the slider, fetched from the HTTP request.

    Fig.

    • Close the web connection and clear the header that was used to store the HTTP request header.
    • Print information about the closed web connection on the serial monitor.

    Fig. Close the connection

    Testing

    • Enter the Wi-Fi or network credentials in the code.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Make sure you have selected the right development board and com port before uploading the code.
    • Open the serial monitor with a 115200 baud rate as defined in the Arduino code.
    • Press the EN button from the ESP32 development board.

    Fig. Serial Monitor

    • Copy the IP address from the serial monitor.
    • Open the web browser.
    • Paste the IP address. A webpage to control the position/angle of servo motor will be displayed, as shown below:

    Fig. Web Page

    This concludes the tutorial. I hope you found this of some help and also to see you soon with a new tutorial on ESP32.

    Accessing ESP32 Dual Core

    We are familiar with multiple features of the ESP32 module. Like Wi-Fi capabilities, classic Bluetooth, Bluetooth low energy (BLE), inbuilt sensors etc.

    Hello readers, I hope you all are doing great. We have already mentioned in our previous tutorials that, ESP32 is also featured with a Dual-Core Processor. Which provides better performance and efficiency.

    In this tutorial, we will learn how to use ESP32’s dual cores. ESP32 has two (32-bit each) Tensilica Xtensa LX6 microprocessors namely, core0 and core1 which makes it a powerful dual-core microcontroller and hence stands apart from its predecessors.

    When we compile and upload a code using Arduino IDE, we do not have to worry about which core executes the code. It just runs.

    Fig. 1 ESP32 dual-core processor

    Features of Dual-Core processor

    • Power Efficiency: A single-core processor can rapidly hit 100% of its workload. On the other hand, a dual-core processor allows the efficient allocation of resources with a multitasking environment.
    • Increased Performance to Multithread Programs: Aside from being able to run multiple programs at the same time, dual-core processors can also collaborate to make a single program faster and more efficient. Multithreading allows programmers to send different instructions from the same program into two processing paths. On a single processor with hyper-threading, the program is still limited to the single core's maximum processing speed. However, on a dual-core, this effectively doubles the speed available to that program.
    • Two programs running simultaneously: Two cores allow two programs to run at the same time. The many complex calculations that a computer must perform to create the average browsing experience are difficult to quantify; however, single-core processors only create the illusion of multitasking through technologies such as hyper-threading.
    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1ESP32AmazonBuy Now

    FreeRTOS in ESP32

    A FreeRTOS (real-time operating system) firmware is already available in the ESP32 module. FreeRTOS is helpful in improving the system performance and managing the resources of the module. FreeRTOS allows users to handle several tasks like measuring sensor readings, making a network request, controlling motor speed etc. all of them run simultaneously and independently.

    FreeRTOS offers multiple APIs for different applications. Those APIs can be used to create tasks and make them run on different cores. You need to create tasks to assign a particular part of code to a specific core. You can also prioritize that on which core the code will run. Priority value starts with level_0.

    Accessing ESP32’s both cores using Ardui1no IDE

    Whenever we run a code on Arduino IDE, it runs on core_1 by default.

    • How to check on which core the code is running?

    There is a function you can use to check on which core the code is running on.

    xPortGetCoreID()

    Run the following code in Arduino IDE:

    void setup()

    {

    Serial.begin(115200);

    Serial.print( " setup() is running on: Core_" );

    Serial.println( xPortGetCoreID() );

    delay(1000);

    }

    void loop()

    {

    Serial.print( " loop() is running on: Core_" );

    Serial.println( xPortGetCoreID() );

    delay(1000);

    }

    • Open the serial monitor with a 115200 baud rate.
    • Press the EN button from the ESP32 development board.

    Fig. 2 Serial Monitor

    From the results on the serial monitor, you can see that both setup() function and loop() function are running on core_1.

    Steps to be followed to create a task are:

    • Create a task handle to keep a track of the task created. For example, a task handle named task is created below:

    Fig. 3

    • Inside setup() function, create a task assigned to a specific core. xTaskCreatedPinnedToCore() function is used to create a task assigned to a specific core.

    This function takes seven arguments:

    1. Name of the function to implement the task
    2. Name of the task
    3. Stack size assigned to the task in words (where 1 word = 2 Bytes)
    4. Task Input parameter
    5. Priority of the task
    6. Task handler
    7. Core where the task should run

    Fig. 4

    • Create a function that contains the code for the task you have been created.

    For example, we have created a function named task_code(). Inside the task_code() function a for(;;) loop is used which will create an infinite loop. All the instructions to be given for a particular core to perform a particular task like led blinking, sensor readings etc. will be written inside this for(;;) loop.

    Fig. 5

    • How to delete the created task, during the code execution?

    You can use the function vTaskDelete() during the code execution to delete a task. This function takes the task handle (task) as an argument.

    • Code for creating and assigning the separate task to each core

    In this code we will use two LEDs to be processed by different core.

    TaskHandle_t task1;

    TaskHandle_t task2;

    // Assign GPIOs pins to LEDs

    const int led1 = LED_BUILTIN;

    const int led2 = 25;

    void setup() {

    Serial.begin(115200 );

    pinMode( led1, OUTPUT );

    pinMode( led2, OUTPUT );

    //create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0

    xTaskCreatePinnedToCore(task_1code, // Task function.

    "Task1", // name of task.

    10000, // Stack size of task

    NULL, // parameter of the task

    1, // priority of the task

    &task1, // Task handle to keep track of created task

    1); // pin task to core 1

    delay(1000);

    //create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1

    xTaskCreatePinnedToCore(task_2code, //Task function.

    "task2", //name of task.

    10000, //Stack size of task

    NULL, //parameter of the task

    1, //priority of the task

    &task2, //Task handle to keep track of created task

    0); //pin task to core 0

    delay(1000);

    }

    //task_1code: blinks an LED every 1000 ms

    void task_1code( void * pvParameters ){

    Serial.print( "task1 running on: core " );

    Serial.println( xPortGetCoreID() );

    for(;;)

    {

    digitalWrite( led1, HIGH);

    delay(1000);

    digitalWrite(led1, LOW);

    delay(1000);

    }

    }

    //task_2code: blinks an LED every 500 ms

    void task_2code( void * pvParameters )

    {

    Serial.print( "task2 running on: core " );

    Serial.println(xPortGetCoreID() );

    for(;;){

    digitalWrite(led2, HIGH );

    delay(500);

    digitalWrite(led2, LOW );

    delay(500);

    }

    }

    void loop()

    {

    Serial.print( " loop() is running on: Core " );

    Serial.println( xPortGetCoreID() );

    delay(1000);

    }

    Code Description

    • We have created two task handle to keep track of two different tasks created for each core. Task1 is for core_1 and task2 is for core_0.
    • Although we do not need to create a new task and a task handle for core_1 because the void loop() function be default run on core_1 but for better understanding we are creating a different task for each core.

    Fig. 6

    • Allocate GPIOs to the LEDs. Led1 is the inbuilt one that is connected with GPIO2 (internally) and another one is led2 to be connected with GPIO 25.

    Fig. 7

    Setup()

    • Initialize the serial monitor with a 115200 baud rate for debugging purposes.
    • Set the mode of LEDs as OUTPUT.

    Fig. 8 setup() function

    • Create a task (task1) using xTaskCreatePinnedToCore() This task will take seven parameters which include; the task function namely task_1code(), name of the task, stack size of the task, priority level, task handle (if created), core to which you want to assign the task.

    Fig. 9

    • Create a similar task for another core. We will create a different function for this task namely task_2code() and will pass task_2 as a task handle and the core selected is

    Fig. 10

    • The next step is to create functions to execute the above task for each core.
    • task_1code() function is passed as a parameter in
    • xPortGetCoreID() function is used to fetch the core number on which the current function is running on.
    • This function will make the inbuilt LED (GPIO2) or led1 blink with a delay of 1 second or 1000msec.
    • This for(;;) loop will make led1 blink continuously which is similar to the instructions executed inside loop() function.
    • print() function is used to print the results on the serial monitor for debugging purposes.

    Fig. 11

    • task_2code() function is called for task2.
    • This code will be executed in core0.
    • Led2 (GPIO25) will blink continuously with a delay of 0.5sec.

    Fig. 12

    • Inside the loop function we called the xPortGetCoreID() function to get the core number which is responsible to execute the instructions written inside loop() function

    Fig. 13 loop function

    Testing

    Components required:

    • ESP32 development board
    • Breadboard
    • 2*Jumper wires
    • 1*LED
    • 1*resistor(330 ohms)

    Steps for testing:

    • Connect the LED with ESP32 as shown below:

    Fig. 14 connecting LED with ESP32

    • Upload the code into the ESP32 development board.
    • Open the serial monitor with a 115200 baud rate.
    • Press the EN from the ESP32 development board.
    • Results observed from the serial monitor are shown below:

    Fig. 15 Results on the serial monitor

    • On the serial monitor, we can see that task1 functions are processed by core 1 and task2 is processed by core 0.
    • We have already mentioned that core1 is the default processing core so instructions inside the loop() function are processed by core1.

    This concludes the tutorial. We hope you found this helpful and also hope to see you soon with a new tutorial on ESP32.

    Sending Sensor Readings to Google Sheet Through IFTTT using ESP32

    Hello readers, I hope you all are doing great. In our previous tutorial, we learnt how to make HTTP POST from ESP32 to the IFTTT server.

    In this tutorial, we will learn about another application of the ESP32 module in the field of IoT (Internet of Things). We can publish multiple sensor readings from ESP32 to Google sheets via the IFTTT web service.

    IFTTT is used as a third-party web service to integrate Google sheets with ESP32.

    Fig. 1

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1ESP32AmazonBuy Now

    Creating an IFTTT Account for Integrating ESP32 with Google Sheets

    We are going to create an applet (on the IFTTT server) that is responsible to integrate the Webhooks and Google Sheets services.

    While operating with the IFTTT server there are some services/utilities that we are going to deal with like Applets and Webhooks. Before getting started with the project, let’s first introduce you to those terms:

    Applet

    An Applet is a small application or a utility program, which is used for one or a few simple functions. It connects two or more devices or apps together. An applet provides integration between two devices or services to enable some functionality that those devices or services cannot do alone or on their own. An applet consists of actions and triggers.

    Fig. 2

    Webhooks

    • Webhooks are hypertext transfer protocol (HTTP) callbacks that are defined by the user. They are data and executable commands sent from one app to another over HTTP rather than through the computer's command line. Essentially, it is a method for apps to send automated messages or information to other apps.
    • When an event occurs on the "trigger" application, the app serializes the data and sends it to a webhook URL from the "action" application (the app that processes the data from the "trigger" application). After that, the active application can send a callback message.

    Getting Started with IFTTT:

    1. Enter the following link in the web browser: https://ifttt.com
    2. Login with your Gmail or Facebook accounts for free.
    3. Click on Create icon (top left menu) to create an

    Fig. 3: Creating an Applet

    1. Click on the ”if This” icon.

    Fig. 4: “If This”

    1. Select a service. Search for the Webhooks service and select the respective icon.

    Fig. 5: Search and Select Webhooks

    1. Click on the Receive a web request option to select a trigger option. The trigger will fire every time the maker service receives a web request to notify it of an event.

    Fig. 6: Receive a Web Request

    1. Assign a name to the trigger event and click on Create trigger We have assigned ESP32_GoogleSheets.

    Fig. 7: Create Trigger

    1. Next, click on the “Then That”

    Fig. 8:  Then That

    1. To select the service, search for the Google Sheets service and click on the respective icon.

    Fig. 9:  Google Sheets

     
    1. The next step is selecting an action, click on Add row to the spreadsheet

    Fig. 10: Select an Action

    1. Click on the connect button to connect with the Google Sheet service, if you haven’t connected to it yet.

    Fig. 11: Connect to Google Sheets Service

    1. A new window will pop up, where you need to log in with your Gmail account.
    2. Enter your Gmail account address and password.
    3. Click on Allow icon, (as shown below) to allow the IFTTT web service to access files from your Google drive. So that IFTTT can create new folders or update details in the existing Google drive folders with new sensor readings.

    Fig. 12: Allow IFTTT Service to Access Files of your Google Drive

    1. Finally, complete the action field by assigning the name to the spreadsheet and path the folder in Google drive. Leave the Formatted row as it is (default).
    2. A folder named IFTTT will be created by default if you leave the above fields empty.

    Fig. 13: Complete Action Fields

    1. Click on the finish

    Fig. 14: Applet Successfully Created

    Testing the Applet

    Before interfacing the IFTTT service (applet) with ESP32, let us test the applet whether it is created successfully or not.

    1. Open the following link: https://ifttt.com/maker_webhooks
    2. Click on the Documentation

    Fig. 15

    • A new window will open containing your key (API).
    • Enter the details in To trigger an Event and click on Test it.

    Fig. 16: Test your Applet

    • Open your Google drive.
    • You should see a folder (named IFTTT ) in your Google drive.
    • Open the folder to see the values received from the IFTTT server.

    Fig. 17:  IFTTT Folder in Google Drive

     

    Components Required:

    • ESP32 development board.
    • USB cable to connect to ESP32 development board with the computer.

    No external components are required as we are using the ESP32’s inbuilt sensors to take the readings.

     

    Arduino IDE code

    Let’s have an overview of the project before writing the Arduino code:

    • To access the internet, the ESP connects to the local Wi-Fi network.
    • Then, the Hall sensor will take the readings;
    • Your ESP32 will communicate with the IFTTT Webhooks service that publishes the readings to a spreadsheet on Google Sheets that is saved in your Google Drive’s folder.
    • After publishing the readings, the ESP goes into deep sleep mode for 15 minutes;
    • After 15 minutes the ESP wakes up;
    • After waking up, the ESP connects to Wi-Fi, and the process repeats.
    • We are using Arduino IDE to compile and upload into the ESP32 module. To know more about Arduino IDE and how to use it, follow our previous tutorial i.e., on ESP32 programming series.

    #include <WiFi.h>

    // Replace with your SSID and Password

    const char* ssid = "SSID";

    const char* password = "Password";

    // Replace with your unique IFTTT URL resource

    const char* serverName = "https://maker.ifttt.com/trigger/replace_this_with_eventName/with/key/replace_this_with_your_unique_key ";

    // Maker Webhooks IFTTT

    const char* server="maker.ifttt.com";

    //----Timer for sleep

    uint64_t uS_TO_S_FACTOR = 1000000; // Conversion factor for micro seconds to seconds

    uint64_t TIME_TO_SLEEP = 900; //sleep for 15 minutes

     

    void setup()

    {

    Serial.begin(115200);

    delay(100);

    Serial.print("Connecting to: ");

    Serial.print(ssid);

    WiFi.begin(ssid, password);

    int timeout = 10 * 4; // 10 seconds

    while( WiFi.status() != WL_CONNECTED && ( timeout-- > 0) )

    {

    delay(200);

    Serial.print(".");

    }

    Serial.println(" ");

    if(WiFi.status() != WL_CONNECTED )

    {

    Serial.println(" Failed to connect, going back to sleep ");

    }

    Serial.print("WiFi connected in: ");

    Serial.print(millis());

    Serial.print(", IP address: ");

    Serial.println(WiFi.localIP());

    makeIFTTTRequest();

    // enable timer deep sleep

    esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

    Serial.println("Going to sleep now");

    esp_deep_sleep_start(); // start deep sleep for 900 seconds (15 minutes)

    }

     

    void loop()

    {

    // sleeping so wont get here

    }

    void makeIFTTTRequest()

    {

    Serial.print("Connecting to ");

    Serial.print(server);

    WiFiClient client;

    int retries = 5;

    while(!!!client.connect(server, 80) && (retries-- > 0))

    {

    Serial.print(".");

    }

    Serial.println();

    if(!!!client.connected())

    {

    Serial.println(" Failed to connect... ");

    }

    Serial.print(" Request server: ");

    Serial.println( serverName );

    // Hall sensor values

    String jsonObject = String("{\"value1\":\"") +

    hallRead() +

    "\",\"value2\":\"" + hallRead()

    + "\",\"value3\":\"" +

    hallRead() + "\"}";

    client.println(String("POST ") + serverName + " HTTP/1.1");

    client.println(String("Host: ") + server);

    client.println("Connection: close\r\nContent-Type: application/json");

    client.print("Content-Length: ");

    client.println(jsonObject.length());

    client.println();

    client.println(jsonObject);

    int timeout = 5 * 10; // 5 seconds

    while(!!!client.available() && (timeout-- > 0)){

    delay(100);

    }

    if(!!!client.available()) {

    Serial.println("No response...");

    }

    while(client.available()){

    Serial.write(client.read());

    }

    Serial.println("\nclosing connection");

    client.stop();

    }

    Code Description

    • Add the required header files.
    • WiFi.h header file is used to enable the Wi-Fi module and its respective functions.

    Fig. 18:  Library Files

    • Enter the network credentials, SSID and Password.

    Fig. 19:  Network Credentials

    • Add the IFTT domain name, the event name (you have created) and the API key. The event name we have created is ESP32_test.

    Fig. 20

    • IFTTT Server URL.

    Fig. 21

    • Time_To_Sleep variable is used to set a timer (sleep time) of 15 minutes (900 sec). ESP32 processor will wake up from sleep mode after every 15 minutes to take the sensor readings and publish them to Google Sheets.
    • uS_To_S_Factor is used to store the conversion value for converting the timer unit from microseconds to seconds.

    Note: The ESP32 sleep time should not be very short. A very short sleep time can result in the exceeded limit of requests imposed by the IFTTT service.

    Fig. 22: Timer

     

    Setup()

      • Initialize the Serial monitor with a 115200 baud rate for debugging purposes.

    Fig. 23:  Serial Monitor

    • Enable ESP32’s Wi-Fi module using begin() function which is using SSID and password as arguments.
    • Wait until the ESP32 is not connected to the Wi-Fi network.
    • Fetch the IP address using WiFi.localIP() function.

    Fig. 24:  Wi-Fi

    • makeIFTTTRequest() function is used to connect ESP32 with the client server.

    Fig. 25

    • esp_sleep_enable_timer_wakeup() function is used to enable the timer for sleep mode.
    • The duration of sleep mode is passed as an argument inside the timer function.
    • Esp_deep_sleep_start() function is used to start the sleep mode.

    Fig. 26

    • The below code represents the process happening inside the makeIFTTTRequest()

    Fig. 27

    • ESP32 connects to IFTTT serve and then communicates with the server (IFTTT) through port 80.
    • ESP32 tries 5 times to connect to the server and if it couldn’t then it will enter the sleep mode.

    Fig. 28

    • jsonObject variable is used to store the sensor data to be shared to the Google Sheets via the IFTTT server.
    • We are using ESP32’s inbuilt Hall sensor to take the readings.
    • This variable will take three sensor values and ESP32 will communicate the readings to Google Sheets.

    Fig. 29

    • Connection with the server will be closed once the data is shared successfully and ESP32 will enter to sleep mode form next 15 minutes.

    Fig. 30

    Testing

    • Select the right development board in Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Make sure that you have entered the right Wi-Fi credentials, API key and event name before uploading the code.
    • Open the serial monitor with a 115200 baud rate as defined in the Arduino code.
    • Press the EN button from the ESP32 development board.
    • Go to your Google drive.
    • You should see a folder (named IFTTT ) in your Google drive.
    • Another folder will be there inside the IFTTT folder (named as ESP32_hall sensor readings, in our case)
    • Open the folder to see the values received from the IFTTT server.
    • The spreadsheet will be updated after every 15 minutes. If you press the EN button before completing the sleep duration(15 minutes), the spreadsheet will be updated automatically with new sensor data, as shown below:

    Fig. 31: Hall Sensor Readings on Google Sheets

    Fig. 32: Serial Monitor

    This concludes the tutorial. I hope you found this of some help and also to see you soon with the new tutorial on ESP32.

    ESP32 HTTP Post with ThingSpeak and IFTTT

    ESP32 is a powerful chip for Internet of Things applications. This tutorial is also based on another ESP32 application in the field of IoT.

    Hello readers, I hope you all are doing great. In the previous tutorial, we learned how to send sensor readings from ESP32 to the cloud (ThingSpeak webserver).

    In this tutorial, we will learn to send HTTP POST requests from the ESP32 board to ThingSpeak and IFTTT APIs.

    Where To Buy?
    No.ComponentsDistributorLink To Buy
    1ESP32AmazonBuy Now

    What is HTTP?

    Fig. 1 Hypertext Transfer Protocol

    HTTP stands for hypertext transfer control and it is a protocol for transferring data between a web client and a web server. Hyper text transfer protocol was invented alongside HTML (Hypertext markup language) to create the first interactive, text-based web browser: the original www or World Wide Web.

    Server and client communication process over HTTP:

    • The ESP32 (client) sends an HTTP request to a server ( for example ThingSpeak or IFTTT.com)
    • The server responds to the ESP32 ( client ).
    • Finally, the response contains request status information as well as the requested content.

    HTTP POST Request

    Fig. 2 HTTP POST Request

    Hypertext transfer protocol uses particular request methods to execute various tasks. Two mostly used HTTP request methods are: HTTP GET request and HTTP POST request.

    HTTP GET request is generated to request data from a specific resource and the HTTP POST request method is used to send data from the client device to the server to create or update resources.

    In this tutorial, we will demonstrate only the HTTP POST method with ThingSpeak and IFTTT web services.

    Features of the HTTP POST request:

    • Unlimited data length: Data is submitted through the body of HTTP so there is no limit/restriction on data length.
    • Secure: Data does not get saved on the web browser hence, this method of data communication is secure.
    • Allows different data types.
    • Data privacy.

    What is IFTTT?

    IFTT stands for If This Then That. It is a free web service for making different services like email, weather services, Twitter etc to connect.

    IFTTT means if a service is triggered, other IFTTT services will take action.

     

    Fig. 3 IFTTT

    IFTTT and ESP32

    IFTTT acts as a bridge between ESP32 and other web services. Some of the tasks the ESP32 board can perform with the IFTTT API service are:

    • Sending Emails and SMSs
    • Controlling ESP32 with Google Assistant
    • Communicating data or information with smartphones.
    • Scheduling events for ESP32.

    IFTTT comprises Applets and Applets further contains two IFTTT services namely trigger and action.

    You can use the applets created by a company or can also create your own applet. To use the IFTTT applet with ESP32, we need to create an applet by ourselves. Such applet will contain Webhooks service to interact directly with ESP32 and other services that you want to use like email, Twitter service etc.

    There are cases while using ESP32 with the IFTTT: either ESP32 will trigger the IFTTT to do some task or the IFTTT triggers ESP32 to do some task.

    Steps to trigger IFTTT via ESP32

    • Create an IFTTT account
    • Create an Applet to connect Webhooks to the desired service.
    • Sending HTTP POST request from ESP32 board to IFTTT
    1. Creating an IFTTT account:

    Enter the following link in the web browser: https://ifttt.com

    1. Login with your Gmail or Facebook accounts for free.
    2. Click on Create icon (top left menu) to create an Applet.
     

    Fig. 4 Creating an Applet

     
    1. Click on the ”if This” icon.

    Fig. 5 ” If This”

     
    • Select a service. Search for the Webhooks service and select the respective icon.

    Fig. 6 Search and Select Webhooks

     
    • Click on the Receive a web request option to select a trigger option. The trigger will fire every time the maker service receives a web request to notify it to an event.

    Fig. 7 Receive a Web Request

     
    • Assign a name to the trigger event and click on Create trigger We have assigned ESP32_test.
     

    Fig. 8 Create Trigger

    • Next, click on the “Then That”

    Fig. 9 Then that

    • Select a service. We are selecting an Email service.

    Fig. 10 Selecting a Service

    • Next, define what will happen whenever the event is triggered (the event that we have created earlier) and click on the Finish

    Fig. 11

    • Testing the Applet
    1. Open the following link: https://ifttt.com/maker_webhooks
    2. Click on the Documentation A new window will open containing your key (API).
    3. Enter the details in To trigger an Event and click on Test it.
     

    Fig. 12 To Trigger an Event

    Fig. 13 Event Successfully Triggered

     
    • Open the email account, you have used while creating an IFTTT account.
    • You should receive an email from IFTTT.

    Arduino Code

    #include <WiFi.h>

    #include <HTTPClient.h>

    //---------Netwrok Credentials

    const char* ssid = "SSID";

    const char* password = "Password";

    const char* serverName = "http://maker.ifttt.com/trigger/ESP32_test/with/key/Enter you API key";

    unsigned long lastTime = 0;

    unsigned long timerDelay = 15000;

    void setup()

    {

    Serial.begin(115200);

    WiFi.begin(ssid, password);

    Serial.println("Connecting");

    while(WiFi.status() != WL_CONNECTED)

    {

    delay(500);

    Serial.print(".");

    }

    Serial.println("");

    Serial.print("Connected to WiFi network with IP Address: ");

    Serial.println(WiFi.localIP());

    // Random seed is a number used to initialize a pseudorandom number generator

    randomSeed(hallRead());

    }

    Void Loop()

    //Send an HTTP POST request after every 15 seconds

    if ((millis() - lastTime) > timerDelay)

    {

    //Check WiFi connection status

    if(WiFi.status()== WL_CONNECTED)

    {

    WiFiClient client;

    HTTPClient http;

    // Your Domain name with URL path or IP address with path

    http.begin(client, serverName);

    // Specify content-type header

    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    // Data to send with HTTP POST

    String httpRequestData = "value1=" + String(random(25)) + "&value2=" + String(random(25))+ "&value3=" + String(random(25));

    // Send HTTP POST request

    int httpResponseCode = http.POST(httpRequestData);

    /*

    // If you need an HTTP request with a content type: application/json, use the following:

    http.addHeader("Content-Type", "application/json");

    // JSON data to send with HTTP POST

    String httpRequestData = "{\"value1\":\"" + String(random(40)) + "\",\"value2\":\"" + String(random(40)) + "\",\"value3\":\"" + String(random(40)) + "\"}";

    // Send HTTP POST request

    int httpResponseCode = http.POST(httpRequestData);

    */

    Serial.print("HTTP Response code: ");

    Serial.println(httpResponseCode);

    Serial.println("successfully conected to host");

    // Free resources

    http.end();

    }

    else

    {

    Serial.println("WiFi Disconnected");

    }

    lastTime = millis();

    }

    }

    Code Description

    • Add the required header files.
    • WiFi.h header file is used to enable the Wi-Fi module and its respective functions.
    • HTTPClient.h header file is used to let the server and client pass information with HTTP response or request.

    Fig. Libraries

    • Enter the network credentials, SSID and Password.

    Fig. Network Credentials

    • Add the IFTT domain name, the event name (you have created) and the API key. The event name we have created is ESP32_test.

    Fig.

    Setup()

    • Initialize the Serial monitor with a 115200 baud rate for debugging purposes.

    Fig.

    • Enable ESP32’s Wi-Fi module using begin() function which is using SSID and password as arguments.
    • Wait until the ESP32 is not connected to the Wi-Fi network.
    • Fetch the IP address using WiFi.localIP() function.

    Fig.

    • randomSeed() function is used to generated a pseudorandom number. We are using Hall sensor to take hall readings and share them to IFTTT server (host).

    Fig.

    Loop()

    • If the ESP32 board is successfully connected to the Wi-Fi network, HTTP POST requests will be generated automatically after every 15 seconds.
    • Some random values (hall readings) will be sent through value1, value1, value3

    Fig

    • Send HTTP POST request.
    • Print the HTTP POST response with the response code.
    • Response code 200 is for successful communication and 402 code will be printed if some error is detected during HTTP post request.

    Fig.

    • Following lines are used when you want to make a request with some JSON

    Fig.

    • End the HTTP request.

    Fig.

    Testing

    • Select the right development board in Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Make sure that you have entered the right Wi-Fi credentials, API key and event name before uploading the code.
    • Open the serial monitor with a 115200 baud rate as defined in the Arduino code.
    • Press the EN button from the ESP32 development board.
    • On the serial monitor, we can check whether ESP32 is successfully connected to the network or not and whether the HTTP POST request is generated successfully or not.

    Fig. 14 Serial Monitor

    • Open your IFTTT account and click on My
    • Next, click on View Activity.

    Fig. 15 View Activity

    • A screenshot of the latest activity is shown below:

    Fig. 16 Received data.

     
    • Check your registered email. You should receive an email from IFTTT.

    Fig. 17 Email Received from IFTTT Server

     

    Making an HTTP POST Request (JSON data) from ESP32 to ThingSpeak with Arduino IDE

    We have already posted an article on sending sensor readings from ESP32 to ThingSpeak. In this article, we will learn how to send HTTP POST requests from ESP32 to send JSON data to the ThigSpeak server.

    ThingSpeak is a web service operated by MathWorks where we can send sensor readings/data to the cloud. We can also visualize and act on the data (calculate the data) posted by the devices to ThingSpeak. The data can be stored in either private or public channels.

    Steps to be followed to access ThingSpeak API:

    • First, you need to create a MathWorks Account.
    • To create an account or log in to ThingSpeak (operated by MathWorks) server follow the link: https://thingspeak.com/
    • Click on Get Started for free.

    Fig. 18 Getting Started for Free

    • Enter your details to create a MathWorks account as shown below:

    Fig. 19 Create New Account

    • If you have already created a MathWorks account, then click on Sign in.

    Fig. 20 MathWorks Sign in

    • Create a channel by clicking on the New Channel

    Fig. 21 New Channel

    • Enter the respective details in the channel.

    Fig. 22 Create a New Channel

     

    Arduino Code

    //-----------Libraries

    #include <WiFi.h>

    #include <HTTPClient.h>

    //-----------Network Credentials

    const char* ssid = "replace with your network SSID";

    const char* password = "replace with netwrok password";

    // Domain Name with full URL Path for HTTP POST Request

    const char* serverName = "http://api.thingspeak.com/update";

    // Service API Key

    String apiKey = "Write API Key";

    unsigned long lastTime = 0;

    unsigned long timerDelay = 5000; //to add delay of 5sec

    void setup()

    {

    Serial.begin(115200);

    WiFi.begin(ssid, password); //initialize ESP32 wifi module

    Serial.println("Connecting");

    while(WiFi.status() != WL_CONNECTED)

    {

    delay(500);

    Serial.print(".");

    }

    Serial.println("");

    Serial.print("Connected to WiFi network with IP Address: ");

    Serial.println(WiFi.localIP());

    Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");

    // Random seed is a number used to initialize a pseudorandom number generator

    randomSeed(analogRead(25));

    }

    void loop()

    {

    //Send an HTTP POST request after every 5 seconds

    if ((millis() - lastTime) > timerDelay)

    {

    //Check the WiFi connection status

    if(WiFi.status()== WL_CONNECTED)

    {

    WiFiClient client;

    HTTPClient http;

    http.begin( client, serverName );

    http.addHeader("Content-Type", "application/json");

    String httpRequestData = "{\"api_key\":\"" + apiKey +

    "\",\"field1\":\"" +

    String(random(30)) + "\"}";

    int httpResponseCode = http.POST(httpRequestData);

    Serial.print("HTTP Response code: ");

    Serial.println(httpResponseCode);

    // Free resources

    http.end();

    }

    else {

    Serial.println("WiFi Disconnected");

    }

    lastTime = millis();

    }

    }

    Code Description

    • Add the server address and API (Write) Key.

    Fig.

    Setup()

    • Inside setup() function, initialize the serial monitor with a 115200 baud rate for debugging purposes. Also initialize the Wi-Fi module using WiFi.begin() function.
    • randomSeed() function is used to generate pseudorandom numbers.
    • Inside the randomSeed() function, the data you want to share will be passed as an argument.
    • The data could be a sensor reading or some analog values.

    Loop()

      • Inside the loop function, once the ESP32 board is successfully connected with Wi-Fi, ESP32 will make an HTTP POST request for JSON data.
      • The request will be made after every 5 seconds.
      • In this code, we will share JSON data.

    Fig.

    • Print the HTTP POST response with the response code.
    • Response code 200 is for successful communication and 402 code will be printed if some error is detected during HTTP post request.

    Fig.

    Testing

    • Select the right development board in Tools >> Boards >> DOIT ESP32 DevKit V1 in Arduino IDE.
    • Compile and upload the code into ESP32 using Arduino IDE.
    • Make sure that you have entered the right Wi-Fi credentials, and write the API key before uploading the code.
    • Open the serial monitor with a 115200 baud rate to check whether ESP32 is connected to Wi-Fi or not.
    • Open the ThingSpeak account and check the Channel Stats.

    Fig. : data (JSON) Chart on ThingSpeak

     

    This concludes the tutorial. I hope you found this of some help and also to see you soon with the new tutorial on ESP32.

    Syed Zain Nasir

    I am Syed Zain Nasir, the founder of <a href=https://www.TheEngineeringProjects.com/>The Engineering Projects</a> (TEP). I am a programmer since 2009 before that I just search things, make small projects and now I am sharing my knowledge through this platform.I also work as a freelancer and did many projects related to programming and electrical circuitry. <a href=https://plus.google.com/+SyedZainNasir/>My Google Profile+</a>

    Share
    Published by
    Syed Zain Nasir