Back
Smart parking project array architecture
IoT Parking Automation

Smart Parking System

A compact parking automation layout combining secure RFID card validation, ultrasonic proximity checks, and real-time cloud data logging.

YOLOv8 Detection
RFID Priority
Alerts Multi-Channel

Project Overview

This system automates vehicle access inside restricted commercial boundaries. The hardware framework utilizes an MFRC522 RFID reader to authenticate user access, paired with an HC-SR04 ultrasonic sensor to track vehicle presence at the entry point.

A NodeMCU ESP8266 coordinates the logic, streaming real-time status data directly to a Google Sheets dashboard. All firmware source code and wiring diagrams are hosted in our public repository.

Core Hardware Modules

NodeMCU ESP8266 Wi-Fi processor managing sensor inputs and cloud synchronization.
MFRC522 RFID Contactless proximity validation for authorized access tokens.
HC-SR04 Ultrasonic Precision sonar distance checks for vehicle detection.
SG90 Servo Motor Mechanical barrier control for physical gate actuation.

Project Resources

ESP8266 Firmware Motion detection firmware featuring ultrasonic sensing, visitor counting, LED indication, NTP time synchronization, and Twilio WhatsApp alert integration.
Hardware Connections Complete wiring guide for NodeMCU ESP8266, HC-SR04 Ultrasonic Sensor, LED indicator, power connections and GPIO mapping.

Pin Configuration

Component NodeMCU Pin
HC-SR04 TRIG D1 (GPIO5)
HC-SR04 ECHO D2 (GPIO4)
LED Indicator D5 (GPIO14)
VCC VIN
GND GND

System Workflow

Google Assistant

ESP RainMaker

ESP32

Relay Module

Home Appliances

Project Source Codes

1. Arduino UNO Firmware

RFID authentication, slot allocation, ultrasonic vehicle detection, servo gate control, and communication with ESP8266.

Download Arduino Code
View Arduino Source Code

#include 
#include 
#include 
#include 

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

Servo entryServo, exitServo;
SoftwareSerial espSerial(A4, A5);  // RX, TX for ESP8266

// tototal slots
#define MAX_SLOTS 20
#define ACTIVE_SLOTS 20

// IR sensor pins
const int irSlots[MAX_SLOTS] = {
  A0, A1, A2  // only first 3 used now
};

// Feedback components
const int greenLED = 2, redLED = A3, buzzer = A3;

// Ultrasonic sensor pins
const int entryTrig = 7, entryEcho = 8;
const int exitTrig = 3, exitEcho = 4;

int maxCars = ACTIVE_SLOTS;
int carCount = 0;

// List of valid UIDs
String validUIDs[] = { "DE67E056", "E38839DA", "9A755032", 
                        "B94C3B6", "BA1D4732", "128F3A6" };
String onlineBookedAll = "";  // slots booked by others
// Track UIDs currently inside
String activeUIDs[MAX_SLOTS];  // maxCars = 3, so tracking 3 UIDs
int activeSlots[MAX_SLOTS];    // slot used by UID

// ===== ONLINE SLOT DATA FROM ESP8266 =====
int onlineBookedSlot = 0;     // slot booked for this UID (0 = none)
String onlineFreeSlots = "";  // online available slots
bool onlineDataReady = false;

        

2. ESP8266 Cloud Communication

Handles Wi-Fi connectivity, Google Apps Script communication, online slot checking, and cloud synchronization.

Download ESP8266 Code
View ESP8266 Source Code



#include 
#include 
#include 
#include 

// Communication with Arduino
#define RX_PIN D2  // GPIO4
#define TX_PIN D3  // GPIO0
SoftwareSerial mySerial(RX_PIN, TX_PIN);

// Wi-Fi credentials
const char* ssid = "AirFiber-MADAN";
const char* password = "Madan@2004";

String onlineBookedAll = "";  // slots booked by ANY user


// πŸ” SLOT CHECK (booking logic)
// SP-INDEX SCRIPT NAME
const char* CHECK_URL =
  "https://script.google.com/macros/s/AKfycbwjUVLU94eyOB6TGJ_kmw1Svg9na6JiQh8jXX-jvK505IFTNOxUhdofyg0Rqs6xZDAm/exec";

// πŸ“© ENTRY / EXIT β†’ Sheet + Email
// SP-ADMIN PANEL SCRIPT NAME
const char* LOG_URL =
  "https://script.google.com/macros/s/AKfycbyS5PV6vPUtk6CYMX2_gR6hwxlDHjtKPGw3fNUIFw7a5NexX5SdZaKSExGwjtUTHtvN1A/exec";

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

  Serial.println("\nConnecting to WiFi...");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nβœ… WiFi Connected!");
  Serial.println("You can manually type data like:");
  Serial.println("ENTRY:DE67E056:3:1 or EXIT:DE67E056:3:1 and ENTRY:E38839DA:3:1 or EXIT:E38839DA:3:1");
  Serial.println("-----------------------------------------------------------------------------------");
}

void loop() {
  String input = "";

  // Read from Arduino
  if (mySerial.available()) {
    input = mySerial.readStringUntil('\n');
  }

  // Read from Serial Monitor
  if (Serial.available()) {
    input = Serial.readStringUntil('\n');
  }

  if (input.length() > 0) {
    input.trim();
    Serial.println("πŸ“© Received: " + input);

    if (input.startsWith("CHECK:")) {
      handleCheckRequest(input);
    } else if (input.startsWith("ENTRY:") || input.startsWith("EXIT:")) {
      processAndUpload(input);
    } else {
      Serial.println("⚠️ Invalid format. Use CHECK:UID or ENTRY/EXIT");
    }
  }
}

/*
// πŸ”§ Function to get vehicle number based on UID
String getVehicleNumber(String uid) {
  // Add your UID–Vehicle mappings here
  if (uid == "DE67E056") return "KA09MA1100";
  else if (uid == "E38839DA") return "KA09MA1234";
  else if (uid == "ABCD1234") return "KA09MA6969";

  // Default if UID not found
  return "UNKNOWN";
}
*/

String getVehicleNumber(String uid) {
  return "";  // ESP8266 will NOT set vehicle number
}


void processAndUpload(String data) {
  String type = data.startsWith("ENTRY:") ? "ENTRY" : "EXIT";
  data = data.substring(type.length() + 1);  // remove prefix

  // Split by colons
  int firstColon = data.indexOf(':');
  int secondColon = data.indexOf(':', firstColon + 1);

  if (firstColon == -1 || secondColon == -1) {
    Serial.println("⚠️ Invalid data format! Use ENTRY:UID:AvailableSlots:AssignedSlot");
    return;
  }

  String uid = data.substring(0, firstColon);
  String availableSlots = data.substring(firstColon + 1, secondColon);
  String assignedSlot = data.substring(secondColon + 1);
  String vehicleNo = getVehicleNumber(uid);  // βœ… Auto vehicle lookup

  String url = String(LOG_URL) + "?uid=" + uid + "&type=" + type + "&availableSlots=" + availableSlots + "&assignedSlot=" + assignedSlot + "&vehicleNo=" + vehicleNo;

  WiFiClientSecure client;
  client.setInsecure();

  HTTPClient http;
  http.begin(client, url);
  int httpCode = http.GET();

  if (httpCode == 200) {
    String response = http.getString();
    Serial.println("HTTP Error Code:");
    Serial.println("Response: " + response);
  } else {
    Serial.println("βœ… Data uploaded successfully!:" + String(httpCode));
  }

  http.end();
}

void handleCheckRequest(String data) {
  String uid = data.substring(6);
  uid.trim();

  Serial.println("🌐 Checking online slot for UID: " + uid);

  String url = String(CHECK_URL) + "?action=checkSlot" + "&uid=" + uid;

  WiFiClientSecure client;
  client.setInsecure();

  HTTPClient http;
  http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
  http.addHeader("User-Agent", "ESP8266");

  http.begin(client, url);
  int httpCode = http.GET();

  Serial.println("HTTP Code: " + String(httpCode));

  if (httpCode != 200) {
    Serial.println("❌ Slot check HTTP failed");
    http.end();
    return;
  }

  String response = http.getString();
  http.end();

  Serial.println("πŸ“₯ Server Response:");
  Serial.println(response);

  int bookedIndex = response.indexOf("\"bookedSlot\":");
  int allowedIndex = response.indexOf("\"allowedSlots\":");

  int bookedSlot = 0;
  String freeSlots = "";

  if (bookedIndex >= 0) {
    bookedSlot = response.substring(bookedIndex + 13).toInt();
  }

  if (allowedIndex >= 0) {
    int start = response.indexOf("[", allowedIndex);
    int end = response.indexOf("]", allowedIndex);
    if (start >= 0 && end >= 0) {
      freeSlots = response.substring(start + 1, end);
      freeSlots.replace(" ", "");
    }
  }


  // πŸ”’ BUILD BOOKED-ALL-SLOTS SAFELY
  onlineBookedAll = "";

  for (int i = 1; i <= 20; i++) {
    String token = "," + String(i) + ",";
    String list = "," + freeSlots + ",";

    // if slot NOT found as whole number β†’ booked
    if (list.indexOf(token) == -1) {
      if (onlineBookedAll.length() > 0) onlineBookedAll += ",";
      onlineBookedAll += String(i);
    }
  }

  Serial.println("πŸ” All Booked Slots: " + onlineBookedAll);


  String reply = "ONLINE:MYBOOKED=" + String(bookedSlot) + ":BOOKEDALL=" + onlineBookedAll + ":FREE=" + freeSlots;

  mySerial.println(reply);
  Serial.println("πŸ“€ Sent to Arduino: " + reply);
}
        

3. Google Apps Script Backend

Google Sheets logging, email notifications, parking receipts, payment tracking, and feedback management.

View Google Apps Script


        

Technologies Used

ESP32 ESP RainMaker Google Assistant Arduino IDE Bluetooth Provisioning OTA Updates EEPROM AceButton Wi-Fi Embedded C++