Arduino-Based Smart Toll Gate Automation System with RFID, GSM, Ultrasonic Sensor and LCD Display

Arduino Smart Toll Gate Automation System – RFID, GSM, Ultrasonic & LCD | MakeMindz
🚗 Advanced · Arduino UNO · IoT · Smart City

Smart Toll Gate
Automation System

RFID-based automatic toll collection using Arduino UNO with servo motor barrier, ultrasonic vehicle detection, GSM SMS notifications, and I2C LCD display — a complete smart city traffic solution.

· By MakeMindz

Arduino UNO RFID RC522 Servo Motor GSM / SIM800L I2C LCD 16×2 Ultrasonic HC-SR04

📖 Read the complete project guide with simulation on MakeMindz

🔗 View Full Project on MakeMindz
// 01

Project Overview

An intelligent toll booth that replaces manual collection with automated RFID authentication and servo gate control

The Smart Toll Gate Automation System uses an RFID RC522 module to identify vehicles equipped with prepaid RFID tags. When a vehicle approaches, the HC-SR04 ultrasonic sensor detects its presence and prompts the driver to scan their card. The RFID UID is matched against a stored database — if the card is valid and the balance is sufficient, the driver confirms payment via a push button, and the servo motor barrier opens automatically.

After deducting the toll fee, the GSM module sends an instant SMS to the vehicle owner confirming the transaction. An IR sensor detects when the vehicle has fully passed, then closes the gate. The I2C 16×2 LCD displays real-time system status throughout the process.

A second Arduino can be connected via SoftwareSerial for dual-controller architecture — receiving payment status updates for logging or display purposes.

📡

RFID Authentication

MFRC522 scans vehicle RFID tags via SPI — verifies UID against stored card database

🚧

Servo Barrier

Servo rotates 0°→90° to open, waits for IR clear signal, then returns to 0° to close

📏

Ultrasonic Detection

HC-SR04 measures vehicle distance — triggers RFID scan only when car is within 50cm

📱

GSM SMS Alert

SIM800L sends SMS to owner confirming toll amount and remaining prepaid balance

🖥️

LCD Status Display

I2C 16×2 LCD shows live status: scanning, processing, granted, insufficient, denied

⏱️

10-Second Timer

Payment confirmation window — button must be pressed within 10 seconds or timeout occurs

💾

Prepaid Balance System

Card balances stored in Arduino memory — deducted on each successful toll payment

🔗

Dual Arduino Serial

SoftwareSerial sends payment status to a second Arduino for logging or remote display

// 02

LCD Status Messages

Real-time messages shown on the 16×2 LCD throughout the toll process

Toll Booth Ready Waiting for Car Vehicle Detected Pay 50 Taka? Payment Success Payment Timeout Insufficient Bal Card Not Recognized Opening Gate... Closing Gate...
💡 I2C LCD Address The LCD uses I2C address 0x27 (common for PCF8574 backpack). If your LCD doesn't display anything, try 0x3F. Use an I2C scanner sketch to find the correct address for your module.
// 03

Components Required

All hardware needed to build the smart toll gate system

01

Arduino UNO

Main controller — manages RFID reading, LCD display, servo control, ultrasonic sensing, and GSM communication

02

RFID RC522 Module + RFID Cards/Tags

Reads vehicle RFID tags via SPI protocol. Provides unique UID per card matched against the registered vehicle database

03

Servo Motor (SG90 or MG90S)

Controls the physical barrier arm — rotates 90° to open, 0° to close. Connected to PWM pin 5.

04

HC-SR04 Ultrasonic Sensor

Detects vehicle presence at the toll booth — triggers the RFID scan workflow only when a vehicle is within 50cm

05

GSM Module (SIM800L / SIM900)

Sends SMS payment confirmation to the registered vehicle owner. Communicates via SoftwareSerial UART.

06

I2C 16×2 LCD Display

Shows real-time system status messages. Uses I2C protocol (only 2 wires: SDA + SCL) — address 0x27

07

IR Sensor Module

Detects when the vehicle has fully passed through the gate — triggers the gate to close automatically

08

Push Button

Payment confirmation button — driver presses within 10 seconds to confirm toll deduction and open gate

09

Jumper Wires + Breadboard

For connections and prototyping — male-to-male and male-to-female wires for all module interconnections

// 04 — Wiring Diagram
// 05

Pin Configuration & Wiring

Complete pin mapping for all modules connected to Arduino UNO

Module / Pin Arduino Pin Notes
RFID RC522 (SPI)
RFID SS (SDA)Pin 10SS_PIN — chip select
RFID RSTPin 9RST_PIN — reset
RFID MOSIPin 11SPI MOSI
RFID MISOPin 12SPI MISO
RFID SCKPin 13SPI Clock
RFID VCC3.3V⚠️ 3.3V only — not 5V!
Ultrasonic (HC-SR04)
TRIGPin 6Trigger pulse output
ECHOPin 7Echo pulse input
Servo Motor + IR + Button
Servo SignalPin 5PWM — gate barrier
IR Sensor OUTPin 4IR_PIN — vehicle clear detect
Push ButtonPin 2INPUT_PULLUP — payment confirm
GSM Module (SoftwareSerial)
GSM TXPin 3GSM_TX — to GSM RX
GSM RXPin 8GSM_RX — to GSM TX (reassigned)
I2C LCD 16×2
LCD SDAA4I2C Data
LCD SCLA5I2C Clock
⚠️ RFID Voltage — Use 3.3V Not 5V The MFRC522 RC522 module operates at 3.3V. Connecting VCC to 5V will permanently damage the module. Always use the Arduino UNO's 3.3V pin.
⚠️ GSM Power Requirements The SIM800L draws up to 2A during transmission. Never power it from the Arduino's 5V pin — use a dedicated 3.7–4.2V LiPo battery or regulated 4V supply with at least 2A capacity.
💡 Pin 2 Conflict — GSM & Button In the original code both GSM_RX and BUTTON_PIN were defined as pin 2. In this corrected build, GSM_RX is reassigned to pin 8 and the button stays on pin 2 with INPUT_PULLUP.
// 06

Arduino Code

Full sketch — includes RFID, servo gate, ultrasonic detection, LCD, and GSM SMS

① Libraries, Pins & Data Structures

sketch.ino — definitions
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

#define RST_PIN    9
#define SS_PIN     10
#define TRIG_PIN   6
#define ECHO_PIN   7
#define IR_PIN     4
#define SERVO_PIN  5
#define BUTTON_PIN 2
#define GSM_TX     3
#define GSM_RX     8   // Reassigned to avoid pin 2 conflict

MFRC522 mfrc522(SS_PIN, RST_PIN);
Servo   gateServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial gsm(GSM_RX, GSM_TX);
SoftwareSerial serialComm(3, 4);

// Registered RFID cards with prepaid balances
struct RFIDCard {
  String uid;
  int    balance;
};

RFIDCard rfidCards[] = {
  {"F3E45216", 200},
  {"A1B2C3D4", 100}
};
const int tollFee = 50;

② Setup & Main Detection Loop

sketch.ino — setup() & loop()
void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  lcd.init(); lcd.backlight();
  lcd.print("Toll Booth Ready");
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(IR_PIN,   INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  gateServo.attach(SERVO_PIN);
  gateServo.write(0);           // Barrier closed at startup
  gsm.begin(9600);
  serialComm.begin(9600);
}

void loop() {
  if (detectVehicle()) {
    lcd.setCursor(0, 0);
    lcd.print("Vehicle Detected");
    delay(500); lcd.clear();

    if (mfrc522.PICC_IsNewCardPresent() &&
        mfrc522.PICC_ReadCardSerial()) {
      String cardID     = getCardID();
      int    balanceIdx = getBalanceIndex(cardID);
      lcd.setCursor(0, 0);

      if (balanceIdx != -1) {
        if (rfidCards[balanceIdx].balance >= tollFee) {
          lcd.print("Pay 50 Taka?");
          bool paid = false;
          unsigned long t = millis();

          while (millis() - t < 10000) {        // 10s window
            if (digitalRead(BUTTON_PIN) == LOW) {
              paid = true; break;
            }
          }

          if (paid) {
            rfidCards[balanceIdx].balance -= tollFee;
            lcd.setCursor(0, 1);
            lcd.print("Payment Success ");
            serialComm.println("Payment Successful");
            String msg = "Toll: 50 deducted. Balance: " +
              String(rfidCards[balanceIdx].balance);
            sendSMS("+8801743648510", msg);
            openGate();
          } else {
            lcd.setCursor(0, 1);
            lcd.print("Payment Timeout");
            serialComm.println("Payment Timeout");
          }
        } else {
          lcd.print("Insufficient Bal");
          serialComm.println("Insufficient Balance");
          delay(2000);
        }
      } else {
        lcd.print("Card Not Found");
        serialComm.println("Card Not Recognized");
        delay(2000);
      }
      mfrc522.PICC_HaltA();
      lcd.clear();
    }
  } else {
    lcd.setCursor(0, 0);
    lcd.print("Waiting for Car ");
    delay(500); lcd.clear();
  }
}

③ Helper Functions

sketch.ino — helper functions
// Ultrasonic distance — returns true if vehicle within 50cm
bool detectVehicle() {
  digitalWrite(TRIG_PIN, LOW);  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  long dur  = pulseIn(ECHO_PIN, HIGH);
  int  dist = dur * 0.034 / 2;
  return (dist < 50);
}

// Read RFID UID as uppercase hex string
String getCardID() {
  String id = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (mfrc522.uid.uidByte[i] < 0x10) id += "0";
    id += String(mfrc522.uid.uidByte[i], HEX);
  }
  id.toUpperCase();
  return id;
}

// Find card index by UID, returns -1 if not found
int getBalanceIndex(String uid) {
  for (int i = 0; i < (int)(sizeof(rfidCards)/sizeof(rfidCards[0])); i++)
    if (rfidCards[i].uid == uid) return i;
  return -1;
}

// Servo: open gate, wait for vehicle to pass, then close
void openGate() {
  lcd.setCursor(0, 0); lcd.print("Opening Gate...");
  gateServo.write(90);
  delay(5000);
  while (digitalRead(IR_PIN) == LOW);  // Wait for vehicle to pass
  lcd.setCursor(0, 0); lcd.print("Closing Gate...");
  gateServo.write(0);
  delay(1500); lcd.clear();
}

// GSM AT commands — send SMS via SIM800L
void sendSMS(String phone, String msg) {
  gsm.print("AT+CMGF=1\r");   delay(100);
  gsm.print("AT+CMGS=\"" + phone + "\"\r"); delay(100);
  gsm.print(msg);              delay(100);
  gsm.write(26);              // Ctrl+Z to send
  delay(5000);
  Serial.println("SMS sent to " + phone);
}
// 07

How It Works

Step-by-step operation of the automatic toll gate system

1

Vehicle Approaches — Ultrasonic Detects

The HC-SR04 sends a 10μs TRIG pulse and measures the ECHO return time. If distance is under 50cm, a vehicle is confirmed at the booth — LCD shows "Vehicle Detected" and the RFID scan is activated.

2

Driver Scans RFID Card

The MFRC522 reads the card's UID via SPI. The UID is converted to an uppercase hex string and searched against the rfidCards[] array. If found, the balance check begins; if not, "Card Not Found" displays.

3

Balance Check & Payment Prompt

If the card balance ≥ tollFee (50), the LCD shows "Pay 50 Taka?" and a 10-second countdown begins. The driver presses the green button to confirm. If no press within 10 seconds, "Payment Timeout" displays.

4

Payment Confirmed — Deduct & Notify

On button press, the toll fee is deducted from the card's balance in memory. A status update is sent to the second Arduino via SoftwareSerial. The GSM module sends an SMS to the registered phone number with the remaining balance.

5

Gate Opens — Vehicle Passes

gateServo.write(90) lifts the barrier. The system waits 5 seconds minimum, then polls the IR sensor. When the IR sensor clears (vehicle fully through), the gate closes with gateServo.write(0).

6

System Resets to Standby

LCD clears, the system returns to "Waiting for Car" state, and the ultrasonic sensor resumes polling for the next vehicle. The process repeats for every vehicle.

// 08

Key Concepts Explained

Protocols and techniques used in this advanced Arduino project

A — SPI Communication (RFID RC522)

Serial Peripheral Interface Protocol

The MFRC522 communicates via SPI using 4 lines: MOSI (master out), MISO (master in), SCK (clock), and SS (chip select). The Arduino acts as SPI master. When mfrc522.PICC_IsNewCardPresent() returns true, the reader has detected a card in its field, and PICC_ReadCardSerial() retrieves the full UID.

B — UART GSM Communication

AT Commands via SoftwareSerial

The SIM800L uses Hayes AT command set over UART. AT+CMGF=1 sets text mode, AT+CMGS="number" specifies the recipient, the message text is sent next, and write(26) (Ctrl+Z, ASCII 26) tells the modem to dispatch the SMS. SoftwareSerial emulates UART on non-hardware pins.

C — I2C LCD Display

Inter-Integrated Circuit 2-Wire Bus

The I2C LCD uses only two wires (SDA + SCL) compared to the 6–8 wires of parallel LCD wiring. A PCF8574 I/O expander chip on the LCD backpack converts I2C signals to the parallel interface the LCD controller needs. The LiquidCrystal_I2C library handles all addressing and data framing.

D — Servo PWM Gate Control

Pulse Width Modulation Positioning

A servo motor position is set by the width of a PWM pulse: ~1ms = 0°, ~1.5ms = 90°, ~2ms = 180°. gateServo.write(0) closes the barrier and gateServo.write(90) opens it. The Servo library handles PWM generation on pin 5 automatically — no manual timing needed.

E — Ultrasonic Distance Measurement

Sound Echo Time-of-Flight

The HC-SR04 emits a 40kHz ultrasonic burst (TRIG HIGH for 10μs), then measures how long the echo takes to return. Distance = (echo duration × speed of sound) ÷ 2. At 20°C, speed of sound ≈ 343 m/s, so the formula becomes distance = duration × 0.034 / 2 in centimetres.

// 09

Real-World Applications

Where this smart toll gate system can be deployed

🛣️

Highway Toll Booths

Automate toll collection on expressways — reduce queues and eliminate manual cash handling

🏙️

Smart City Traffic

Integrate with city-wide traffic management systems for congestion pricing and zone access

🅿️

Parking Lot Control

Automatic entry and exit barrier for prepaid parking passes — logs timestamps per vehicle

🏭

Factory Vehicle Entry

Authenticate registered delivery vehicles — log all entries and deny unauthorized access

🚌

Transport Monitoring

RFID-based bus or truck fleet tracking at checkpoints with timestamp logging

🏫

Campus Gate Control

University or school vehicle access control — only registered staff/student vehicles enter

// 10

Future Enhancements

Ways to extend and upgrade this project

☁️Cloud-based toll management dashboard
💳Automatic balance recharge integration
📷Number plate recognition system
📶ESP32 Wi-Fi live monitoring
🖥️Centralized toll data server
🛣️Multi-lane toll automation
📊Traffic analytics dashboard
🔋Solar-powered toll station
🚗 Arduino UNO · RFID · Servo · GSM · Smart Toll Gate
Smart Toll Gate Automation System · MakeMindz

Comments

try for free