To build a reliable raspberry pi movement detection system, use an HC-SR501 PIR (Passive Infrared) sensor for standard room occupancy, or an RCWL-0516 mmWave radar if you need through-wall detection. Wire the sensor's digital output to GPIO 17 (BCM numbering), power it from the 5V rail, and use the gpiozero library on Raspberry Pi OS Bookworm for event-driven Python detection. This guide walks through the exact hardware selection, wiring safety checks, and the specific software debugging steps required for modern Pi environments.

Sensor Technology Comparison: PIR vs. mmWave vs. Digital PIR

Before wiring anything, you need to select the right sensor for your environment. Standard analog PIRs are cheap but prone to thermal false triggers. mmWave sensors penetrate drywall but consume more power. Here is how the three most common modules stack up for embedded projects in 2026.

Sensor Model Technology Detection Range Quiescent Current Avg Price (2026) Best Use Case
HC-SR501 Analog PIR (Fresnel lens) Up to 7m (120°) ~50 µA $1.50 - $2.50 Budget room occupancy, battery-backed setups
RCWL-0516 Microwave Radar (Doppler) Up to 9m (360° through walls) ~2.8 mA $2.00 - $3.50 Hidden sensors behind enclosures/drywall
Panasonic EKMC1603111 Digital PIR (Silicon lens) Up to 12m (Multi-zone) ~150 µA $8.00 - $12.00 High-reliability commercial/industrial IoT
HLK-LD2410 24GHz mmWave (FMCW) Up to 6m (Static & moving) ~70 mA $4.50 - $6.00 Human presence (detects breathing/micro-movements)

Parts List & Pin Mapping

This build targets the Raspberry Pi 5 (4GB or 8GB variant) running Raspberry Pi OS (Bookworm). The software architecture relies on the lgpio backend, which is mandatory for Pi 5 GPIO access.

Bench Note: The HC-SR501 requires a minimum of 4.5V to operate its internal HT7133 voltage regulator. Do not attempt to power it directly from the Pi's 3.3V pin, or the sensor will fail to initialize.

Required Components

  • Microcontroller: Raspberry Pi 5 (4GB/8GB) with active cooler
  • Sensor: HC-SR501 PIR Motion Sensor module
  • Resistor: 10kΩ pull-down resistor (optional, prevents floating pin state during Pi boot)
  • Wiring: 3x Female-to-Female Dupont jumper wires
  • Tools: Digital multimeter (for voltage verification)

Pin Mapping Table

HC-SR501 Pin Raspberry Pi 5 Pin (Physical) BCM GPIO Function
VCC Pin 2 or 4 N/A 5V Power Input
OUT Pin 11 GPIO 17 Digital Signal (High on motion)
GND Pin 9 N/A Ground Reference

Wiring & Physical Setup

Follow these steps to wire the circuit safely. Always de-energize the Pi before making physical GPIO connections to prevent accidental short circuits on the 5V rail.

  1. Power Down: Shut down the Raspberry Pi via the OS and disconnect the USB-C power supply.
  2. Connect Power: Plug the HC-SR501 VCC pin into Physical Pin 2 (5V) and GND into Physical Pin 9.
  3. Verify Output Voltage (Critical Step): Before connecting the OUT pin to the Pi, power the Pi back up. Set your multimeter to DC Voltage. Probe the HC-SR501 OUT pin and GND. It should read ~3.3V when triggered (wave your hand over the lens). If it reads 5V, your specific board lacks the internal LDO regulator. You must build a voltage divider (e.g., 2kΩ and 3.3kΩ) to step the signal down to 3.3V before connecting it to GPIO 17, or you will fry the Pi 5's GPIO bank.
  4. Connect Signal: Once verified at 3.3V, power down again and connect the OUT pin to Physical Pin 11 (BCM GPIO 17).
  5. Adjust Potentiometers: The HC-SR501 has two orange trimpots. Turn the 'Delay Time' pot fully counter-clockwise for a ~0.3s reset time. Turn the 'Sensitivity' pot to the 12 o'clock position for a ~4m range.

Python Implementation with Error Handling

With the release of Raspberry Pi OS Bookworm, the legacy RPi.GPIO library is deprecated and incompatible with the Pi 5. We use gpiozero backed by lgpio. Ensure you have the required packages installed via terminal: sudo apt install python3-gpiozero python3-rpi-lgpio.

For deeper library documentation, refer to the official gpiozero documentation.

#!/usr/bin/env python3
"""
Raspberry Pi Movement Detection using HC-SR501 PIR Sensor
Target: Raspberry Pi 5 (Bookworm OS)
Library: gpiozero (lgpio backend)
"""

import sys
import time
import logging
from signal import pause

# Configure logging for terminal and file output
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout),
        logging.FileHandler('movement_log.txt')
    ]
)
logger = logging.getLogger(__name__)

try:
    # Import gpiozero components
    from gpiozero import MotionSensor
    from gpiozero.exc import BadPinFactory, GPIOPinInUse

    # PIN DEFINITION
    # BCM 17 corresponds to Physical Pin 11
    PIR_PIN = 17 
    
    # Initialize sensor with a 1-second queue to debounce rapid triggers
    pir = MotionSensor(PIR_PIN, queue_len=1, pull_up=False, bounce_time=0.5)
    logger.info(f'Successfully initialized PIR sensor on BCM GPIO {PIR_PIN}')

    def motion_detected_callback():
        timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
        logger.info(f'MOVEMENT DETECTED at {timestamp}')
        # Add your payload logic here (e.g., trigger camera, send MQTT)

    def motion_stopped_callback():
        logger.info('Area is now clear. Sensor reset.')

    # Bind events
    pir.when_motion = motion_detected_callback
    pir.when_no_motion = motion_stopped_callback

    logger.info('Listening for movement... Press CTRL+C to exit.')
    pause() # Keep the script running efficiently

except ImportError as e:
    logger.critical(f'Missing dependency: {e}. Run: sudo apt install python3-gpiozero python3-rpi-lgpio')
    sys.exit(1)

except BadPinFactory:
    logger.critical('gpiozero cannot find a valid pin factory. Ensure rpi-lgpio is installed for Pi 5.')
    sys.exit(1)

except GPIOPinInUse:
    logger.critical(f'GPIO {PIR_PIN} is currently in use by another process. Check wiringPi or pigpio daemons.')
    sys.exit(1)

except KeyboardInterrupt:
    logger.info('Script terminated by user.')
    sys.exit(0)

except Exception as e:
    logger.error(f'An unexpected error occurred: {e}')
    sys.exit(1)

Debugging: The First Three Things to Check When It Fails

When your raspberry pi movement detection script fails or behaves erratically, run through this ranked decision tree. These are the most common failure modes on modern Pi hardware.

1. Software Error: ModuleNotFoundError: No module named 'RPi.GPIO'

  • Cause: You are using legacy code written for Raspberry Pi OS Bullseye or earlier. The Pi 5's RP1 southbridge chip does not support the old RPi.GPIO C-extension.
  • Fix: Refactor your code to use gpiozero (as shown above) or the raw lgpio Python bindings. Do not attempt to force-install RPi.GPIO via pip; it will fail to compile or crash the kernel.

2. Software Error: gpiozero.exc.BadPinFactory

  • Cause: gpiozero is installed, but it cannot find the underlying hardware backend to talk to the GPIO pins. This happens on Bookworm if the lgpio backend is missing.
  • Fix: Run sudo apt install python3-rpi-lgpio. If you are running inside a Docker container, you must pass the --privileged flag and map /dev/gpiomem into the container, otherwise the pin factory will fail to initialize.

3. Hardware Error: Phantom Triggers (Continuous False Positives)

  • Cause: The HC-SR501 is highly sensitive to thermal drift and power supply noise. If the Pi's 5V rail has ripple, or if a heat source (like the Pi's own CPU heatsink) is in the sensor's field of view, it will trigger constantly.
  • Fix: First, ensure the white Fresnel lens is securely seated; a loose lens causes focal scattering. Second, adjust the 'Sensitivity' trimpot counter-clockwise to reduce the detection cone. Finally, add a 100µF electrolytic capacitor across the VCC and GND pins on the sensor board to smooth out voltage dips caused by the Pi's Wi-Fi radio transmitting.

Extending and Simplifying the Build

Depending on your end goal, you may need to scale this project up for home automation or scale it down for reliability.

How to Simplify the Build

If you are tired of tuning analog potentiometers and dealing with PIR thermal false triggers, swap the HC-SR501 for an I2C Time-of-Flight (ToF) sensor like the VL53L1X. While it costs roughly $8 more, it provides exact millimeter distance measurements via digital I2C. You define a 'zone' in software (e.g., 'trigger if object is < 1500mm'), completely eliminating hardware tuning and ambient light interference.

How to Extend the Build

To turn this standalone script into a smart home node, integrate the MQTT protocol to publish state changes to Home Assistant or Node-RED.

  1. Install the Paho MQTT library: pip install paho-mqtt.
  2. Initialize the client in your Python script: client = mqtt.Client('pi_pir_node').
  3. Inside the motion_detected_callback function, publish a JSON payload: client.publish('home/livingroom/motion', '{"state": "ON", "lux": 45}', qos=1).
  4. This allows your Pi to act as a wireless edge sensor, feeding movement data directly into your central automation server without relying on local polling.