#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ---------- Pin assignments ----------
const int GREEN_LED_PIN = 25; // Gate OPEN indicator
const int RED_LED_PIN = 26; // Gate CLOSED / booth busy indicator
const int BUZZER_PIN = 27; // Short beep when a vehicle finishes
// ---------- LCD setup (address, columns, rows) ----------
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ---------- Time scaling ----------
const unsigned long TIME_UNIT_MS = 1000; // 1 unit = 1 second
// ---------- Vehicle model ----------
struct Vehicle {
String id;
int arrivalTime;
int serviceTime;
int startTime;
int completionTime;
int waitingTime;
int turnaroundTime;
};
// ---------- Sample input data (edit these for your report) ----------
const int NUM_VEHICLES = 5;
Vehicle fleet[NUM_VEHICLES] = {
{"V1", 0, 4, 0, 0, 0, 0},
{"V2", 1, 3, 0, 0, 0, 0},
{"V3", 2, 1, 0, 0, 0, 0},
{"V4", 3, 2, 0, 0, 0, 0},
{"V5", 5, 3, 0, 0, 0, 0}
};
void sortByArrivalTime(Vehicle arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j].arrivalTime > arr[j + 1].arrivalTime) {
Vehicle temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void computeSchedule(Vehicle arr[], int n) {
int currentTime = 0;
for (int i = 0; i < n; i++) {
if (currentTime < arr[i].arrivalTime) {
currentTime = arr[i].arrivalTime;
}
arr[i].startTime = currentTime;
arr[i].completionTime = currentTime + arr[i].serviceTime;
arr[i].waitingTime = arr[i].startTime - arr[i].arrivalTime;
arr[i].turnaroundTime = arr[i].completionTime - arr[i].arrivalTime;
currentTime = arr[i].completionTime;
}
}
void gateOpen() {
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
}
void gateClosed() {
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, HIGH);
}
void beep() {
digitalWrite(BUZZER_PIN, HIGH);
delay(150);
digitalWrite(BUZZER_PIN, LOW);
}
void simulateProcessing(Vehicle arr[], int n) {
for (int i = 0; i < n; i++) {
gateClosed();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Processing ");
lcd.print(arr[i].id);
lcd.setCursor(0, 1);
lcd.print("Wait:");
lcd.print(arr[i].waitingTime);
lcd.print(" Serv:");
lcd.print(arr[i].serviceTime);
Serial.println("----------------------------------------");
Serial.print("Now serving: "); Serial.println(arr[i].id);
Serial.print(" Arrival Time : "); Serial.println(arr[i].arrivalTime);
Serial.print(" Start Time : "); Serial.println(arr[i].startTime);
Serial.print(" Service Time : "); Serial.println(arr[i].serviceTime);
Serial.print(" Completion Time : "); Serial.println(arr[i].completionTime);
Serial.print(" Waiting Time : "); Serial.println(arr[i].waitingTime);
Serial.print(" Turnaround Time : "); Serial.println(arr[i].turnaroundTime);
delay(arr[i].serviceTime * TIME_UNIT_MS);
gateOpen();
beep();
delay(300);
}
}
void printSummary(Vehicle arr[], int n) {
float totalWT = 0, totalTAT = 0;
Serial.println("\n========== FCFS TOLL PLAZA - FINAL REPORT ==========");
Serial.println("ID\tAT\tBT\tST\tCT\tWT\tTAT");
for (int i = 0; i < n; i++) {
Serial.print(arr[i].id); Serial.print("\t");
Serial.print(arr[i].arrivalTime); Serial.print("\t");
Serial.print(arr[i].serviceTime); Serial.print("\t");
Serial.print(arr[i].startTime); Serial.print("\t");
Serial.print(arr[i].completionTime); Serial.print("\t");
Serial.print(arr[i].waitingTime); Serial.print("\t");
Serial.println(arr[i].turnaroundTime);
totalWT += arr[i].waitingTime;
totalTAT += arr[i].turnaroundTime;
}
Serial.print("Average Waiting Time : "); Serial.println(totalWT / n);
Serial.print("Average Turnaround Time : "); Serial.println(totalTAT / n);
Serial.println("=====================================================");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AvgWT:");
lcd.print(totalWT / n);
lcd.setCursor(0, 1);
lcd.print("AvgTAT:");
lcd.print(totalTAT / n);
}
void setup() {
Serial.begin(115200);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Toll Plaza FCFS");
lcd.setCursor(0, 1);
lcd.print("Simulator");
delay(1500);
sortByArrivalTime(fleet, NUM_VEHICLES);
computeSchedule(fleet, NUM_VEHICLES);
Serial.println("Vehicles sorted by arrival time (FCFS order):");
for (int i = 0; i < NUM_VEHICLES; i++) {
Serial.println(fleet[i].id);
}
simulateProcessing(fleet, NUM_VEHICLES);
printSummary(fleet, NUM_VEHICLES);
}
void loop() {
// Nothing repeating - this is a one-shot simulation for the demo video.
}