Skip to content

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

Cart

Prices 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.

  1. Connect 5V rail from Pi to breadboard + rail.
  2. Connect GND from Pi to breadboard - rail.
  3. Place both IR sensors on breadboard spaced apart.
  4. Connect sensor power pins to 5V rail.
  5. Connect sensor GND pins to GND rail.
  6. Connect a 10kΩ resistor from each sensor signal pin to GND.
  7. 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.

  1. Create a test script to read GPIO inputs.
  2. Wave your hand over each sensor.
  3. Verify the GPIO pin goes HIGH when motion is detected.
  4. 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.

  1. Set up GPIO pins as inputs with pull-down resistors.
  2. Create a function to check sensor states.
  3. Detect entry: outside sensor triggers, then inside sensor triggers → add 1.
  4. Detect exit: inside sensor triggers, then outside sensor triggers → subtract 1.
  5. Wait for both sensors to clear before counting again.
python
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.

  1. Install Tkinter for GUI: sudo apt-get install python3-tk
  2. Create a simple window displaying current occupancy.
  3. Update the display each time count changes.
  4. 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.