Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino Nano-Based Passenger Counter with LoRa and LCD Display

View and Edit Project In Cirkit DesignerImage of Arduino Nano-Based Passenger Counter with LoRa and LCD Display

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

  1. 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
  2. LCD screen 16x2 I2C

    • Description: A 16x2 character LCD display with I2C interface.
    • Pins: SCL, SDA, VCC, GND
  3. 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
  4. IR Sensor

    • Description: An infrared sensor used for detecting objects.
    • Pins: out, gnd, vcc
  5. Potentiometer

    • Description: A variable resistor used to adjust the passenger count.
    • Pins: GND, Output, VCC
  6. 5V Battery

    • Description: A power source providing 5V.
    • Pins: +, -

Wiring Details

Arduino Nano

LCD screen 16x2 I2C

RFM95

IR Sensor (instance 1)

IR Sensor (instance 2)

Potentiometer

5V Battery

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 +