Overview
The HC-SR501 is a passive infrared (PIR) motion sensor module that detects changes in infrared radiation — which is how it "sees" warm bodies moving in its field of view. It's the classic, low-cost motion detector used in hobby alarms, automatic lighting, security systems, occupancy sensors, and scare-the-cat projects. When motion is detected, it drives its output pin HIGH for a user-configurable duration.
The module includes two onboard potentiometers — one for sensitivity (detection distance, roughly 3–7 meters) and one for time delay (how long the output stays HIGH after a trigger — the datasheet range is 0.3 s up to 5 minutes). A jumper on the side selects the trigger mode: repeatable (H) extends the timer on each new detection, while non-repeatable (L) resets only after the delay expires.
This manual covers specifications, the pinout, wiring for Arduino, ESP32, Raspberry Pi, and the Pico, a working code example per platform, and FAQs about warm-up time, tuning the pots, and false-trigger mitigation.
At a Glance
Specifications
| Parameter | Value |
| Sensor Type | Passive infrared (PIR) |
| Operating Voltage | 5V - 20V (regulator onboard) |
| Output Voltage | 3.3V HIGH / 0V LOW |
| Detection Range | 3 - 7 meters (adjustable) |
| Detection Angle | < 120° within 7 m (datasheet also quotes a 110° cone) |
| Time Delay (Ton) | 0.3 s to 5 min, adjustable (datasheet) |
| Blocking / Lock Time | 0.2 s per the datasheet we ship (other HC-SR501 datasheets list ~2.5 s) |
| Trigger Modes | H (repeatable) / L (non-repeatable) |
| Warm-up Time | ~1 minute ("nearly a minute to initialize" — ignore triggers during warm-up) |
| Current Draw | 65 mA max (datasheet) |
| Working Temperature | -15°C to +70°C |
| Dimensions | 32 × 23 mm board, Ø23 mm Fresnel lens |
| Pin Count | 3 (VCC, OUT, GND) — labelled on the sensor side of the board |
HC-SR501 Pinout
HC-SR501 pinout: three pins — VCC (5–20V DC in), OUT (3.3V digital output, HIGH while motion is detected) and GND. The labels are printed on the sensor side of the board next to the header, so check the silkscreen rather than assuming an order.
| Pin | Function |
| VCC | 5–20V DC input (onboard regulator) |
| OUT | Digital output: 3.3V (HIGH) while motion is detected, 0V (LOW) otherwise — read it on any GPIO of a 3.3V or 5V board |
| GND | Ground |
The two unpopulated pads next to the sensor, RL and RT, are optional: RL takes a light-dependent resistor so the sensor only triggers in the dark, and RT takes a thermistor for temperature compensation. Leave both empty for normal use.
Wiring Guide
Arduino Wiring
Power the PIR sensor from the Arduino's 5V rail. The output swings 0V / 3.3V, which the Arduino reads as LOW / HIGH on any digital pin.
| Module Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| OUT | D2 (any digital pin) |
| GND | GND |
ESP32 Wiring
Power from the ESP32's VIN/5V pin (USB-powered). The 3.3V output from the module is ideal for ESP32 logic levels.
| Module Pin | ESP32 Pin |
|---|---|
| VCC | 5V (VIN) |
| OUT | GPIO 4 (any GPIO) |
| GND | GND |
Raspberry Pi Wiring
The Pi's 5V rail can power the module directly. The 3.3V output is safe for any Pi GPIO input pin.
| Module Pin | Raspberry Pi Pin |
|---|---|
| VCC | 5V (Pin 2) |
| OUT | GPIO 17 (Pin 11) |
| GND | GND (Pin 6) |
Raspberry Pi Pico Wiring
Power from the Pico's VBUS or VSYS (5V USB) and read the output on any GP pin.
| Module Pin | Pico Pin |
|---|---|
| VCC | VBUS (Pin 40, 5V) |
| OUT | GP15 (Pin 20) |
| GND | GND (Pin 38) |
How to Adjust the HC-SR501: Sensitivity, Time Delay and Trigger Jumper
Three things on the board change how the HC-SR501 behaves. Adjust them in small steps and test between changes — the output only updates after the current delay expires.
- Sensitivity pot — sets the detection distance, roughly 3 m to 7 m. Clockwise increases the range.
- Time-delay pot — sets how long OUT stays HIGH after a detection, from about 0.3 s up to 5 minutes (datasheet). Clockwise lengthens the delay.
- Trigger jumper (H / L) — H (repeat trigger) restarts the timer on every new detection, so OUT stays HIGH as long as movement continues; L (single trigger) lets OUT go LOW after the delay even if movement continues, then waits through the lock time before it can trigger again. H is the usual choice for lights and alarms.
Code Examples
Arduino
// HC-SR501 PIR Motion Sensor - basic motion detection
const int pirPin = 2;
const int ledPin = 13;
void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.println("PIR warming up... wait 30-60 seconds.");
delay(30000);
Serial.println("Ready.");
}
void loop() {
int state = digitalRead(pirPin);
if (state == HIGH) {
digitalWrite(ledPin, HIGH);
Serial.println("Motion detected!");
} else {
digitalWrite(ledPin, LOW);
}
delay(100);
}
ESP32
// HC-SR501 PIR on ESP32 - interrupt-driven motion detection
const int pirPin = 4;
volatile bool motion = false;
void IRAM_ATTR onMotion() {
motion = true;
}
void setup() {
Serial.begin(115200);
pinMode(pirPin, INPUT);
attachInterrupt(digitalPinToInterrupt(pirPin), onMotion, RISING);
Serial.println("PIR ready (warming up...).");
delay(30000);
}
void loop() {
if (motion) {
motion = false;
Serial.println("Motion detected!");
}
delay(50);
}
Raspberry Pi
# HC-SR501 PIR Motion Sensor on Raspberry Pi
# Install: pip install gpiozero
from gpiozero import MotionSensor
from signal import pause
pir = MotionSensor(17)
print("PIR warming up...")
pir.wait_for_no_motion()
print("Ready. Waiting for motion.")
pir.when_motion = lambda: print("Motion detected!")
pir.when_no_motion = lambda: print("All clear.")
pause()
Raspberry Pi Pico (MicroPython)
# HC-SR501 PIR on Raspberry Pi Pico
from machine import Pin
import time
pir = Pin(15, Pin.IN)
led = Pin(25, Pin.OUT) # onboard LED
print("Warming up PIR sensor...")
time.sleep(30)
print("Ready.")
while True:
if pir.value() == 1:
led.on()
print("Motion detected!")
else:
led.off()
time.sleep_ms(100)



