4 min read
Motion Detection with Pir Sensor
Part 1: Understanding and Interfacing with the Pir Sensor
What is a Pir Sensor?
PIR stands for Passive Infrared sensor. It is an electronic sensor that measures infrared (IR) light radiating from objects in its field of view.
-
How it works: All objects with a temperature above absolute zero emit heat energy in the form of radiation. Usually, this is invisible to the human eye, but PIR sensors can detect it.
-
Motion Detection: The sensor looks for changes in the IR levels. When a warm body (like a human or a pet) moves across the sensor's field of view, the sensor detects a positive differential change. When the body leaves the sensing area, the sensor generates a negative differential change. This change in pulses is what triggers the "Motion Detected" signal.
-
"Passive": It is called "passive" because the sensor does not generate or radiate any energy for detection purposes; it strictly receives energy triggered by other sources.
Interfacing with Python (using gpiozero)
The easiest way to interact with a PIR sensor on the Raspberry Pi is using the gpiozero library. It provides a simple interface for handling input devices.
A. Basic Polling Method
In this method, the code constantly checks (loops) to see if the sensor status has changed.
from gpiozero import MotionSensor
# Initialize the sensor on GPIO Pin 23
pir = MotionSensor(23)
print("Waiting for motion...")
while True:
# 'motion_detected' returns a boolean (True/False)
print(pir.motion_detected)B. Using Interrupts (event-driven)
Checking pir.motion_detected inside a while loop can be inefficient or difficult to manage if your program needs to do other things simultaneously. A better approach is using events or interrupts.
You can assign functions to specific events:
-
pir.when_motion: Triggers when movement is detected. -
pir.when_no_motion: Triggers when movement stops.
Example 1: Controlling an LED based on state This example checks the state inside a loop, similar to the first example but adding an LED.
from gpiozero import MotionSensor, LED
from time import sleep
led = LED(17) # LED on GPIO 17
pir = MotionSensor(23) # PIR on GPIO 23
while True:
sleep(0.01) # Small delay to reduce CPU usage
if pir.motion_detected:
led.on()
else:
led.off()Example 2: The "Clean" Event-Driven Approach This is the recommended way to handle sensors. It uses signal.pause() to keep the script running while waiting for signals, rather than writing your own while True loop.
from gpiozero import MotionSensor, LED
from signal import pause
led = LED(17)
pir = MotionSensor(23) # Ensure you specify the Pin number
print("System Ready. Press Ctrl+C to stop.")
try:
# Assign the callback functions directly
pir.when_motion = led.on
pir.when_no_motion = led.off
# Keep the program running to listen for events
pause()
except KeyboardInterrupt:
print("\nExiting Program...")
# 'pass' does nothing, just allows the block to complete cleanly
passInstalling Libraries on Raspberry Pi
Modern Raspberry Pi OS (Bookworm and later) protects the system Python environment, making it slightly stricter to install packages via pip. Here are the standard methods:
Method A: Using the Gui (thonny)
If you are using the Desktop version of Raspberry Pi OS:
-
Open Thonny IDE.
-
Go to Tools -> Manage Packages.
-
Search for the library name (e.g.,
gpiozero) and click install.
Method B: Using the Terminal
If you are using the Lite version or prefer the command line:
1. APT (Recommended for System-wide) The safest way to install libraries globally is using the system package manager (apt). These versions are pre-tested for your OS.
sudo apt install python3-gpiozero2. PIP (Python Package Installer) If the library is not available via apt, you generally use pip. However, modern OS versions (Ubuntu/Debian 12+) block direct system-wide pip installs to prevent breaking system tools (PEP 668).
-
Option 2.1: Virtual Environments (Best Practice) Create an isolated environment for your project. This prevents conflicts with system updates.
python # Create the environment named 'my-env' python3 -m venv my-env # Activate the environment source my-env/bin/activate # Install your library safely inside this environment pip3 install libname -
Option 2.2: User-Only Installation Install the library only for the current user, not the whole system. This is often allowed without breaking system packages.
python pip3 install --user libname -
Option 2.3: Force System Install (Risky) You can override the protection using the break-system-packages flag. Warning: This effectively tells the OS, "I know what I'm doing, and if the system breaks, it is my responsibility."
python pip3 install libname --break-system-packages
Comments
Loading the discussion…