#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL2jBGxfz2c"
#define BLYNK_TEMPLATE_NAME "hospital ward access control"
#define BLYNK_AUTH_TOKEN "Qr8R4g7B8HPqaEK21eb9l6KhzLYNXhUM"
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
#include <DFRobotDFPlayerMini.h>
#include <BlynkSimpleEsp32.h>
#include <WiFi.h>
#include <WiFiClient.h>
#define SS 5
#define RST 14
#define rled 26
#define bled 25
#define BUTTON_PIN 4
#define servoPin 13
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 3*3600
#define UTC_OFFSET_DST 0
#define buzzer 15
#define movePin 27
struct Student {
String tag; // RFID tag (UID as string)
String name; // Full name
bool inside; // false = outside, true = inside the bus
};
Student students[10] = {
{"A1B2C3D4", "Alice Johnson", false},
{"B2C3D4E5", "Brian Smith", false},
{"C3D4E5F6", "Carla Mendes", false},
{"D4E5F6G7", "David Kim", false},
{"E5F6G7H8", "Emily White", false},
{"F6G7H8I9", "Frank Lee", false},
{"G7H8I9J0", "Grace Chen", false},
{"H8I9J0K1", "Henry Black", false},
{"I9J0K1L2", "Ivy Brown", false},
{"J0K1L2M3", "Jacob Green", false}
};
float latitude,longitude,speed;
bool isMoving;
LiquidCrystal_I2C lcd(0x27, 20, 4);
MFRC522 scanner(SS,RST);
DFRobotDFPlayerMini myDFPlayer;
Servo myServo;
void setup() {
Serial.begin(9600);
delay(500);
Serial.println("initializing");
pinMode(rled, OUTPUT);
pinMode(bled, OUTPUT);
pinMode(buzzer, OUTPUT);
pinMode(movePin,INPUT);
pinMode(32,INPUT_PULLDOWN);
lcd.init();
lcd.backlight();
loadingdisplay();
clearLine(3);
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("Connecting WiFi....");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
spinner();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("WiFi connected");
delay(2000);
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("Updating time...");
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("Time Updated");
delay(2000);
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("Initialize voice...");
Serial2.begin(9600);
clearLine(3);
lcd.setCursor(0, 3);
lcd.print("Voice Initialized");
delay(2000);
Blynk.begin(auth, ssid, pass);
myServo.attach(servoPin);
myServo.write(0);
Serial.println("Type RFID Tag ID to scan a product...");
lcd.clear();
}
void loop()
{
isMoving=digitalRead(movePin);
homedisplay();
while(digitalRead(movePin)==LOW)
{
allowScan();
}
if(digitalRead(32))
{
handDetected();
}
}
void allowScan()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCAN FOR DOOR ACCESS");
lcd.setCursor(0, 3);
lcd.print(" TO GET IN OR OUT ");
if (Serial.available()) {
String inputTag = Serial.readStringUntil('\n');
inputTag.trim();
bool found = false;
for (int i = 0; i < 10; i++) {
if (students[i].tag == inputTag) {
found = true;
Serial.println("Card found: " + students[i].name);
Serial.println("Opening door....");
grantAlert(i);
delay(3000);
grant();
break;
}
}
if (!found) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("UNKNOW/UNREGISTERED");
lcd.setCursor(0, 1);
lcd.print(" STUDENT ID CARD ");
lcd.setCursor(0, 2);
lcd.print("CONTACT SCHOOL");
lcd.setCursor(0, 3);
lcd.print(" FOR PROBLEM DETAIL ");
Serial.println("Tag not recognized!");
delay(2000);
}
}delay(500);
}
void loadingdisplay()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("*SUCURE ACCESS FOR *");
lcd.setCursor(0,1);
lcd.print("* SMART SHOOL BUS *");
lcd.setCursor(0,2);
lcd.print(" SYSTEM INITIALIZE ");
lcd.setCursor(0,3);
lcd.print("PLEASE WAIT");
for(int k=11;k<20;k++)
{
lcd.setCursor(k,3);
lcd.print(".");
delay(200);
}
}
void homedisplay()
{
lcd.setCursor(0,0);
lcd.print("*SUCURE ACCESS FOR *");
lcd.setCursor(0,1);
lcd.print("* SMART SCHOOL BUS *");
lcd.setCursor(0,2);
if(!isMoving)
{
lcd.print("ARRIVED AT STATION");
}
else
{
lcd.print(" BUS IN MOTION ");
}
}
void alert_display(String textAlert)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" -EMERGENCY ALERT- ");
lcd.setCursor(0,1);
lcd.print("********************");
lcd.setCursor(0,2);
lcd.print("*");
lcd.setCursor(1,2);
lcd.print(textAlert);
lcd.setCursor(19,2);
lcd.print("*");
lcd.setCursor(0,3);
lcd.print("********************");
//myDFPlayer.play(2);
}
void Alert(uint8_t num)
{
for(uint8_t q=0;q<num;q++){
digitalWrite(buzzer, HIGH);
digitalWrite(rled, HIGH);
tone(buzzer, 100);
delay(1000);
digitalWrite(buzzer, LOW);
digitalWrite(rled, LOW);
noTone(buzzer);
delay(1000);}
}
void clearLine(uint8_t lineNum)
{
for(uint8_t i=0;i<20;i++)
{
lcd.setCursor(i,lineNum);
lcd.print(" ");
}
}
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
lcd.setCursor(0, 3);
lcd.print("Connection Err");
return;
}
lcd.setCursor(0,3);
lcd.print(&timeinfo, "%H:%M:%S %d/%m/%Y");
}
void spinner()
{
static int8_t counter = 0;
const char* glyphs = "\xa1\xa5\xdb";
lcd.setCursor(19, 3);
lcd.print(glyphs[counter++]);
if (counter == strlen(glyphs)) {
counter = 0;
}
}
void grant()
{
myServo.write(180);
delay(3000);
myServo.write(90);
}
void grantAlert(int p)
{
lcd.setCursor(0,0);
lcd.print("Hi! "+students[p].name);
lcd.setCursor(0,1);
lcd.print(" YOU ARE WELCOME ");
lcd.setCursor(0,2);
if(!students[p].inside){lcd.print("PLEASE! GET INSIDE"); }
else{ lcd.print("PLEASE! DISEMBARK "); }
lcd.setCursor(0,3);
lcd.print("--------------------");
}
void denyAlert()
{
lcd.setCursor(0,0);
lcd.print("--------------------");
lcd.setCursor(0,1);
lcd.print("| SORRY! YOUR CARD |");
lcd.setCursor(0,2);
lcd.print("|HAS BEEN REJECTED |");
lcd.setCursor(0,3);
lcd.print("--------------------");
}
void handDetected()
{
lcd.setCursor(0,0);
lcd.print("--------------------");
lcd.setCursor(0,1);
lcd.print("| HAND DETECTED OUT |");
lcd.setCursor(0,2);
lcd.print("| THE SIDE WINDOW |");
lcd.setCursor(0,3);
lcd.print("--------------------");
Alert(4);
}
HAND SENSOR
MOTION SENSOR