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

Arduino UNO-Based Smart Parking System with RFID and Ultrasonic Sensors

View and Edit Project In Cirkit DesignerImage of Arduino UNO-Based Smart Parking System with RFID and Ultrasonic Sensors

Circuit Documentation

Summary

This circuit is designed to manage a parking system using an Arduino UNO microcontroller. The system includes RFID for access control, ultrasonic sensors for detecting car presence, a servo motor for gate control, and an LCD screen for displaying available parking slots. The Arduino UNO coordinates all these components and runs the embedded code to manage the parking system.

Component List

  1. HC-SR04 Ultrasonic Sensor

    • Pins: VCC, TRIG, ECHO, GND
    • Description: Used to measure distance to detect the presence of a car.
    • Purpose in Circuit: One sensor is used to detect cars near the gate, and another is used to detect cars in the parking slot.
  2. Arduino UNO

    • Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0, A1, A2, A3, A4, A5, SCL, SDA, AREF, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
    • Description: Microcontroller board based on the ATmega328P.
    • Purpose in Circuit: Acts as the central controller for the parking system.
  3. RFID-RC522

    • Pins: VCC (3.3V), RST, GND, IRQ, MISO, MOSI, SCK, SDA
    • Description: RFID reader module.
    • Purpose in Circuit: Used to read RFID tags for access control.
  4. LCD screen 16x2 I2C

    • Pins: SCL, SDA, VCC, GND
    • Description: 16x2 character LCD display with I2C interface.
    • Purpose in Circuit: Displays the number of available parking slots.
  5. Servo

    • Pins: GND, VCC, PWM
    • Description: Servo motor.
    • Purpose in Circuit: Controls the gate mechanism.

Wiring Details

HC-SR04 Ultrasonic Sensor (Gate)

HC-SR04 Ultrasonic Sensor (Slot)

Arduino UNO

RFID-RC522

LCD screen 16x2 I2C

Servo

Documented Code

#include <MFRC522.h>
#include <Servo.h>
#include <LiquidCrystal_I2C.h>

// RFID setup
#define RST_PIN 9
#define SS_PIN 10
MFRC522 rfid(SS_PIN, RST_PIN);

// Ultrasonic sensors setup
#define TRIG_GATE 6
#define ECHO_GATE 7
#define TRIG_SLOT 8
#define ECHO_SLOT 5

// Servo motor setup
Servo gateServo;

// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Variables
int totalSlots = 1;
int availableSlots = 1;
bool slotRecentlyFreed = false; // Tracks if the slot was just freed

// Allowed and restricted UIDs
const char* allowedUIDs[] = {"C3 CA 3F 1A", "81 A8 52 1B"};
const char* restrictedUIDs[] = {"05 8E 97 02 6E 31 00"};

void setup() {
  Serial.begin(9600);

  // Initialize RFID
  SPI.begin();
  rfid.PCD_Init();

  // Ultrasonic sensors setup
  pinMode(TRIG_GATE, OUTPUT);
  pinMode(ECHO_GATE, INPUT);
  pinMode(TRIG_SLOT, OUTPUT);
  pinMode(ECHO_SLOT, INPUT);

  // Servo motor setup
  gateServo.attach(3);
  gateServo.write(0); // Initial position: closed

  // LCD setup
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Parking System");
  delay(2000);
  lcd.clear();
  updateLCD();
}

void loop() {
  // Check for RFID card
  if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
    String uid = getUID();
    Serial.print("RFID UID: ");
    Serial.println(uid);

    // Check UID access
    if (isUIDAllowed(uid) && isCarNearGate()) {
      if (availableSlots > 0) {
        Serial.println("Access granted!");
        openGate(3000);
      } else {
        Serial.println("No slots available!");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("No Slots Available");
        delay(2000);
        updateLCD();
      }
    } else if(!isCarNearGate()){
      // 
    } 
    
    else {
      Serial.println("Access denied!");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Access Denied");
      delay(2000);
      updateLCD();
    }

    rfid.PICC_HaltA(); // Halt RFID reading
  }

  // Monitor parking slot status
  if (isSlotOccupied()) {
    if (availableSlots > 0) {
      availableSlots--;
      updateLCD();
    }
  } else {
    if (availableSlots < totalSlots) {
      availableSlots++;
      slotRecentlyFreed = true; // Mark slot as recently freed
      updateLCD();
    }
  }

  // Handle exit logic
  if (slotRecentlyFreed) {
    Serial.println("Car leaving. Opening gate.");
    openGate(5000);
    slotRecentlyFreed = false; // Reset flag after gate opens
  }

  delay(500); // Delay to avoid rapid updates
}

void openGate(int delayTime) {
  // Open the gate
  gateServo.write(90); // Open gate
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Gate Opening...");
  delay(delayTime); // Keep gate open for specified seconds
  gateServo.write(0);  // Close gate
  lcd.clear();
  updateLCD();
}

bool isCarNearGate() {
  digitalWrite(TRIG_GATE, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_GATE, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_GATE, LOW);
  long duration = pulseIn(ECHO_GATE, HIGH);
  int distance = duration * 0.034 / 2;
  return distance < 10; // Car detected within 10 cm
}

bool isSlotOccupied() {
  digitalWrite(TRIG_SLOT, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_SLOT, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_SLOT, LOW);
  long duration = pulseIn(ECHO_SLOT, HIGH);
  int distance = duration * 0.034 / 2;
  return distance < 10; // Car detected within 10 cm
}

void updateLCD