In this tutorial, we will learn to interface HC-SR501 PIR motion sensor with Arduino and about the working principle. We will also see some Arduino sketches. We will show you a basic sketch to show the working of the PIR sensor. Additionally, we will also include a sketch that will detect motion using external interrupts of Arduino and PIR Sensor motion sensor.
HC-SR501 PIR Motion Sensor Working
Every object above -273°C (absolute zero) emits infrared rays when they are heated and on the same principle, the human body emits IR rays due to body heat which the PIR motion sensor detects.
The PIR motion sensor consists of a pyroelectric sensor and a Fresnel lens. The lens is responsible to focus the IR rays on the pyroelectric sensor. The pyroelectric sensor consists of two rectangular slots that allow infrared radiation to pass through. Two independent infrared sensor electrodes, one providing a positive output and the other a negative output, are hidden below them. This is because we’re looking for a shift in IR levels rather than ambient IR levels. The two electrodes are linked in such a way that they cancel out each other. The output will swing high or low if one part sees more or less IR radiation than the other.
When there is no movement around the sensor, the slots detect the same levels of IR waves. Therefore, the output signal is zero. When movement is detected, one-half of the PIR sensor is captured, causing a positive differential change between the two halves. The sensor generates a negative differential change when there is no longer any movement. The sensor sets its output pin high when the corresponding pulse of signals is received.
Whenever there is a motion around the sensor, it will detect the heat of the human body and produces a high output logic 1 at the output of the sensor. Hence, whenever the motion sensor detects the human body around it, its output becomes high.
HC-SR501 PIR Motion Detector
The HC-SR501 PIR sensor is a low-cost motion detector sensor. It is a passive motion sensor which means it can only detect something around it and it cannot transmit anything.
The diagram below shows the PIR motion sensor. Notice that the white dome shape found at the front of the sensor module is the Fresnel lens.
The diagram below shows the back side of the HC-SR501 PIR sensor.
You may notice that the BSS0001 signal processing IC is located at one side. This PIR sensor is built around this micro power PIR motion detector IC that is used for signal processing. Moving ahead you can see a 3.3V DC voltage regulator as well. This allows the PIR sensor to be used with different microcontrollers of various logic levels with ease. We can use DC voltage in between 4.5V-12V to power this sensor due to the presence of the voltage regulator.
Adjusting Parameters (Trigger, Sensitivity and Time Delay)
At the bottom of the board you can view a jumper to adjust trigger, a potentiometer for sensitivity adjustment and another potentiometer for time delay adjustment.
Trigger Adjustment Jumper: We can either of the two trigger modes while working with HC-SR501 PIR sensor. ‘L’ selects the Single Trigger mode and ‘H’ selects the Multiple or repeating trigger mode. When the jumper is positioned at H, whenever a movement is detected the output signal will be HIGH and the timer delay restarts. Whereas, if the jumper is positioned at L, then the output signal will remain HIGH according to the time period set through the time delay potentiometer.
We can also adjust the sensitivity of this sensor by changing the variable resistors available on the sensor. One variable resistor is for sensitivity adjustment of distance and another variable resistor is for sensitivity adjustment of time that is the amount of time for which the output should be high.
Sensitivity Adjustment: This potentiometer allows us to adjust the range (maximum distance) for motion detection. It approximately ranges from 3 metres-7 meters. Moving the potentiometer clockwise increases the range whereas moving it anti clockwise decreases the range.
Time Delay Adjustment: This potentiometer allows us to adjust the time period till which the output signal remains HIGH when motion is detected. We can set it for as short as 3 seconds and as long as 5 minutes. Moving the potentiometer clockwise increases the time delay whereas moving it anti clockwise decreases the time delay.
Increasing Adaptability of HC-SR501
One interesting feature of HC-SR501 PIR motion sensor is that it provides two solder pads RL and RT at the backside of the board. We can use these to solder LDR and thermistor to increase the adaptability of our sensor.
The solder pad labelled RL is for soldering a light dependent resistor (LDR) or a photoresistor. This will allow the PIR sensor to be activated only in dark places thereby being quite handy in motion sensitive lighting systems.
The solder pad labelled RT is for soldering a thermistor. This will allow the PIR sensor to be used in different extreme temperatures thereby ensuring the sensitivity of the sensor is less dependent on ambient temperature. Additionally, it also improves the accuracy of the movement detection.
Specifications
The table below shows some key specifications of HC-SR501 PIR sensor.
Voltage | 5V-20V |
Power Consumption | 65mA |
TTL Output | 3.3V, 0V |
Sensing Range | Less than 120 degree, within 7 meters |
Temperature | -15 – 70 °C |
Measuring range | 3 meters – 7 meters |
Delay time | 3s-300s |
Dimensions | 32×24 mm |
HC-SR501 Pinout
The HC-SR501 PIR sensor consists of 3 pins as shown below:
- VCC: It is a power supplier pin and you should connect it with Vin of our Arduino board.
- Out: It is the 3.3V TTL logic output pin of the PIR sensor. Basically, we get output from this pin. When no motion is detected it is at a LOW state whereas when motion is detected the state goes to HIGH.
- GND: It is a ground pin and you should connect it with the ground of your Arduino board.
Using the HC-SR501 PIR motion sensor as a standalone unit
Let us first see how to use the HC-SR501 PIR motion sensor as a standalone unit without any microcontroller. This setup will help us test the functionality of the PIR sensor as well as work around the time delay, sensitivity and trigger modes.
We will require the following components:
Required Components
- One HC-SR501 PIR Sensor
- One 5mm LED
- One 220 ohm resistor
- Batteries
- Breadboard
- Connecting Wires
Assemble all these components as shown in the schematic diagram below:
The PIR Sensor which we are using in this tutorial consists of three pins. Two of them are power supply pins such as VCC and ground pins. We can power PIR motion sensor directly from the external batteries as shown above. The center pin is the output pin which provides an active high pulse whenever motion is detected. Otherwise, this pin remains active low.
In the above schematic, we can see that the cathode pin of LED is connected with common ground, and the anode pin is connected with the OUT pin of the sensor through the 220 ohm current limiting resistor.
When movement is detected, the OUT pin goes HIGH and the LED turn on. Wait for a few moments for the PIR sensor to adjust to the IR waves in the surrounding.
Interfacing HC-SR501 PIR Motion Sensor and Arduino
Now let us proceed forward and learn how to interface the HC-SR501 PIR motion sensor with Arduino UNO.
Required Components
- Arduino UNO
- One HC-SR501 PIR Sensor
- Connecting Wires
The connections are pretty straight forward. Connect VCC of PIR sensor with 5V pin of Arduino. Connect GND pin of PIR sensor with GND of Arduino. Moreover, connect the OUT pin of the sensor with any digital pin of the Arduino board. Here we are using Pin 7 to connect with the OUT pin.
We will set the trigger mode to H for multiple trigger. This will ensure that whenever a movement is detected the output signal will be HIGH and the timer delay restarts. For the timer delay we will set it to 3 seconds which is the minimum.
For demonstration purposes, we will trigger the Arduino onboard LED to turn ON when motion is detected. You can use an external LED, a relay or a buzzer as well.
Arduino Sketch
Open your Arduino IDE and go to File > New to open a new file. Copy the code given below in that file and save it.
The following sketch will turn the onboard LED of Arduino on when movement is detected and display “Motion detected!” message in the serial monitor. When there is no movement, the onboard LED will turn off and the serial monitor will display “Motion stopped.”
int led = 13;
int OUT = 7;
bool motion_State = false;
int PIR_State = LOW;
void setup() {
pinMode(led, OUTPUT);
pinMode(OUT, INPUT);
Serial.begin(115200);
}
void loop(){
PIR_State = digitalRead(OUT);
if (PIR_State == HIGH)
{
digitalWrite(led, HIGH);
if (motion_State == false)
{
Serial.println("Motion detected!");
motion_State = true;
}
}
else
{
digitalWrite(led, LOW);
if (motion_State == true)
{
Serial.println("Motion stopped");
motion_State = false;
}
}
}
How the Code Works?
First, we will define the Arduino pin through which the onboard LED is connected. It is Pin 3. Also, we will define the Arduino pin through which the PIR motion sensor’s OUT pin is connected. It is Pin 7 in our case.
int led = 13;
int OUT = 7;
Next we will create two variables. The motion state holds false as no motion is detected initially. It will turn true whenever motion will be detected. The PIR_State on the other hand holds the state of the OUT pin of the PIR sensor. Initially it is set to LOW indicating that no motion is detected yet.
bool motion_State = false;
int PIR_State = LOW;
Inside the setup() function, we will open a serial connection at a baud rate of 115200 and set up the PIR sensor module’s OUT pin as an input and the onboard LED pin as an output.
void setup() {
pinMode(led, OUTPUT);
pinMode(OUT, INPUT);
Serial.begin(115200);
}
Inside the loop() function, we first read the state of the PIR sensor’s OUT pin using digitalRead(OUT) and store it in the variable ‘PIR_State.’
PIR_State = digitalRead(OUT);
Now using if-else statement we will check whether the PIR motion sensor’s state is HIGH or LOW. If the state is HIGH then it means motion was detected. Hence the onboard LED will turn ON. Additionally, the serial monitor will print “Motion detected!” The motion_State variable will be set to true now.
if (PIR_State == HIGH)
{
digitalWrite(led, HIGH);
if (motion_State == false)
{
Serial.println("Motion detected!");
motion_State = true;
}
}
Else if the state is LOW then it means motion was not detected. Hence the onboard LED will turn OFF. Additionally, the serial monitor will print “Motion stopped” The motion_State variable will be set to false now.
else
{
digitalWrite(led, LOW);
if (motion_State == true)
{
Serial.println("Motion stopped");
motion_State = false;
}
}
Demonstration
To see the demonstration of the above code, upload the code to Arduino. But, before uploading code, make sure to select the Arduino board from Tools > Board and also select the correct COM port to which the Arduino board is connected from Tools > Port.
Once the code is uploaded to Arduino, open the serial monitor and set the baud rate to 115200. Now move your hand near the PIR sensor and the Arduino’s onboard LED will turn ON. Move your hand away and the LED will turn OFF. Simultaneously, the serial monitor will display motion detected and motion stopped messages.
Using External Interrupts to Detect Motion using PIR Sensor and Arduino
Next up, we will show you how to set up external interrupts with HC-SR501 PIR motion sensor and Arduino.
Interrupts
Interrupts are used to handle events that do not happen during the sequential execution of a program. For example, we want to perform certain tasks and these tasks execute sequentially in your Arduino program. But there are few tasks that only execute when a special event occurs such as an external trigger signal to the digital input pin of a microcontroller.
An external interrupt or a ‘hardware interrupt’ is caused by the external hardware module. For example, there is a Touch Interrupt which happens when touch is detected and a GPIO interrupt when a key is pressed down. In this tutorial, the interrupt will be triggered when the motion will be detected.
With interrupt, we do not need to continuously check the state of the digital input pin. When an interrupt occurs (a change is detected), the processor stops the execution of the main program and a function is called upon known as ISR or the Interrupt Service Routine. The processor then temporarily works on a different task (ISR) and then gets back to the main program after the handling routine has ended. This is shown in the figure below.
An example can be that of pressing a push button or motion detection with a PIR Sensor. In both cases, a push button or a PIR motion sensor can be used to trigger an interrupt. Therefore, when an external event occurs, the processor stops what it is doing and executes the interrupt service routine which we define for the respective event. After that, it returns to the current program. External Interrupts are extremely useful because with their help we do not have to constantly monitor the digital input pin state.
Configuring Interrupts in Arduino IDE
Now let us look at how to set up external interrupts in our Arduino using Arduino IDE. The following steps need to be followed.
We will use the following function to configure an interrupt in Arduino IDE:
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
The attachInterrupt() function takes in three arguments:
- digitalPinToInterrupt(pin): This is a function which takes in the pin of the Arduino as a parameter inside it. It denotes the pin which will cause an interrupt to occur. For example if setting Pin 2 as an interrupt pin the function will be specified as digitalPinToInterrupt(2). For Arduino UNO, you can use Pin 2 and Pin 3 as external interrupt pins.
- ISR: This is the second argument used to set up an interrupt. It is a special kind of function known as the Interrupt Service Routine which takes in no parameters and also returns nothing. Whenever the interrupt will occur this function will be called.
- mode: This denotes the triggering action for the interrupt to occur. The following four parameters are used to specify the mode:
LOW: This is used to trigger the interrupt when the pin is in a low state.
CHANGE: This is used to trigger the interrupt when the pin changes its state (HIGH-LOW or LOW-HIGH)
RISING: This is used to trigger the interrupt when the pin goes from LOW to HIGH.
FALLING: This is used to trigger the interrupt when the pin goes from HIGH to LOW.
Schematic
After learning all the techniques mentioned previously, now we are ready to proceed with our motion detection project. Now we will learn how to handle interrupts in Arduino using a PIR sensor. When a PIR sensor will detect motion, we will display “Motion Detected!” in the serial monitor.
The following components are required:
- Arduino UNO
- One PIR Sensor
- Connecting Wires
The connections are pretty straight forward. Connect VCC of PIR sensor with 5V pin of Arduino. Connect GND pin of PIR sensor with GND of Arduino. Moreover, connect the OUT pin of the sensor with the external interrupt pin of the Arduino board. Here we are using Pin 2 to connect with the OUT pin.
The center pin is the output pin which provides an active high pulse whenever motion is detected. Otherwise, this pin remains active low. That means a rising edge occurs when a PIR sensor detects motion. We can detect this rising edge with the help of interrupt pins of Arduino.
How PIR sensor works with External Interrupt?
The PIR Sensor acts as a source for the external interrupt. That means we connect the output of the PIR sensor with the external interrupt pin of Arduino. Furthermore, we attach the rising edge-triggered interrupt to this pin. That means this pin will trigger the interrupt whenever it will sense a rising edge on its input.
When a PIR sensor detects motion, an external interrupt is caused, and the serial monitor will display “Motion Detected!” You can even use the interrupt to control an LED, relay or a buzzer as well.
Arduino Sketch
Open your Arduino IDE and go to File > New to open a new file. Copy the code given below and save it.
const int OUT_Pin = 2;
void setup() {
Serial.begin(115200);
pinMode(OUT_Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(OUT_Pin), movement_detection, RISING);
delay(20000); //Power On Delay
}
void loop() {
}
void movement_detection(){
Serial.println("Motion Detected!");
}
How does the Code Works?
First, we will define the Arduino pin through which the PIR motion sensor’s OUT pin is connected. It is Pin 2 in our case.
const int OUT_Pin = 2;
movement_detection()
Next, we will define the function which will act as the Interrupt Service Routine(ISR). It is called movement_detection(). Whenever the PIR sensor will detect a movement, this function will be called. It will print ‘Motion Detected!’ in the serial monitor.
void movement_detection(){
Serial.println("Motion Detected!");
}
setup()
Inside the setup() function, we will open a serial connection at a baud rate of 115200 and set up the PIR sensor module’s pin as an input pullup.
Serial.begin(115200);
pinMode(OUT_Pin, INPUT_PULLUP);
Next, we will set the interrupt by using the attachInterrupt() function and pass three arguments inside it. These include the digitalPinToInterrupt(OUT_pin) function configures the interrupt with the pin connected with the PIR sensor, the ISR which is the movement_detection function which we defined previously, and lastly RISING which is the mode for the interrupt set up. The OUT_Pin will detect the motion and call the movement_detection function whenever the pin’s state will go from LOW to HIGH.
attachInterrupt(digitalPinToInterrupt(OUT_Pin), movement_detection, RISING);
Moreover, add a delay of 20 seconds for the PIR sensor to settle.
delay(20000);
loop()
The loop() function is empty in our case.
Demonstration
To see the demonstration of the above code, upload the code to Arduino. But, before uploading code, make sure to select the Arduino board from Tools > Board and also select the correct COM port to which the Arduino board is connected from Tools > Port.
Once the code is uploaded to Arduino, open the serial monitor and set the baud rate to 115200. Now move your hand over the PIR sensor and the serial monitor will display the motion detected message.
You may also like to read:
- How to use PIR Motion Sensor with Raspberry Pi Pico
- ESP8266 Interrupts and Timers Arduino IDE – PIR Motion Sensor Example
- ESP32 Interrupts and Timers with PIR Sensor using Arduino IDE
- MicroPython: Interrupts with ESP32 and ESP8266 – PIR Sensor Interfacing Example
- PIR sensor interfacing with pic microcontroller
- ESP32 IoT Motion Detection Web Server with Email Alert
- ESP8266 IoT Motion Detection Web Server with Email Alert
hello !
can you provide the pir module cause i can’t find it .
Can I get the circuit diagram and code for automatic Street light which is on only at night time by detecting vehicle using arduino along with pir sensor and ldr.
Can the PIR sensors sense the motion of non humans such as cars?