Arduino Nano-Based Passenger Counter with LoRa and LCD Display
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to monitor and transmit passenger count data using an Arduino Nano, an LCD screen, IR sensors, a potentiometer, and an RFM95 LoRa module. The system counts passengers entering and exiting through IR sensors, displays the count on an LCD screen, and transmits the data via LoRa. The potentiometer can also be used to adjust the passenger count.
Component List
Arduino Nano
- Description: A small, complete, and breadboard-friendly board based on the ATmega328P.
- Pins: D1/TX, D0/RX, RESET, GND, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11/MOSI, D12/MISO, VIN, 5V, A7, A6, A5, A4, A3, A2, A1, A0, AREF, 3V3, D13/SCK
LCD screen 16x2 I2C
- Description: A 16x2 character LCD display with I2C interface.
- Pins: SCL, SDA, VCC, GND
RFM95
- Description: A LoRa transceiver module for long-range communication.
- Pins: DIO2, DIO1, DIO0, 3.3V, DIO4, DIO3, GND, ANT, MISO, MOSI, SCK, NSS, RESET, DIO5
IR Sensor
- Description: An infrared sensor used for detecting objects.
- Pins: out, gnd, vcc
Potentiometer
- Description: A variable resistor used to adjust the passenger count.
- Pins: GND, Output, VCC
5V Battery
- Description: A power source providing 5V.
- Pins: +, -
Wiring Details
Arduino Nano
- D13/SCK connected to RFM95 SCK
- D12/MISO connected to RFM95 MISO
- 3V3 connected to RFM95 3.3V
- D11/MOSI connected to RFM95 MOSI
- D10 connected to RFM95 NSS
- A0 connected to Potentiometer Output
- D9 connected to RFM95 RESET
- A4 connected to LCD screen 16x2 I2C SDA
- A5 connected to LCD screen 16x2 I2C SCL
- D3 connected to IR Sensor (instance 1) out
- D2 connected to IR Sensor (instance 2) out and RFM95 DIO0
- 5V connected to IR Sensor (instance 1) vcc, IR Sensor (instance 2) vcc, LCD screen 16x2 I2C VCC, Potentiometer VCC, and 5V Battery +
- GND connected to RFM95 GND, IR Sensor (instance 1) gnd, IR Sensor (instance 2) gnd, LCD screen 16x2 I2C GND, Potentiometer GND, and 5V Battery -
LCD screen 16x2 I2C
- SCL connected to Arduino Nano A5
- SDA connected to Arduino Nano A4
- VCC connected to Arduino Nano 5V
- GND connected to Arduino Nano GND
RFM95
- SCK connected to Arduino Nano D13/SCK
- MISO connected to Arduino Nano D12/MISO
- 3.3V connected to Arduino Nano 3V3
- MOSI connected to Arduino Nano D11/MOSI
- NSS connected to Arduino Nano D10
- RESET connected to Arduino Nano D9
- DIO0 connected to Arduino Nano D2
- GND connected to Arduino Nano GND
IR Sensor (instance 1)
- out connected to Arduino Nano D3
- gnd connected to Arduino Nano GND
- vcc connected to Arduino Nano 5V
IR Sensor (instance 2)
- out connected to Arduino Nano D2
- gnd connected to Arduino Nano GND
- vcc connected to Arduino Nano 5V
Potentiometer
- Output connected to Arduino Nano A0
- GND connected to Arduino Nano GND
- VCC connected to Arduino Nano 5V
5V Battery
- + connected to Arduino Nano 5V
- - connected to Arduino Nano GND
Code Documentation
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <LoRa.h>
// Initialize LCD with I2C address (commonly 0x27 or 0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin assignments for IR sensors and potentiometer
const int entranceSensorPin = 2; // Digital pin for entrance IR sensor
const int exitSensorPin = 3; // Digital pin for exit IR sensor
const int potentiometerPin = A0; // Analog pin for potentiometer (ensure correct connection on Nano)
// Variables to store passenger count and previous sensor states
int passengerCount = 0;
int previousEntranceState = LOW;
int previousExitState = LOW;
int previousPotValue = 0;
// Maximum passenger capacity
const int maxCapacity = 20;
// LoRa settings
const int csPin = 10;
const int resetPin = 9;
const int irqPin = 2;
const long frequency = 433E6; // 433 MHz
// Destination and license information
const String destination = "Mataas na Kahoy";
const String license = "carlo6969";
void setup() {
// Initialize serial communication for debugging (optional)
Serial.begin(9600);
// Initialize LCD
lcd.init();
lcd.backlight();
// Set up sensor pins
pinMode(entranceSensorPin, INPUT);
pinMode(exitSensorPin, INPUT);
// Initialize LoRa
LoRa.setPins(csPin, resetPin, irqPin);
if (!LoRa.begin(frequency)) { // Set frequency to 433 MHz
lcd.setCursor(0, 1);
lcd.print("LoRa init failed!");
delay(2000); // Display the error message for 2 seconds
} else {
lcd.setCursor(0, 1);
lcd.print("LoRa init success");
delay(2000); // Display the success message for 2 seconds
}
// Print the frequency to the serial monitor for verification
Serial.print("LoRa Frequency set to: ");
Serial.print(frequency);
Serial.println(" Hz");
// Display initial passenger count (starting at 0)
updateLCD();
}
void loop() {
// Read current sensor states
int currentEntranceState = digitalRead(entranceSensorPin);
int currentExitState = digitalRead(exitSensorPin);
// Detect rising edge for entrance sensor (LOW to HIGH)
if (currentEntranceState == HIGH && previousEntranceState == LOW && passengerCount < maxCapacity) {
passengerCount++;
updateLCD();
Serial.println("Entrance detected. Count: " + String(passengerCount));
delay(100); // Debounce delay to prevent multiple counts
}
// Detect rising edge for exit sensor (LOW to HIGH)
if (currentExitState == HIGH && previousExitState == LOW) {
passengerCount = max(0, passengerCount - 1); // Ensure count doesn't go negative
updateLCD();
Serial.println("Exit detected. Count: " + String(passengerCount));
delay(100); // Debounce delay to prevent multiple counts
}
// Update previous sensor states for edge detection
previousEntranceState = currentEntranceState;
previousExitState = currentExitState;
// Read potentiometer value and scale it to 0-255
int potValue = analogRead(potentiometerPin) / 4; // 0-1023 mapped to 0-255
// Check for significant potentiometer change (threshold of 10)
if (abs(potValue - previousPotValue) > 10) {
if (potValue > previousPotValue && passengerCount < maxCapacity) {
passengerCount++;
Serial.println("Potentiometer turned CW. Count: " + String(passengerCount));
} else {
passengerCount = max(0, passengerCount - 1);
Serial.println("Potentiometer turned CCW. Count: " + String(passengerCount));
}
previousPotValue = potValue;
updateLCD();
delay(100); // Debounce delay for potentiometer
}
// Prepare data to send
String data = destination +