A PIR sensor (Passive Infrared Sensor) is one of the most popular components in electronics for motion detection. Whether you are building a home security system, an automatic light switch, or an IoT alert device, the PIR sensor gives you a reliable and low-cost way to detect human movement. In this guide, we cover everything from how the pyroelectric effect works inside the sensor, to wiring the HC-SR501 module to an Arduino and building real projects including a buzzer alarm and an ESP32 smart alert system.
Table of Contents
How PIR Sensors Detect Motion
The name passive means the sensor does not emit any energy — it only receives infrared radiation emitted by warm objects like humans and animals. Inside every PIR sensor is a pyroelectric crystal element. When infrared radiation hits this crystal, it generates a small electric charge. When a person walks across the sensor field of view, the temperature distribution changes, causing a differential signal between two halves of the sensing element. This differential signal is amplified and processed to produce a digital HIGH output.
The dome-shaped Fresnel lens on top of the sensor focuses infrared radiation from different zones onto the sensing element, greatly expanding the detection field to roughly 110 degrees horizontally and up to 7 metres in range for the HC-SR501 module.
HC-SR501 Module Specifications
The HC-SR501 is the standard PIR module used in Arduino and Raspberry Pi projects worldwide. Here are its key specifications:
- Supply voltage: 4.5V to 20V DC
- Output voltage: 3.3V HIGH / 0V LOW (compatible with 3.3V and 5V microcontrollers)
- Detection range: Up to 7 metres
- Detection angle: Up to 110 degrees
- Trigger modes: Single trigger (L) and repeatable trigger (H) — selectable via jumper
- Delay time: Adjustable from 5 seconds to 5 minutes
- Sensitivity: Adjustable from 3 metres to 7 metres
- Output: Active HIGH digital signal on pin OUT
- Quiescent current: Less than 50 microamps — excellent for battery-powered projects
The module has three pins: VCC (power), GND, and OUT (signal). The onboard BISS0001 chip handles all the amplification and signal conditioning, so your microcontroller receives a clean digital HIGH or LOW directly.
Sensitivity and Delay Trimpots
The HC-SR501 has two orange trimpots (small adjustable resistors) on the PCB, and a two-pin jumper for trigger mode selection:
- Sensitivity trimpot (right side): Rotate clockwise to increase detection range (up to about 7 m), anticlockwise to decrease (down to about 3 m). Start at midpoint for most indoor rooms.
- Delay trimpot (left side): Controls how long the output stays HIGH after motion is detected. Clockwise increases hold time (up to about 5 minutes), anticlockwise reduces it (minimum about 5 seconds).
- Trigger jumper H (Repeatable): Timer resets each time new motion is detected — the output stays HIGH continuously as long as someone is in range. Best for lighting control.
- Trigger jumper L (Single): Output goes HIGH once, then LOW for the delay period before it can trigger again. Useful for one-shot alerts.
Pro tip: Fresh HC-SR501 modules need a 30 to 60 second warm-up time after power-on before they give reliable readings. During this period you may see spurious HIGH pulses — this is normal.
Wiring HC-SR501 to Arduino
Wiring the PIR sensor to an Arduino is straightforward with just three connections:
| HC-SR501 Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| GND | GND |
| OUT | Digital Pin 2 |
You can power the HC-SR501 from the Arduino 5V pin for bench testing. For permanent installations, connect VCC to a 9V to 12V wall adapter for maximum detection range, since higher supply voltage increases sensitivity.
Basic Motion Detection Code
Upload this sketch to see motion detection working in the Serial Monitor:
const int PIR_PIN = 2;
const int LED_PIN = 13;
void setup() {
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("Warming up PIR sensor...");
delay(30000);
Serial.println("PIR sensor ready!");
}
void loop() {
int motionState = digitalRead(PIR_PIN);
if (motionState == HIGH) {
digitalWrite(LED_PIN, HIGH);
Serial.println("Motion detected!");
} else {
digitalWrite(LED_PIN, LOW);
}
delay(100);
}
LED Indicator and Buzzer Alarm
Adding a buzzer turns your motion detector into an audible alarm — perfect for a simple security alert system. Connect an LED to pin 13 with a 220 ohm resistor, and a 5V active buzzer to pin 8 through the same 220 ohm resistor, with its other leg to GND.
const int PIR_PIN = 2;
const int LED_PIN = 13;
const int BUZZ_PIN = 8;
bool alarmActive = false;
unsigned long alarmStart = 0;
const unsigned long ALARM_DURATION = 3000;
void setup() {
pinMode(PIR_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZ_PIN, OUTPUT);
Serial.begin(9600);
delay(30000);
Serial.println("PIR Alarm ready");
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH && !alarmActive) {
alarmActive = true;
alarmStart = millis();
Serial.println("ALERT: Motion detected!");
}
if (alarmActive) {
digitalWrite(LED_PIN, HIGH);
digitalWrite(BUZZ_PIN, HIGH);
if (millis() - alarmStart >= ALARM_DURATION) {
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZ_PIN, LOW);
alarmActive = false;
}
}
delay(50);
}
Automatic Light Control Project
The most common real-world application of the PIR sensor in Indian homes is automatic corridor and bathroom lighting. Set the trigger jumper to H (Repeatable) mode, and adjust the delay trimpot to about 1 to 2 minutes so lights stay on while the room is occupied. Wire a 5V relay module to pin 7 of the Arduino. The relay NC/NO terminals connect to your light fixture circuit. When motion is detected, the relay closes and switches on the light; when no motion is detected for the set delay period, the relay opens and the light turns off.
const int PIR_PIN = 2;
const int RELAY_PIN = 7;
void setup() {
pinMode(PIR_PIN, INPUT);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
delay(30000);
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
digitalWrite(RELAY_PIN, HIGH);
} else {
digitalWrite(RELAY_PIN, LOW);
}
delay(100);
}
False Trigger Prevention
False triggers are the most frustrating issue with PIR sensors. Here are the common causes and fixes:
- Air conditioning or fans: Moving air causes thermal gradients. Point the sensor away from AC vents.
- Sunlight or lamps: Rapid temperature changes from sunlight entering a room can trigger the sensor. Use curtains or reposition the sensor.
- Vibrations: Physical vibration near the sensor can cause electrical noise. Mount on a solid surface.
- Animals: Pets at floor level will trigger most PIR sensors. Mount the sensor high and angled downward so its cone does not cover the floor.
- Warm-up period: Always wait at least 30 seconds after power-on before treating sensor output as valid.
- Software debouncing: Add a minimum trigger interval in code so repeated triggers within 2 to 3 seconds are ignored.
ESP32 IoT Alert Project
Combining the PIR sensor with an ESP32 enables Wi-Fi based push notifications or Telegram messages when motion is detected — ideal for a remote monitoring or security alert system. Connect the PIR OUT pin to GPIO 14 on the ESP32. The 60-second cooldown in the code below prevents alert flooding.
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "YourWiFiName";
const char* password = "YourWiFiPassword";
const char* BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN";
const char* CHAT_ID = "YOUR_CHAT_ID";
const int PIR_PIN = 14;
unsigned long lastAlert = 0;
const unsigned long COOLDOWN = 60000;
void sendTelegramAlert(String message) {
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(BOT_TOKEN)
+ "/sendMessage?chat_id=" + String(CHAT_ID)
+ "&text=" + message;
http.begin(url);
http.GET();
http.end();
}
void setup() {
Serial.begin(115200);
pinMode(PIR_PIN, INPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.println("Wi-Fi connected");
delay(30000);
Serial.println("PIR IoT ready");
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
if (millis() - lastAlert > COOLDOWN) {
sendTelegramAlert("Motion+detected+at+home!");
lastAlert = millis();
Serial.println("Alert sent!");
}
}
delay(200);
}
Replace YOUR_TELEGRAM_BOT_TOKEN and YOUR_CHAT_ID with values from BotFather on Telegram. You can also send data to Blynk, MQTT broker, or any webhook endpoint using the same HTTP pattern.
Frequently Asked Questions
Q: Can I use a PIR sensor outdoors?
The HC-SR501 module itself is not weatherproof, but you can house it in a sealed enclosure with a plastic window for the Fresnel lens. For permanent outdoor use, consider dedicated weatherproof PIR detectors designed for security applications.
Q: What is the difference between single trigger (L) and repeatable trigger (H) mode?
In H mode, the output stays HIGH and the timer resets each time new motion is detected — ideal for lighting where you want the light to stay on as long as someone is present. In L mode, the sensor triggers once, then goes LOW for the full delay period before it can trigger again — better for one-shot alerts.
Q: Why does my PIR sensor trigger randomly at night?
This is usually caused by temperature changes in the environment — warm air from heating systems, a window being opened, or the ambient temperature dropping at night. Try reducing the sensitivity trimpot and ensuring the sensor is not pointed at any heat sources.
Q: Can the HC-SR501 detect animals or pets?
Yes — it detects any warm body including pets. To avoid pet false alarms, mount the sensor at 2 to 2.5 metres height and angle it downward so the detection cone covers human height but not floor level where pets move.
Q: What is the voltage output from the OUT pin?
When motion is detected the OUT pin goes to approximately 3.3V HIGH (not 5V), which is compatible with both Arduino (5V logic) and ESP32/ESP8266 (3.3V logic) without any level shifting.
Shop Sensors at Zbotic.in
Find sensors, modules, and components for your next project — fast delivery across India.
Add comment