Learn
Detecting Motion with an HC-SR501 PIR Sensor on a Raspberry Pi 4B
Wire an HC-SR501 PIR motion sensor to a Raspberry Pi 4B, simulate a real motion event with a click, and read the digital output in Python — wiring, the Delay/Sensitivity/Retrigger settings, and why this sensor is Pi-safe with no divider needed, unlike the HC-SR04.
Note: the HC-SR501 PIR Motion Sensor is a VIP-tier component in the simulator — you’ll need a VIP plan to use it there.
Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.
What you’ll need
- Raspberry Pi 4B
- HC-SR501 PIR Motion Sensor
Step by step
- Drag Raspberry Pi 4B onto the Canvas.
- Drag the HC-SR501 PIR Motion Sensor onto the Canvas — a real 3-pin module. It can mount straight into a breadboard, or wire directly to the Pi.
- Hover over its 3 pins to confirm the labels, left to right: VCC, OUT, GND.
- Wire VCC → a Pi power pin and GND → a Pi GND pin.
- Wire OUT → any Pi GPIO pin you'll configure as an input (e.g. physical pin 38) — no voltage divider needed here: unlike the HC-SR04's Echo pin, OUT is a genuine 3.3V-safe digital signal, matching the real HC-SR501 datasheet.
- Click the sensor to select it, then open its settings panel and set three values: Delay (sec) — how long OUT stays HIGH after a trigger (3–300, default 5); Sensitivity (%) — scales that hold duration from 0.5× at 0% up to 1.5× at 100%, unaltered at the 50% default (a disclosed simulation convenience, not a model of real PIR detection-range physics, since this simulator has no distance/heat-source concept to give Sensitivity its real datasheet meaning); and Retrigger Mode — Repeatable ("H", the common factory-default jumper position) or Non-repeatable ("L").
- Go to the Code tab and write a script that polls the OUT pin in a loop:
import RPi.GPIO as GPIOimport asyncio GPIO.setmode(GPIO.BOARD)PIR_OUT = 38 # adjust to match your wiring GPIO.setup(PIR_OUT, GPIO.IN) while True: if GPIO.input(PIR_OUT) == 1: print("Motion detected!") else: print("No motion.") await asyncio.sleep(0.5)- Click Start.
- Click directly on the sensor's own body on the Canvas — this simulates a real motion event, the same way a person walking in front of an actual HC-SR501 would trigger it.
Watch the Console: it should switch to printing "Motion detected!" for roughly your configured Delay (scaled by Sensitivity), then return to "No motion." — no further clicks needed for the hold itself to run its course.
- To see the Retrigger Mode setting matter: in Repeatable mode (the default), click the sensor again while it's still reading HIGH — the hold timer restarts at full duration, visibly extending how long "Motion detected!" keeps printing.
- Switch Retrigger Mode to Non-repeatable and repeat — a second click while already triggered is correctly ignored; OUT still returns to LOW at the original scheduled time, unaffected by the extra click.
What “working correctly” looks like
- Clicking the sensor's body lights its own small onboard status LED (matching a real HC-SR501 board's indicator) and flips OUT HIGH for roughly your configured Delay × Sensitivity scaling, then back to LOW — visible both on the sensor itself and in the Console's own printed output.
- In Repeatable mode, clicking the sensor again while it's still triggered visibly extends the HIGH window past the original duration.
- In Non-repeatable mode, clicking again while still triggered has no effect at all — OUT returns LOW at the original time regardless.
- Clicking the sensor works whether or not a simulation is currently running, but OUT's value only reaches a running Python script while Start is active — matching how every other GPIO-facing component in this simulator behaves.
If something’s wrong
- OUT never reads HIGH → confirm OUT is wired to the exact pin your script configures with GPIO.setup(pin, GPIO.IN), and confirm you're clicking directly on the sensor's own body, not just near it.
- OUT stays HIGH longer than you expected → check the Sensitivity setting — a higher percentage scales the hold duration up to 1.5× the configured Delay, by design (a disclosed simulation convenience, not real PIR detection-range physics).
- A second click during an active hold doesn't seem to do anything → confirm Retrigger Mode is set to Repeatable — in Non-repeatable mode, a click during an already-active hold is correctly ignored, not a bug.