#define BLYNK_TEMPLATE_ID "TMPL5e-GHNXus"
#define BLYNK_TEMPLATE_NAME "parking"
#define BLYNK_AUTH_TOKEN "QmyPiNOjz-2TXNS9xBlNnAvofz0IDpqu"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>
#include <Ultrasonic.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
// WiFi credentials
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// NTP server details
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 3600;
// Ultrasonic sensor pins
#define TRIG_PIN_1 4
#define ECHO_PIN_1 5
#define TRIG_PIN_2 25
#define ECHO_PIN_2 34
// Servo motor pins
#define ENTRY_SERVO_PIN 14
#define EXIT_SERVO_PIN 2
// RGB LED pins
#define R_LIGHT 12
#define G_LIGHT 13
#define B_LIGHT 27
// Buzzer pin
#define BUZZER_PIN 15
// PIR sensor pin
#define PIR_PIN 35
// Keypad configuration
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {16, 17, 18, 19};
byte colPins[COLS] = {32, 33, 23, 26};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Ultrasonic ultrasonic1(TRIG_PIN_1, ECHO_PIN_1);
Ultrasonic ultrasonic2(TRIG_PIN_2, ECHO_PIN_2);
// Add more ultrasonic sensor objects as needed
Servo entryServo;
Servo exitServo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
String enteredPIN = "";
String currentPIN = "";
String previousPIN = "";
int freeSpace = 0;
void setup() {
Serial.begin(115200);
// Setup Blynk
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// Setup servo motors
entryServo.attach(ENTRY_SERVO_PIN);
exitServo.attach(EXIT_SERVO_PIN);
entryServo.write(0); // Barrier down
exitServo.write(0); // Barrier down
// Setup ultrasonic sensors
pinMode(TRIG_PIN_1, OUTPUT);
pinMode(ECHO_PIN_1, INPUT);
pinMode(TRIG_PIN_2, OUTPUT);
pinMode(ECHO_PIN_2, INPUT);
// Setup LCD
lcd.init();
lcd.backlight();
// Setup buzzer
pinMode(BUZZER_PIN, OUTPUT);
// Setup RGB LED
pinMode(R_LIGHT, OUTPUT);
pinMode(G_LIGHT, OUTPUT);
pinMode(B_LIGHT, OUTPUT);
// Setup PIR sensor
pinMode(PIR_PIN, INPUT);
lcd.print("Ticket Parking");
setRGBColor(0, 0, 255);
tone(BUZZER_PIN, 200);
delay(1500); // Delay for cars to leave
lcd.clear();
noTone(BUZZER_PIN);
// Initialize NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
void loop() {
Blynk.run();
// Check parking spaces
freeSpace = checkParkingSpaces();
if (freeSpace != 0) {
lcd.setCursor(0, 0);
lcd.print("Space: ");
lcd.print(freeSpace);
lcd.print(" FREE");
setRGBColor(0, 255, 0); // Green
noTone(BUZZER_PIN); // Turn off buzzer
} else {
lcd.setCursor(0, 0);
lcd.print("NO SPACE");
setRGBColor(255, 0, 0); // Red
tone(BUZZER_PIN, 200); // Turn on buzzer
}
// Entry logic based on PIR sensor
if (digitalRead(PIR_PIN) == HIGH) {
handleEntry();
}
// Keypad handling for exit
char key = keypad.getKey();
if (key) {
if (key == '#') {
checkPIN();
} else {
enteredPIN += key;
lcd.setCursor(0, 1);
lcd.print("PIN: ");
lcd.print(enteredPIN);
}
}
}
int checkParkingSpaces() {
// Check each ultrasonic sensor to find a free space
int space = 0;
if (ultrasonic1.read(CM) > 50) {
space += 1;
}
if (ultrasonic2.read(CM) > 50) {
space += 1;
}
// Add more checks for additional sensors
Blynk.virtualWrite(V1, space);
return space; // No free space
}
void handleEntry() {
if (freeSpace == 0) {
lcd.setCursor(0, 1);
lcd.print("NO SPACE");
setRGBColor(255, 0, 0); // Red
tone(BUZZER_PIN, 200); // Turn on buzzer
delay(2000);
lcd.clear();
return;
}
if (currentPIN == "") {
// Entry Logic
currentPIN = generatePIN();
Blynk.virtualWrite(V0, currentPIN); // Send the new PIN to Blynk
entryServo.write(70); // Lift entry barrier
setRGBColor(0, 0, 255); // Blue
lcd.setCursor(0, 1);
lcd.print("PIN: ");
lcd.print(currentPIN);
delay(3000);
entryServo.write(90); // Lower entry barrier
Blynk.virtualWrite(V2, "Entry Time: " + getTime()); // Log entry time to Blynk
lcd.clear();
}
}
void checkPIN() {
if (enteredPIN == currentPIN) {
// Exit Logic
exitServo.write(0); // Lift exit barrier
setRGBColor(0, 0, 255); // Blue
delay(3000);
exitServo.write(90); // Lower exit barrier
Blynk.virtualWrite(V3, "Exit Time: " + getTime()); // Log exit time to Blynk
// Clear the current PIN for next use
currentPIN = "";
} else {
lcd.setCursor(0, 1);
lcd.print("WRONG PIN ");
setRGBColor(255, 165, 0); // Orange
delay(2000);
}
enteredPIN = "";
lcd.clear();
}
String generatePIN() {
// Generate a 4-digit unique PIN
String pin = "";
for (int i = 0; i < 4; i++) {
pin += String(random(0, 10));
}
previousPIN = currentPIN;
return pin;
}
String getTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "Failed to obtain time";
}
char buffer[20];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M", &timeinfo);
return String(buffer);
}
void setRGBColor(int red, int green, int blue) {
analogWrite(R_LIGHT, red);
analogWrite(G_LIGHT, green);
analogWrite(B_LIGHT, blue);
}