#include <ESP32Servo.h>
#include <WiFi.h>
#include "time.h"
//Конфігурація апаратної частини (Піни)
#define PIN_SERVO 18
#define PIN_LED_GREEN 14
#define PIN_LED_RED 12
#define PIN_BUZZER 27
// Мережеві налаштування та параметри NTP
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 7200; // Таймзона Київ (GMT+2)
const int daylightOffset_sec = 3600; // Врахування літнього часу
//Ініціалізація об'єкта сервоприводу
Servo myServo;
//Модель даних користувача
struct User {
String uid;
String name;
String role; //Доступні ролі: "ADMIN", "DOCTOR", "GUEST"
};
//Локальна база даних системи контролю доступу
User database[] = {
{"5252", "romchik", "BOSS"},
{"1616", "rostik", "KENT"},
{"6767", "nikitka", "PESHKA"}
};
int dbSize = 3;
//ДОПОМІЖНІ ФУНКЦІЇ ТА ЛОГІКА СИСТЕМИ
//Запит та форматування поточного часу з NTP
String getLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "Time Error";
}
char timeStringBuff[50];
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
return String(timeStringBuff);
}
//Процедура успішного підтвердження доступу
void grantAccess(String name, String role, String time) {
Serial.println("--------------------------------");
Serial.println("[ACCESS GRANTED]");
Serial.printf("Time: %s\n", time.c_str());
Serial.printf("User: %s (%s)\n", name.c_str(), role.c_str());
digitalWrite(PIN_LED_GREEN, HIGH);
myServo.write(90); //Відмикання замка
delay(3000); //Пауза у відкритому стані
myServo.write(0); //Замикання замка
digitalWrite(PIN_LED_GREEN, LOW);
}
//Процедура відмови у доступі та активація тривоги
void denyAccess(String id, String reason, String time) {
Serial.println("--------------------------------");
Serial.println("[ACCESS DENIED - SECURITY ALERT]");
Serial.printf("Time: %s\n", time.c_str());
Serial.printf("ID/Name: %s\n", id.c_str());
Serial.printf("Reason: %s\n", reason.c_str());
digitalWrite(PIN_LED_RED, HIGH);
//Генерація двотонального сигналу тривоги
tone(PIN_BUZZER, 1000); delay(500); noTone(PIN_BUZZER); delay(200);
tone(PIN_BUZZER, 1000); delay(500); noTone(PIN_BUZZER);
digitalWrite(PIN_LED_RED, LOW);
Serial.println(">> LOG SENT TO CLOUD SERVER");
}
//Перевірка прав доступу за зчитаним UID
void handleAccess(String uid) {
int userIndex = -1;
//Лінійний пошук ідентифікатора в базі
for (int i = 0; i < dbSize; i++) {
if (database[i].uid == uid) {
userIndex = i;
break;
}
}
String timestamp = getLocalTime();
//Обробка результату авторизації
if (userIndex == -1) {
denyAccess(uid, "UNKNOWN_USER", timestamp);
} else if (database[userIndex].role == "GUEST") {
denyAccess(database[userIndex].name, "RESTRICTED_ROLE", timestamp);
} else {
grantAccess(database[userIndex].name, database[userIndex].role, timestamp);
}
}
//ОСНОВНІ ФУНКЦІЇ ARDUINO
void setup() {
Serial.begin(115200);
//Конфігурація режимів роботи пінів периферії
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_BUZZER, OUTPUT);
myServo.attach(PIN_SERVO);
myServo.write(0); //Вихідний стан замка — закрито
//Ініціалізація бездротового підключення
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//Запуск синхронізації часу через мережу
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.println("System Ready. Scan Card (Type ID in Serial)...");
}
void loop() {
//Моніторинг та зчитування даних з Serial інтерфейсу
if (Serial.available() > 0) {
String inputID = Serial.readStringUntil('\n');
inputID.trim(); //Очищення від символів переносу рядка та пробілів
if (inputID.length() > 0) {
handleAccess(inputID);
}
}
delay(100); //Стабілізаційний таймаут циклу
}