This shows you the differences between two versions of the page.
iothings:proiecte:2025sric:securitysystem [2025/04/22 20:08] roxana.popa2703 |
iothings:proiecte:2025sric:securitysystem [2025/05/29 01:06] (current) roxana.popa2703 |
||
---|---|---|---|
Line 4: | Line 4: | ||
*Email: roxana.popa2703@stud.acs.upb.ro | *Email: roxana.popa2703@stud.acs.upb.ro | ||
*Master: SRIC | *Master: SRIC | ||
+ | |||
+ | ==== General description ==== | ||
+ | |||
+ | This project proposes a basic password validation security system based on ESP32. It receives the password as input from the user from the keyboard module and validates it against the database entries. If the user is allowed, the green LED will turn on and the buzzer will make a sound indicating the access is permitted. If the access is not permitted, the red LED will turn on and the buzzer will make a distinctive sound. | ||
+ | |||
+ | Every attempt is logged into the database and is accessible to the admin user via the webserver. The admin can also blacklist/whitelist users in the webserver and the changes will be immediately picked up by the controller. The admin can also export all the attempts in a CSV format for further analysis. | ||
+ | |||
+ | ==== Hardware description ==== | ||
+ | |||
+ | For the implementation of this project, the following hardware components were used: | ||
+ | * ESP-WROOM-32 | ||
+ | * 2 x LED (one red, one green) | ||
+ | * 1 x Passive buzzer | ||
+ | * 1 x Breadboard | ||
+ | * 1 x Keyboard module | ||
+ | * Wires | ||
+ | |||
+ | {{:iothings:proiecte:2025sric:hw.png|}} | ||
+ | |||
+ | ==== Software description ==== | ||
+ | |||
+ | The following libraries were used: | ||
+ | ---- | ||
+ | |||
+ | #include <WiFi.h> // to connect ESP32 via WiFi | ||
+ | #include "time.h" // for logs timestamps | ||
+ | #include <Firebase_ESP_Client.h> // to read/write data to Firebase | ||
+ | | ||
+ | The Wi-Fi setup and connection: | ||
+ | WiFi.mode(WIFI_STA); | ||
+ | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); | ||
+ | uint8_t status = WiFi.waitForConnectResult(); | ||
+ | if (status == WL_CONNECTED) { | ||
+ | Serial.println(); | ||
+ | Serial.println("connected (WL_CONNECTED)"); | ||
+ | } | ||
+ | |||
+ | The NTP server sync: | ||
+ | configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); | ||
+ | Serial.print("Waiting for NTP time sync..."); | ||
+ | while (time(nullptr) < 100000) { | ||
+ | delay(500); | ||
+ | Serial.print("."); | ||
+ | } | ||
+ | Serial.println("\nTime synced!"); | ||
+ | | ||
+ | Access logging: | ||
+ | FirebaseJson log; | ||
+ | log.set("password", password); | ||
+ | log.set("status", status); | ||
+ | time_t now; | ||
+ | time(&now); | ||
+ | String timestamp = String(now); | ||
+ | String path = "users/logs/" + timestamp; | ||
+ | if (Firebase.RTDB.setJSON(&data, path, &log)) { | ||
+ | Serial.println("Log sent at " + timestamp); | ||
+ | } else { | ||
+ | Serial.print("Failed to send log: "); | ||
+ | Serial.println(data.errorReason()); | ||
+ | } | ||
+ | |||
+ | The **setup** function: | ||
+ | |||
+ | Serial.begin(115200); | ||
+ | Serial.setTimeout(1000); | ||
+ | pinMode(RED_LED, OUTPUT); | ||
+ | pinMode(GREEN_LED, OUTPUT); | ||
+ | pinMode(BUZZER, OUTPUT); | ||
+ | connectToWiFi(); | ||
+ | initTime(); | ||
+ | // Configure Firebase | ||
+ | config.api_key = API_KEY; | ||
+ | config.database_url = DATABASE_URL; | ||
+ | // Sign in anonymously (or use email/password) | ||
+ | auth.user.email = USER_EMAIL; | ||
+ | auth.user.password = USER_PASSWORD; | ||
+ | // Initialize Firebase | ||
+ | Firebase.begin(&config, &auth); | ||
+ | Firebase.reconnectWiFi(true); | ||
+ | // Delay to ensure connection setup | ||
+ | delay(2000); | ||
+ | | ||
+ | The **loop** function: | ||
+ | if (Serial.available() > 0) { | ||
+ | String password = Serial.readString(); | ||
+ | password.trim(); | ||
+ | Serial.println(password); | ||
+ | if (!Firebase.RTDB.getJSON(&data, listenerPath)) { | ||
+ | Serial.printf("Stream begin error, %s\n", data.errorReason().c_str()); | ||
+ | } | ||
+ | json = data.jsonObject(); | ||
+ | String jsonStr; | ||
+ | json.toString(jsonStr, true); // 'true' = pretty print (multi-line, indented) | ||
+ | Serial.println(jsonStr); | ||
+ | FirebaseJsonData status; | ||
+ | json.get(status, password); | ||
+ | if (!status.success) { | ||
+ | Serial.println("Key 'status' not found!"); | ||
+ | } else { | ||
+ | logAccess(password, status.stringValue); | ||
+ | if(status.stringValue == "allowed"){ | ||
+ | digitalWrite(GREEN_LED, HIGH); | ||
+ | tone(BUZZER, 1000); | ||
+ | delay(200); | ||
+ | digitalWrite(GREEN_LED, LOW); | ||
+ | noTone(BUZZER); | ||
+ | } | ||
+ | else{ | ||
+ | digitalWrite(RED_LED, HIGH); | ||
+ | tone(BUZZER, 400); | ||
+ | delay(200); | ||
+ | digitalWrite(RED_LED, LOW); | ||
+ | noTone(BUZZER); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ |