Hello readers, we hope you all are doing great. In this tutorial, we are going to demonstrate how to detect motion with ESP32 using a PIR motion sensor.
Interrupts are used when a microcontroller needs to continuously monitor for an event while the same micro-controller is executing other tasks as well.
We have already posted a tutorial on ESP32 Interrupts, which includes both software and hardware interrupt.
Fig. 1 Motion Detection
In this tutorial, we are implementing hardware interrupt (Hardware interrupts are the external interrupts that are caused by an external event) method. Where we are using a PIR sensor to generate interrupts. Interrupt generated via PIR motion sensor comes under the category of a hardware interrupt. PIR motion sensor is mostly used in home automation applications where we can make home appliances to respond automatically over human presence. Appliance connected to ESP32 will respond automatically (as per the instructions provided) whenever an interrupt is being triggered by the PIR motion sensor.
What is a PIR Motion sensor and how does it work?
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.
Fig. 2 PIR Motion Sensor
The PIR motion sensor has a few settings. Sensitivity will be one of the options. Lower sensitivity indicates a moving leaf or a small mouse. The sensitivity can be adjusted based on the installation location and project requirements. The second tuning option is 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.
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.
- ESP32 development board
- PIR motion sensor (HC-SR501)
- 330 Ohm resistor
- Connecting wires
Interfacing PIR with ESP32
Fig. 3 PIR motion sensor Pins
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.
//----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");
startTimer = true;
lastTrigger = millis();
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
now = millis();
if( startTimer && (now - lastTrigger > ( timeSeconds*500)))
Serial.println(" Turning OFF the LED " );
digitalWrite( led, LOW );
startTimer = false;
- The first step is setting up the GPIO pins for LED and motion sensor (PIR).
- LED is connected to GPIO 23 and PIR sensor to GPIO4.
Fig. 4 Define GPIO pins
- Next, we are defining variables that are used to set the timer for adding delay after the interrupt is being detected.
- The variable now is defining the current time
- The variable lastTrigger is defining the time when the interrupt is detected.
- The variable startTimer is used to start the time when an interrupt is detected.
Fig. 5 Timer
- It is required that the interrupt service routine should have the minimum possible execution time because it halts or blocks the normal program execution.
- The attribute IRAM_ATTR is used to run the code (interrupt code) inside the internal RAM when an interrupt occurs because RAM (random access memory) is much faster than flash memory.
- After the execution of the interrupt code or ISR the normal code will be stored or executed inside the flash memory.
Fig. 6 Detect a motion
- 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.
- Write the initials state of LED as LOW.
- Next step is attaching the digital pin to interrupt using the attachInterrupt The detectMovement function is passed as an argument inside this function.
Fig. 7 Setup
- Inside the loop function which is continuously running, the detectsMovement function will be called every time when an interrupt occurs, which we have defined previously inside the setup() function.
- LED will turn off after a delay of 5sec (once an interrupt is detected) or you can say that LED will be ON only for 5sec (5000ms).
- The variable “now” will be updated every time with the current time.
Fig. 8 Loop function
- 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 115200 baud rate as defined in the Arduino code.
- Press the EN button from the ESP32 development board.
Fig. 9 Serial Monitor Output
This concludes the tutorial. I hope you found this of some help and also to see you soon with new tutorial on ESP32.