Occupancy Counter with PIR Sensors
Build a people counter using Raspberry Pi and two IR motion sensors to track room occupancy.
- Raspberry Pi
- Intermediate
- 90 minutes
- 4 steps
Shop this project
CartPrices from vilros.com. Tax and shipping at checkout.
Before you start, you'll need
- Raspberry Pi (Model B Rev 2 or newer)
- 2× IR motion sensors (PIR)
- 2× 10kΩ resistors
- Breadboard
- GPIO ribbon connector
- Jumper wires (8+)
Connect IR motion sensors
About 20 minutes
Wire both PIR sensors to GPIO pins.
- Connect 5V rail from Pi to breadboard + rail.
- Connect GND from Pi to breadboard - rail.
- Place both IR sensors on breadboard spaced apart.
- Connect sensor power pins to 5V rail.
- Connect sensor GND pins to GND rail.
- Connect a 10kΩ resistor from each sensor signal pin to GND.
- Connect sensor 1 signal to GPIO 17, sensor 2 signal to GPIO 27.
You should see
Both sensors are wired and powered.
Test sensor detection
About 15 minutes
Verify sensors detect motion.
- Create a test script to read GPIO inputs.
- Wave your hand over each sensor.
- Verify the GPIO pin goes HIGH when motion is detected.
- Adjust sensor sensitivity if needed (potentiometer on module).
You should see
Both sensors detect motion reliably.
Write the counting logic
About 30 minutes
Program entry/exit detection.
- Set up GPIO pins as inputs with pull-down resistors.
- Create a function to check sensor states.
- Detect entry: outside sensor triggers, then inside sensor triggers → add 1.
- Detect exit: inside sensor triggers, then outside sensor triggers → subtract 1.
- Wait for both sensors to clear before counting again.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
SENSOR_OUTSIDE = 17
SENSOR_INSIDE = 27
GPIO.setup(SENSOR_OUTSIDE, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(SENSOR_INSIDE, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
occupancy = 0
def wait_for_clear():
while GPIO.input(SENSOR_OUTSIDE) or GPIO.input(SENSOR_INSIDE):
time.sleep(0.1)
def count_people():
global occupancy
while True:
# Check for entry (outside sensor first)
if GPIO.input(SENSOR_OUTSIDE):
time.sleep(0.2)
# Wait for inside sensor
timeout = 0
while not GPIO.input(SENSOR_INSIDE) and timeout < 50:
time.sleep(0.1)
timeout += 1
if GPIO.input(SENSOR_INSIDE):
occupancy += 1
print(f"Person entered. Occupancy: {occupancy}")
wait_for_clear()
# Check for exit (inside sensor first)
if GPIO.input(SENSOR_INSIDE):
time.sleep(0.2)
# Wait for outside sensor
timeout = 0
while not GPIO.input(SENSOR_OUTSIDE) and timeout < 50:
time.sleep(0.1)
timeout += 1
if GPIO.input(SENSOR_OUTSIDE):
occupancy = max(0, occupancy - 1)
print(f"Person exited. Occupancy: {occupancy}")
wait_for_clear()
time.sleep(0.1)
try:
count_people()
except KeyboardInterrupt:
GPIO.cleanup()
print("\nCounter stopped.")Mount sensors on door frame sides for real-world use.
You should see
The counter tracks people entering and exiting.
Add a display (optional)
About 25 minutes
Show occupancy on an LCD or GUI.
- Install Tkinter for GUI: sudo apt-get install python3-tk
- Create a simple window displaying current occupancy.
- Update the display each time count changes.
- Or connect an LCD module to show the count.
You should see
Current occupancy is displayed visually.
It didn't work
False counts from sensor noise.
Add longer delays between checks. Adjust sensor sensitivity. Add debouncing logic to require sustained HIGH signals.
What to do next
Stuck? Contact Vilros Support with your board model and what you see on screen.