#include <WiFi.h>
#include <HTTPClient.h>
#include <SPI.h>
#include <MFRC522.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <ESP32Servo.h>
// ============= PIN DEFINITIONS =============
#define SS_PIN 5
#define RST_PIN 26
#define GREEN_LED 2
#define RED_LED 4
#define BUZZER_PIN 15
#define BUTTON_PIN 14
#define SERVO_PIN 13
// ============= GLOBAL OBJECTS =============
MFRC522 rfid(SS_PIN, RST_PIN);
Adafruit_SSD1306 display(128, 64, &Wire, -1);
Servo gateServo;
// WiFi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Timing variables
unsigned long ledOffTime = 0;
unsigned long buzzerOffTime = 0;
unsigned long servoReturnTime = 0;
bool isLedActive = false;
bool isBuzzerActive = false;
bool isServoMoving = false;
unsigned long lastButtonPress = 0;
bool isScanning = false;
// ============= SETUP =============
void setup() {
Serial.begin(115200);
Serial.println("\n\n=== ASTU PC Ownership Detector ===");
// Initialize pins
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
// Initialize OLED
Wire.begin(21, 22);
if(display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("ASTU Security");
display.println("System Ready");
display.display();
Serial.println("OLED OK");
} else {
Serial.println("OLED Failed");
}
// Initialize RFID
SPI.begin(18, 19, 23, 5);
rfid.PCD_Init();
Serial.println("RFID OK");
// Initialize Servo
gateServo.attach(SERVO_PIN);
gateServo.write(0);
Serial.println("Servo OK");
// Connect WiFi
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi Connected!");
display.clearDisplay();
display.setCursor(0, 0);
display.println("ASTU Security");
display.println("WiFi Connected");
display.println("Ready to Scan");
display.display();
} else {
Serial.println("\nWiFi Failed!");
}
Serial.println("System Ready - Press Button to Scan");
}
// ============= DISPLAY FUNCTION =============
void updateDisplay(String line1, String line2, String line3) {
display.clearDisplay();
display.setCursor(0, 0);
display.println("=== ASTU SECURITY ===");
display.println();
display.println(line1);
if (line2.length() > 0) display.println(line2);
if (line3.length() > 0) display.println(line3);
display.display();
}
// ============= LED and BUZZER FUNCTIONS =============
void startLed(int ledPin, int duration) {
digitalWrite(ledPin, HIGH);
if (ledPin == GREEN_LED) digitalWrite(RED_LED, LOW);
else digitalWrite(GREEN_LED, LOW);
ledOffTime = millis() + duration;
isLedActive = true;
}
void updateLed() {
if (isLedActive && millis() >= ledOffTime) {
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
isLedActive = false;
}
}
void startBuzzer(int duration, bool isAlarm = false) {
if (isAlarm) tone(BUZZER_PIN, 2500);
else tone(BUZZER_PIN, 2000);
buzzerOffTime = millis() + duration;
isBuzzerActive = true;
}
void updateBuzzer() {
if (isBuzzerActive && millis() >= buzzerOffTime) {
noTone(BUZZER_PIN);
isBuzzerActive = false;
}
}
// ============= SERVO FUNCTION =============
void moveServoTemporarily(int angle, int delayMs) {
gateServo.write(angle);
servoReturnTime = millis() + delayMs;
isServoMoving = true;
}
void updateServo() {
if (isServoMoving && millis() >= servoReturnTime) {
gateServo.write(0);
isServoMoving = false;
}
}
// ============= RFID SCAN FUNCTION =============
void scanRFID() {
if (!rfid.PICC_IsNewCardPresent()) return;
if (!rfid.PICC_ReadCardSerial()) return;
String uid = "";
for (byte i = 0; i < rfid.uid.size; i++) {
if (rfid.uid.uidByte[i] < 0x10) uid += "0";
uid += String(rfid.uid.uidByte[i], HEX);
}
uid.toUpperCase();
Serial.print("RFID UID: ");
Serial.println(uid);
updateDisplay("RFID Detected", "UID: " + uid, "Verifying...");
// FOR DEMO: Simulate server response
// Remove this section and uncomment HTTP section for real server
simulateServerResponse(uid);
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
// ============= SIMULATED SERVER RESPONSE FOR TESTING =============
void simulateServerResponse(String uid) {
// Demo: Authorize specific UIDs for testing
// In Wokwi, you can set RFID cards to these values
if (uid == "DEADBEEF" || uid == "12345678" || uid == "ASTU1234") {
Serial.println("Authorized User Detected!");
startLed(GREEN_LED, 2000);
startBuzzer(500, false);
moveServoTemporarily(90, 3000);
updateDisplay("AUTHORIZED", "Welcome!", "Access Granted");
} else {
Serial.println("Unauthorized User Detected!");
startLed(RED_LED, 2000);
startBuzzer(2000, true);
updateDisplay("UNAUTHORIZED", "ALERT!", "Access Denied");
}
}
// ============= REAL HTTP FUNCTION (Uncomment to use with real server) =============
/*
void sendToServer(String uid) {
if (WiFi.status() != WL_CONNECTED) {
updateDisplay("Network Error", "No WiFi", "");
return;
}
HTTPClient http;
http.begin("http://host.docker.internal:5000/api/verify");
http.addHeader("Content-Type", "application/json");
String payload = "{\"rfid_uid\":\"" + uid + "\",\"device\":\"laptop\",\"location\":\"ASTU_GATE\"}";
int httpCode = http.POST(payload);
if (httpCode > 0) {
String response = http.getString();
Serial.println(response);
if (response.indexOf("authorized") > 0 && response.indexOf("true") > 0) {
startLed(GREEN_LED, 2000);
startBuzzer(500, false);
moveServoTemporarily(90, 3000);
updateDisplay("AUTHORIZED", "Access Granted", "");
} else {
startLed(RED_LED, 2000);
startBuzzer(2000, true);
updateDisplay("UNAUTHORIZED", "Access Denied", "");
}
}
http.end();
}
*/
// ============= MAIN LOOP =============
void loop() {
updateLed();
updateBuzzer();
updateServo();
// Check button press
if (digitalRead(BUTTON_PIN) == LOW && !isScanning) {
if (millis() - lastButtonPress > 200) {
lastButtonPress = millis();
isScanning = true;
Serial.println("\nButton Pressed - Scanning...");
updateDisplay("Scanning RFID", "Place tag near", "reader...");
// Scan for 5 seconds
unsigned long startTime = millis();
bool found = false;
while (millis() - startTime < 5000) {
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
found = true;
break;
}
updateLed();
updateBuzzer();
updateServo();
delay(10);
}
if (found) {
scanRFID();
} else {
Serial.println("No RFID Tag Found");
updateDisplay("Timeout", "No Tag Found", "Press Button Again");
startBuzzer(300, false);
}
isScanning = false;
}
}
delay(10);
}