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. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
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.
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.
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
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:
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.
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
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
Table 1
Fig. 6 ESP32 and HCSR-501 connections
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
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:
https://github.com/mobizt/ESP-Mail-Client
Fig. 7 Adding ESP-Mail-Client Library
//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.
Fig. 8
Fig. 9
Fig. 10
Fig. 11
Fig. 12
Fig. 13
Fig. 14
Fig. 15
Fig. 16
Fig. 17 Variable for PIR sensor
Fig. 18
Fig. 19
Fig. 20
Fig. 21
Fig. 22
Fig. 23
Fig. 24
Fig. 25 ‘If motion detected’
Fig. 25 No motion detected
Fig. 26 Clear the email log
Fig. 27 select development board and COM port
Fig. 28 ESP32’s Inbuilt LED is turned ON when a motion is detected
Fig. 29 Serial monitor
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.
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. | Components | Distributor | Link To Buy | |
1 | ESP32 | Amazon | Buy Now |
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 has two variable resistors on its back side, used to adjust the Sensitivity and Detection Range, explained below:
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:
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:
Here's the circuit diagram for motion detection with ESP32 and PIR Sensor:
Now let's design the programming code for motion detection:
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;
}
}
//----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
}
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.
void loop()
{
now = millis();
if( startTimer && (now - lastTrigger > ( timeSeconds*500)))
{
Serial.println(" Turning OFF the LED " );
digitalWrite( led, LOW );
startTimer = false;
}
}
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 !!!