#include <Wire.
h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// Initialize the LCD (I2C address 0x27, 16 columns, 2 rows)
LiquidCrystal_I2C lcd(0x27, 16, 4);
const int trigPin1 = 7, echoPin1 = 6;
const int trigPin2 = 5, echoPin2 = 4;
const int trigPin3 = 3, echoPin3 = 2;
const int ledRed1 = 29, ledYellow1 = 31, ledGreen1 = 33;
const int ledRed2 = 35, ledYellow2 = 37, ledGreen2 = 39;
const int ledRed3 = 41, ledYellow3 = 43, ledGreen3 = 45;
bool isReserved1 = false, isReserved2 = false, isReserved3 = false;
int lastStatus1 = -1, lastStatus2 = -1, lastStatus3 = -1; // To track previous
status
//This is for the gate
const int trigPin4 = 8;
const int echoPin4 = 9;
const int gateControlServoPin = 10;
Servo gateControlServo;
String gateStatus = "Unknown";
void setup() {
[Link](9600); // For serial communication with Serial Monitor (PC)
[Link](9600); // For serial communication with NodeMCU via Serial2
(GPIO1 and GPIO3)
[Link]();
[Link]();
[Link](0, 0);
[Link]("Parking System");
delay(2000);
[Link]();
pinMode(trigPin1, OUTPUT); pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT); pinMode(echoPin2, INPUT);
pinMode(trigPin3, OUTPUT); pinMode(echoPin3, INPUT);
pinMode(ledRed1, OUTPUT); pinMode(ledYellow1, OUTPUT); pinMode(ledGreen1,
OUTPUT);
pinMode(ledRed2, OUTPUT); pinMode(ledYellow2, OUTPUT); pinMode(ledGreen2,
OUTPUT);
pinMode(ledRed3, OUTPUT); pinMode(ledYellow3, OUTPUT); pinMode(ledGreen3,
OUTPUT);
pinMode(trigPin4, OUTPUT);
pinMode(echoPin4, INPUT);
[Link](gateControlServoPin);
[Link](90); // Initial position
[Link]("System Initialized!");
}
void loop() {
handleSerialInput();
controlEntranceGate(trigPin4, echoPin4, gateControlServo);
String slotStatus1 = getSlotStatus(1, trigPin1, echoPin1, ledRed1, ledYellow1,
ledGreen1, isReserved1, lastStatus1);
String slotStatus2 = getSlotStatus(2, trigPin2, echoPin2, ledRed2, ledYellow2,
ledGreen2, isReserved2, lastStatus2);
String slotStatus3 = getSlotStatus(3, trigPin3, echoPin3, ledRed3, ledYellow3,
ledGreen3, isReserved3, lastStatus3);
updateLCD(slotStatus1, slotStatus2, slotStatus3);
delay(1000);
}
void controlEntranceGate(int trig, int echo, Servo &servo) {
// Trigger ultrasonic pulse
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
// Read echo pulse
long duration = pulseIn(echo, HIGH, 30000); // Timeout at 30 ms
if (duration == 0) {
[Link]("Entrance: Sensor error");
gateStatus = "Sensor error";
return;
}
// Calculate distance in cm
int distance = duration * 0.034 / 2;
// Gate control logic
if (distance <= 15) {
[Link](0); // Close gate
[Link]("Entrance: Object Detected - Gate Closed");
gateStatus = "Gate: Closed";
} else {
[Link](90); // Open gate
[Link]("Entrance: Clear - Gate Open");
gateStatus = "Gate: Open";
}
}
String getSlotStatus(int slot, int trig, int echo, int ledRed, int ledYellow, int
ledGreen, bool &isReserved, int &lastStatus) {
int distance = getDistance(trig, echo);
int currentStatus = (distance > 0 && distance <= 10) ? 1 : 0;
// If the slot is reserved and now occupied, auto-cancel the reservation
if (isReserved && currentStatus == 1) {
isReserved = false;
[Link]("Slot ");
[Link](slot);
[Link](" reservation used - now cleared.");
}
if (isReserved) {
digitalWrite(ledYellow, HIGH);
digitalWrite(ledRed, LOW);
digitalWrite(ledGreen, LOW);
return "Slot " + String(slot) + ": Reserved";
}
// Status logic (only updates if changed)
if (currentStatus != lastStatus) {
lastStatus = currentStatus;
if (currentStatus == 1) {
digitalWrite(ledRed, HIGH);
digitalWrite(ledYellow, LOW);
digitalWrite(ledGreen, LOW);
sendStatusToNodeMCU(slot, 1);
} else {
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, LOW);
digitalWrite(ledGreen, HIGH);
sendStatusToNodeMCU(slot, 0);
}
}
return "Slot " + String(slot) + (currentStatus == 1 ? ": Occupied" : ":
Available");
}
void updateLCD(String status1, String status2, String status3) {
[Link]();
[Link](0, 0);
[Link](status1);
[Link](0, 1);
[Link](status2);
[Link](0, 2);
[Link](status3);
[Link](0, 3); [Link](gateStatus);
}
int getDistance(int trig, int echo) {
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
long duration = pulseIn(echo, HIGH, 30000);
return (duration == 0) ? -1 : duration * 0.034 / 2;
}
void handleSerialInput() {
if ([Link]() > 0) {
String message = [Link]();
[Link]();
[Link](); // Make sure to handle case insensitivity.
[Link]("Received from NodeMCU: ");
[Link](message);
// Handling slot reservations based on the message received from NodeMCU
if (message == "SLOT SLOT 1 RESERVED") {
isReserved1 = true;
[Link]("Slot 1 RESERVED");
} else if (message == "SLOT 1 CANCELLED") {
isReserved1 = false;
[Link]("Slot 1 Reservation CANCELED");
}
if (message == "SLOT SLOT 2 RESERVED") {
isReserved2 = true;
[Link]("Slot 2 RESERVED");
} else if (message == "SLOT 2 CANCELLED") {
isReserved2 = false;
[Link]("Slot 2 Reservation CANCELED");
}
if (message == "SLOT SLOT 3 RESERVED") {
isReserved3 = true;
[Link]("Slot 3 RESERVED");
} else if (message == "SLOT 3 CANCELLED") {
isReserved3 = false;
[Link]("Slot 3 Reservation CANCELED");
}
}
}
void sendStatusToNodeMCU(int slot, int status) {
String message = "SLOT " + String(slot) + " STATUS " + String(status);
[Link](message); // Send the message to NodeMCU
[Link]("Sending status to NodeMCU: ");
[Link](message); // Log the status being sent to NodeMCU
}