#include #include #include #include #include #include // ================= WIFI ================= #define WIFI_SSID "ivann" #define WIFI_PASSWORD "12345678" // ================= FIREBASE ================= #define DATABASE_URL "https://doorguard-7fe8c-default-rtdb.firebaseio.com/" #define DATABASE_SECRET "wKeZFSXj8cyroV5xnjkMIsefRgSvklLI9dgnnQJW" // ================= RFID ================= #define SS_PIN 5 #define RST_PIN 4 #define SCK_PIN 18 #define MISO_PIN 19 #define MOSI_PIN 23 // ================= RELAY ================= #define RELAY_PIN 26 // ================= DOOR SENSOR ================= #define DOOR_SENSOR_PIN 27 // ================= EXIT ================= #define EXIT_BUTTON_PIN 32 // ================= LCD ================= #define SDA_LCD 21 #define SCL_LCD 22 // ================= OBJECT ================= MFRC522 rfid(SS_PIN, RST_PIN); LiquidCrystal_I2C lcd(0x27, 16, 2); FirebaseData fbdo; FirebaseAuth auth; FirebaseConfig config; // ================= VARIABLE ================= String uidString = ""; String userName = ""; String lastDoorCommand = "CLOSE"; bool autoCloseActive = false; unsigned long doorTimer = 0; unsigned long lastScanTime = 0; unsigned long lastButtonTime = 0; bool lastDoorState = false; // ================= SETUP ================= void setup() { Serial.begin(115200); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, HIGH); pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); pinMode(EXIT_BUTTON_PIN, INPUT_PULLUP); // LCD Initialization Wire.begin(SDA_LCD, SCL_LCD); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print("SMART DOOR LOCK"); lcd.setCursor(0,1); lcd.print("STARTING..."); delay(2000); // RFID Initialization SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, SS_PIN); rfid.PCD_Init(); // WIFI Connection WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting WiFi"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println("\nWiFi Connected"); // FIREBASE Configuration config.database_url = DATABASE_URL; config.signer.tokens.legacy_token = DATABASE_SECRET; Firebase.begin(&config, &auth); Firebase.reconnectWiFi(true); Serial.println("Firebase Connected"); // Reset State Awal Firebase.RTDB.setString(&fbdo, "/rfid/doorControl", "CLOSE"); Firebase.RTDB.setString(&fbdo, "/rfid/status", "IDLE"); Firebase.RTDB.setString(&fbdo, "/rfid/lastScan", "IDLE"); } // ================= LOOP ================= void loop() { handleRemoteControl(); handleRFID(); handleExitButton(); handleDoorSensor(); handleAutoClose(); } // ================= REMOTE CONTROL ================= void handleRemoteControl() { if (Firebase.RTDB.getString(&fbdo, "/rfid/doorControl")) { String cmd = fbdo.stringData(); if (cmd != lastDoorCommand) { lastDoorCommand = cmd; if (cmd == "OPEN") { lcd.clear(); lcd.setCursor(0,0); lcd.print("DOOR OPENED"); lcd.setCursor(0,1); lcd.print("FROM APP"); openDoor(false); Firebase.RTDB.setString(&fbdo, "/rfid/status", "DOOR OPENED FROM APP"); } else if (cmd == "CLOSE") { lcd.clear(); lcd.setCursor(0,0); lcd.print("DOOR CLOSED"); lcd.setCursor(0,1); lcd.print("FROM APP"); closeDoor(); Firebase.RTDB.setString(&fbdo, "/rfid/status", "DOOR CLOSED FROM APP"); } delay(2000); } } } // ================= HANDLE RFID ================= void handleRFID() { if (millis() - lastScanTime < 1000) return; if (!rfid.PICC_IsNewCardPresent()) return; if (!rfid.PICC_ReadCardSerial()) return; uidString = ""; for (byte i = 0; i < rfid.uid.size; i++) { if (rfid.uid.uidByte[i] < 0x10) uidString += "0"; uidString += String(rfid.uid.uidByte[i], HEX); } uidString.toLowerCase(); Serial.print("UID Detected: "); Serial.println(uidString); lcd.clear(); lcd.setCursor(0,0); lcd.print("SCANNING CARD..."); lcd.setCursor(0,1); lcd.print(uidString); bool access = false; if (Firebase.RTDB.getBool(&fbdo, "/rfid/cards/" + uidString + "/active")) { if (fbdo.boolData()) access = true; } if (access) { if (Firebase.RTDB.getString(&fbdo, "/rfid/cards/" + uidString + "/name")) { userName = fbdo.stringData(); } else { userName = "User"; } } if (access) { lcd.clear(); lcd.setCursor(0,0); lcd.print("ACCESS GRANTED"); lcd.setCursor(0,1); String displayWelcome = "WELCOME " + userName; displayWelcome.toUpperCase(); lcd.print(displayWelcome); Firebase.RTDB.setString(&fbdo, "/rfid/lastScan", uidString); Firebase.RTDB.setString(&fbdo, "/rfid/status", "ACCESS_GRANTED"); Firebase.RTDB.setString(&fbdo, "/rfid/lastUser", userName); openDoor(true); } else { lcd.clear(); lcd.setCursor(0,0); lcd.print("ACCESS DENIED"); lcd.setCursor(0,1); lcd.print("UNKNOWN CARD"); Firebase.RTDB.setString(&fbdo, "/rfid/lastScan", uidString); Firebase.RTDB.setString(&fbdo, "/rfid/status", "ACCESS_DENIED"); Firebase.RTDB.setString(&fbdo, "/rfid/notification", "ACCESS_DENIED"); } delay(3500); lastScanTime = millis(); rfid.PICC_HaltA(); rfid.PCD_StopCrypto1(); } // ================= HANDLE EXIT BUTTON ================= void handleExitButton() { if (digitalRead(EXIT_BUTTON_PIN) == LOW && (millis() - lastButtonTime > 1000)) { lcd.clear(); lcd.setCursor(0,0); lcd.print("ACCESS GRANTED"); lcd.setCursor(0,1); lcd.print("EXIT"); Firebase.RTDB.setString(&fbdo, "/rfid/status", "OPENED FROM INSIDE"); openDoor(true); delay(1500); lastButtonTime = millis(); } } // ================= OPEN DOOR ================= void openDoor(bool autoClose) { digitalWrite(RELAY_PIN, LOW); Firebase.RTDB.setString(&fbdo, "/rfid/relay", "ON"); delay(300); rfid.PCD_Init(); if (autoClose) { autoCloseActive = true; doorTimer = millis(); } } // ================= CLOSE DOOR ================= void closeDoor() { digitalWrite(RELAY_PIN, HIGH); Firebase.RTDB.setString(&fbdo, "/rfid/relay", "OFF"); autoCloseActive = false; delay(300); rfid.PCD_Init(); } // ================= AUTO CLOSE ================= void handleAutoClose() { if (autoCloseActive && (millis() - doorTimer >= 3000)) { closeDoor(); } } // ================= DOOR SENSOR ================= void handleDoorSensor() { bool doorOpen = digitalRead(DOOR_SENSOR_PIN); if (doorOpen != lastDoorState) { lastDoorState = doorOpen; lcd.clear(); if (doorOpen) { lcd.setCursor(0,0); lcd.print("STATUS:"); lcd.setCursor(0,1); lcd.print("DOOR OPEN"); Firebase.RTDB.setString(&fbdo, "/rfid/doorSensor", "OPEN"); } else { lcd.setCursor(0,0); lcd.print("STATUS:"); lcd.setCursor(0,1); lcd.print("DOOR CLOSED"); Firebase.RTDB.setString(&fbdo, "/rfid/doorSensor", "CLOSED"); } } }