#include <Arduino.h>
#include <WiFi.h>
#include <Preferences.h>
#include <WebServer.h>
#include <Keypad.h>
// Доступ к точке доступа Wi-Fi
const char* ssid = "ESP32-Config";
const char* password = "";
IPAddress localIP(192, 168, 4, 1); // IP-адрес нашей сети
IPAddress gateway(192, 168, 4, 1); // Gateway совпадает с нашим IP
IPAddress subnet(255, 255, 255, 0); // Маска подсети
// Настройки сервера
WebServer server(80); // Веб-сервер на порте 80
// Настройки клавиатуры
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte colPins[COLS] = {4, 5, 6, 7}; // Колонки клавиатуры
byte rowPins[ROWS] = {0, 1, 2, 3}; // Строки клавиатуры
// Пины периферии
const int LED1 = 8; // Зелёный светодиод (успешный ввод)
const int LED2 = 9; // Красный светодиод (тревога)
const int BUZZER = 10; // Пищалка
const int SOLENOID = 18;// Замок (соленоид)
// Ключевые константы
#define PASSWORD_LENGTH 4
#define PASSWORD_COUNT 15
#define BOSS_START_INDEX 10
// Система Preferences
Preferences preferences;
// Глобальные переменные
bool isBossCode = false;
char enteredPassword[PASSWORD_LENGTH+1]; // Пользовательский пароль
int passwordIndex = 0; // Индекс ввода символов
// Клавиатура
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Вспомогательные функции
void blinkLED(int ledPin, int duration) {
digitalWrite(ledPin, HIGH);
delay(duration);
digitalWrite(ledPin, LOW);
}
void beep(int times) {
for (int i=0; i<times; i++) {
tone(BUZZER, 1000, 200); // Звук
delay(300); // Пауза
}
}
void alarm() {
Serial.println("Error: Incorrect Password!");
for (int i=0; i<5; i++) {
digitalWrite(LED2, HIGH);
tone(BUZZER, 2000, 100); // Тревожный звук
delay(200);
digitalWrite(LED2, LOW);
delay(200);
}
}
// Создание страницы конфигурации
void handleRoot() {
String htmlPage =
"<html><head>"
"<title>ESP32 Lock Configuration</title></head>"
"<body style='background-color:#fafafa;'><h1>Change Password:</h1>"
"<form action='/change-password' method='POST'>"
"<input type='text' name='new_password' placeholder='Enter new password' required /><br/><br/>"
"<button type='submit'>Submit</button>"
"</form></body></html>";
server.send(200, "text/html", htmlPage);
}
// Обработчик формы отправки нового пароля
void handleChangePassword() {
if(server.hasArg("new_password")) {
String newPassword = server.arg("new_password");
if(newPassword.length() > 0 && newPassword.length() <= PASSWORD_LENGTH) {
preferences.begin("lock_system", false);
preferences.putString("current_password", newPassword.c_str()); // Записываем новый пароль
preferences.end();
server.send(200, "text/plain", "Password changed successfully!");
} else {
server.send(400, "text/plain", "Invalid password length.");
}
} else {
server.send(400, "text/plain", "No password received.");
}
}
// Инициализация сетевых компонентов
void initWifi() {
WiFi.softAP(ssid, password); // Создаем точку доступа
WiFi.softAPConfig(localIP, gateway, subnet); // Конфигурируем сеть
server.on("/", handleRoot); // Главная страница
server.on("/change-password", handleChangePassword); // Обработчик POST запроса
server.begin(); // Запускаем сервер
Serial.println("HTTP Server started at http://192.168.4.1");
}
// Открытие замка
void openLock() {
Serial.println("Unlocking...");
digitalWrite(SOLENOID, HIGH); // Открываем замок
delay(1000); // Держим открытым одну секунду
digitalWrite(SOLENOID, LOW); // Закрываем замок обратно
if (isBossCode) {
beep(3); // Сигнал для boss-кода
} else {
blinkLED(LED1, 200); // Моргаем зеленым светодиодом
}
}
// Проверка пароля
void checkPassword() {
preferences.begin("lock_system", false); // Читаем настройки
String currentPassword = preferences.getString("current_password"); // Текущий пароль
preferences.end();
if(currentPassword.equals(enteredPassword)) {
openLock();
} else {
alarm();
}
// Сбрасываем буфер ввода
passwordIndex = 0;
memset(enteredPassword, 0, sizeof(enteredPassword));
}
void setup() {
Serial.begin(115200);
delay(1000); // Ждём подключения последовательного порта
// Инициализация периферии
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(SOLENOID, OUTPUT);
// Инициализация Preferences
preferences.begin("lock_system", false);
if(preferences.isKey("current_password") == false) {
preferences.putString("current_password", "1234"); // Установим дефолтный пароль
}
preferences.end();
// Запускаем точку доступа и сервер
initWifi();
Serial.println("System Ready.");
}
void loop() {
char key = keypad.getKey();
if (key != NO_KEY) {
if ((key >= '0' && key <= '9')) {
if (passwordIndex < PASSWORD_LENGTH) {
enteredPassword[passwordIndex++] = key;
blinkLED(LED1, 50); // Индикатор успешного ввода символа
tone(BUZZER, 1000, 50); // Звуковой клик при вводе
Serial.print(key); // Отладочная печать
}
if (passwordIndex == PASSWORD_LENGTH) {
enteredPassword[PASSWORD_LENGTH] = '\0';
checkPassword();
}
} else if (key == '#') {
// Сброс пароля
passwordIndex = 0;
memset(enteredPassword, 0, sizeof(enteredPassword));
Serial.println("\nPassword cleared.");
}
}
// Обрабатываем запросы на веб-сервере
server.handleClient();
}