Bi-Directional People Counter
Using Arduino UNO
A smart room occupancy monitor using two PIR sensors. Tracks entries and exits in real-time, displaying the live count on a 16×2 LCD — hands-free, automatic, and scalable.
How It Works — Direction Detection
Two PIR sensors are placed at the doorway. The Arduino reads the order in which they trigger to determine if someone is entering or exiting.
Decision Flowchart
Count cannot go below 0 — safeguarded in code.
Components Required
Circuit Diagram
Place both PIR sensors ~5 cm apart at the doorway, one behind the other in the direction of travel.
LCD Display Output
The 16×2 LCD (connected in 4-bit mode) continuously shows the current room occupancy:
People In Room:
Count: 3
The count updates instantly whenever a person enters or exits. Count is protected from going below 0.
Pin Connections
PIR Sensors → Arduino UNO
Component Pin Arduino Wire
PIR Sensor 1 VCC 5V Red
PIR Sensor 1 GND GND Black
PIR Sensor 1 OUT (Signal) D2 Teal
PIR Sensor 2 VCC 5V Red
PIR Sensor 2 GND GND Black
PIR Sensor 2 OUT (Signal) D3 Rose
16×2 LCD → Arduino UNO (4-bit mode)
LCD Pin Label Connects To
1 VSS (GND) GND
2 VDD 5V
3 V0 (Contrast) Potentiometer wiper
4 RS D7
5 RW GND
6 EN (Enable) D8
11 D4 D9
12 D5 D10
13 D6 D11
14 D7 D12
15 A (Backlight +) 5V via 220Ω
16 K (Backlight −) GND
Step-by-Step Build Guide
1
Plan Your Doorway Placement
Decide which side of the door is "inside" vs "outside". PIR Sensor 1 (entry detection) should be on the outer side, Sensor 2 on the inner side. Space them ~5 cm apart along the direction of travel.
2
Connect PIR Sensor 1 to Arduino
VCC → 5V, GND → GND, OUT → D2. Use a red wire for power, black for ground, and teal for signal for easy identification.
3
Connect PIR Sensor 2 to Arduino
VCC → 5V, GND → GND, OUT → D3. You can share the 5V and GND rails on the breadboard for both sensors.
4
Set Up the 16×2 LCD in 4-bit Mode
Connect VSS→GND, VDD→5V, RW→GND. Connect RS→D7, EN→D8, D4→D9, D5→D10, D6→D11, D7→D12. Add 220Ω resistor on backlight anode.
5
Wire the Potentiometer for LCD Contrast
Connect the two outer legs of the 10kΩ pot to 5V and GND. Connect the wiper (middle leg) to LCD pin 3 (V0). You'll adjust this after powering on.
6
Install the LiquidCrystal Library
In Arduino IDE, go to Sketch → Include Library → Manage Libraries. Search for "LiquidCrystal" by Arduino and install it. (It may be pre-installed.)
7
Upload the Arduino Code
Paste the code below into Arduino IDE. Select "Arduino UNO" as board, choose your COM port, and click Upload.
8
Adjust LCD Contrast & Test
Turn the potentiometer until the LCD text becomes clearly visible. Then test by walking through the doorway in both directions. The count should increment and decrement correctly.
9
Calibrate PIR Sensitivity
Most HC-SR501 PIR sensors have two orange potentiometers on the back — one adjusts sensitivity, the other adjusts delay time. Set delay to minimum (~0.3s) for fast person detection.
Arduino Code
Uses the built-in LiquidCrystal library — no extra installs needed.
Arduino C++
// ============================================
// Bi-Directional People Counter | MakeMindz
// 2× PIR Sensors + 16×2 LCD + Arduino UNO
// Tinkercad: tinkercad.com (see simulation)
// ============================================
#include <LiquidCrystal.h>
// LCD pin mapping: RS, EN, D4, D5, D6, D7
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// PIR sensor pins
const int PIR1 = 2; // Entry sensor (outer)
const int PIR2 = 3; // Exit sensor (inner)
int count = 0;
bool pir1State = false;
bool pir2State = false;
bool entrySeq = false;
bool exitSeq = false;
void setup() {
pinMode(PIR1, INPUT);
pinMode(PIR2, INPUT);
lcd.begin(16, 2);
lcd.print("People Counter");
lcd.setCursor(0, 1);
lcd.print("makemindz.com");
delay(2000);
updateDisplay();
Serial.begin(9600);
}
void loop() {
bool s1 = digitalRead(PIR1);
bool s2 = digitalRead(PIR2);
// Entry: PIR1 triggers first
if (s1 && !pir1State) {
pir1State = true;
entrySeq = true;
exitSeq = false;
}
if (s2 && entrySeq && !pir2State) {
count++;
pir2State = true;
entrySeq = false;
updateDisplay();
Serial.print("Entry! Count: ");
Serial.println(count);
}
// Exit: PIR2 triggers first
if (s2 && !pir2State) {
pir2State = true;
exitSeq = true;
entrySeq = false;
}
if (s1 && exitSeq && !pir1State) {
if (count > 0) count--; // Never below 0
pir1State = true;
exitSeq = false;
updateDisplay();
Serial.print("Exit! Count: ");
Serial.println(count);
}
// Reset states when sensors go LOW
if (!s1) pir1State = false;
if (!s2) pir2State = false;
delay(50);
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("People In Room:");
lcd.setCursor(0, 1);
lcd.print("Count: ");
lcd.print(count);
}
🔬
Try the Tinkercad Simulation
This exact project has a ready-made Tinkercad simulation — open it and run the code without any hardware.
The Tinkercad link above is the exact simulation for this project — no setup needed.
Key Features & Applications
✅Detects entry and exit direction
✅Real-time occupancy display
✅Automatic counting — no manual input
✅Low cost, easy installation
✅Suitable for small–medium rooms
✅Hands-free, contactless operation
📍 Where to Use It
🏫 Smart Classrooms
🏢 Office Monitoring
📚 Library Control
🛒 Shopping Stores
🔬 Lab Safety
🚀 Possible Upgrades
Buzzer Alert at Max Capacity
Add a passive buzzer to pin D13 — trigger it when count reaches a defined limit (e.g., 30 people).
Automatic Light Control
Connect a relay to automatically turn room lights on when count > 0 and off when the room is empty.
IoT Cloud Monitoring
Add an ESP8266 Wi-Fi module to push occupancy data to platforms like ThingSpeak or Blynk for remote monitoring.
More Arduino Projects
🟢 Beginner Projects
Ultrasonic Distance Measurement
Traffic Light Simulation
16×2 LCD Display
Temperature Measurement
LDR Street Light
Kids Piano Circuit
🔵 Intermediate Projects
Servo + Potentiometer
Temperature Controlled Fan
LPG Gas Leakage Detection
Auto Door Lock
Digital Clock
RGB Lamp Control
🔵 Advanced Projects
Circuit Diagram
Place both PIR sensors ~5 cm apart at the doorway, one behind the other in the direction of travel.
LCD Display Output
The 16×2 LCD (connected in 4-bit mode) continuously shows the current room occupancy:
The count updates instantly whenever a person enters or exits. Count is protected from going below 0.
Pin Connections
PIR Sensors → Arduino UNO
| Component | Pin | Arduino | Wire |
|---|---|---|---|
| PIR Sensor 1 | VCC | 5V | Red |
| PIR Sensor 1 | GND | GND | Black |
| PIR Sensor 1 | OUT (Signal) | D2 | Teal |
| PIR Sensor 2 | VCC | 5V | Red |
| PIR Sensor 2 | GND | GND | Black |
| PIR Sensor 2 | OUT (Signal) | D3 | Rose |
16×2 LCD → Arduino UNO (4-bit mode)
| LCD Pin | Label | Connects To |
|---|---|---|
| 1 | VSS (GND) | GND |
| 2 | VDD | 5V |
| 3 | V0 (Contrast) | Potentiometer wiper |
| 4 | RS | D7 |
| 5 | RW | GND |
| 6 | EN (Enable) | D8 |
| 11 | D4 | D9 |
| 12 | D5 | D10 |
| 13 | D6 | D11 |
| 14 | D7 | D12 |
| 15 | A (Backlight +) | 5V via 220Ω |
| 16 | K (Backlight −) | GND |
Step-by-Step Build Guide
Arduino Code
Uses the built-in LiquidCrystal library — no extra installs needed.
// ============================================ // Bi-Directional People Counter | MakeMindz // 2× PIR Sensors + 16×2 LCD + Arduino UNO // Tinkercad: tinkercad.com (see simulation) // ============================================ #include <LiquidCrystal.h> // LCD pin mapping: RS, EN, D4, D5, D6, D7 LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // PIR sensor pins const int PIR1 = 2; // Entry sensor (outer) const int PIR2 = 3; // Exit sensor (inner) int count = 0; bool pir1State = false; bool pir2State = false; bool entrySeq = false; bool exitSeq = false; void setup() { pinMode(PIR1, INPUT); pinMode(PIR2, INPUT); lcd.begin(16, 2); lcd.print("People Counter"); lcd.setCursor(0, 1); lcd.print("makemindz.com"); delay(2000); updateDisplay(); Serial.begin(9600); } void loop() { bool s1 = digitalRead(PIR1); bool s2 = digitalRead(PIR2); // Entry: PIR1 triggers first if (s1 && !pir1State) { pir1State = true; entrySeq = true; exitSeq = false; } if (s2 && entrySeq && !pir2State) { count++; pir2State = true; entrySeq = false; updateDisplay(); Serial.print("Entry! Count: "); Serial.println(count); } // Exit: PIR2 triggers first if (s2 && !pir2State) { pir2State = true; exitSeq = true; entrySeq = false; } if (s1 && exitSeq && !pir1State) { if (count > 0) count--; // Never below 0 pir1State = true; exitSeq = false; updateDisplay(); Serial.print("Exit! Count: "); Serial.println(count); } // Reset states when sensors go LOW if (!s1) pir1State = false; if (!s2) pir2State = false; delay(50); } void updateDisplay() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("People In Room:"); lcd.setCursor(0, 1); lcd.print("Count: "); lcd.print(count); }
Try the Tinkercad Simulation
This exact project has a ready-made Tinkercad simulation — open it and run the code without any hardware.
The Tinkercad link above is the exact simulation for this project — no setup needed.
Key Features & Applications
📍 Where to Use It
🚀 Possible Upgrades
More Arduino Projects
🟢 Beginner Projects
🔵 Intermediate Projects
🔵 Advanced Projects

Comments
Post a Comment