Добрый день уважаемые форумчане! пишу здесь так как уже отчаялся совсем..... Может кто сталкивался с похожей задачей, и может подсказать что я не так делаю...
Итак начнем все по порядку:
К идее сделать свой контроллер СКУД я пришел полгода назад, так как то что имеется на рынке или слишком дорогое или не отвечает нужному функционалу.
Рассматривал разные варианты и пришел только к 1 - возьми и сделай сам.
Что имею:
1) Контроллер ESP-WROOM32
2) реле управления замком 1 канальное
3) Считыватель Matrix II wiegand
4) Кнопка выход
5) кнопка reset
6) Ethernet модуль enc28j60
На данный момент реализован функционал:
1) проход по ключу записанному в базе
2) заливание бызы через FTP
3) FTP сервер для обращения к SPIFFS(собственно здесь и хранится вся стартовая конфигурация)
4) кнопка ресет для возвращения стандартных настроек(сеть(ip mask gateway) wifi(ssid и пароль сети по умолчанию для ввода устройства в сеть) время открытия замка, режим accept для сбора базы ключей, перезагрузка контроллера по умолчанию 0)
Что не получается:
Не получается подключить ethernet модуль совместно с реализованными функциями. Это приводит или к работе только ethernet модуля + web server или контроллер начинает уходить в boot loop. Мне нужна помощь знающих людей которые могут посоветовать как обойти данную проблему
Предлагайте идеи для реализации нужного функционала(совет ставить маршрутизатор не подойдёт, так как бывает такое что нет возможности разместить его рядом с контроллером)
Схему подключения прилогаю
Итак начнем все по порядку:
К идее сделать свой контроллер СКУД я пришел полгода назад, так как то что имеется на рынке или слишком дорогое или не отвечает нужному функционалу.
Рассматривал разные варианты и пришел только к 1 - возьми и сделай сам.
Что имею:
1) Контроллер ESP-WROOM32
2) реле управления замком 1 канальное
3) Считыватель Matrix II wiegand
4) Кнопка выход
5) кнопка reset
6) Ethernet модуль enc28j60
На данный момент реализован функционал:
1) проход по ключу записанному в базе
2) заливание бызы через FTP
3) FTP сервер для обращения к SPIFFS(собственно здесь и хранится вся стартовая конфигурация)
4) кнопка ресет для возвращения стандартных настроек(сеть(ip mask gateway) wifi(ssid и пароль сети по умолчанию для ввода устройства в сеть) время открытия замка, режим accept для сбора базы ключей, перезагрузка контроллера по умолчанию 0)
Что не получается:
Не получается подключить ethernet модуль совместно с реализованными функциями. Это приводит или к работе только ethernet модуля + web server или контроллер начинает уходить в boot loop. Мне нужна помощь знающих людей которые могут посоветовать как обойти данную проблему
Исходный код устройства:
#include <Wiegand.h>
#include <WiFi.h>
#include <SPIFFS.h>
#include <FTPServer.h>
#include <IPAddress.h>
#include <unordered_set> // Используем unordered_set для быстрого поиска ключей
WIEGAND wg;
const int relayPin = 13;
const char* ip_file = "/ip.cfg";
const char* wifi_file = "/wifi.cfg";
const char* ftp_file = "/ftp.cfg";
const char* keys_file = "/keys.cfg";
const char* lock_time_file = "/lock_time.cfg";
const char* reboot_file = "/reboot.cfg";
const char* accept_file = "/accept.cfg";
FTPServer ftpServer(SPIFFS);
const int resetButtonPin = 15; //Кнопка reset
const int buttonPin = 12; // Пин для кнопки
std::unordered_set<long> keysSet; // Используем множество для хранения ключей
int lockTime = 5; // Время работы реле в секундах
unsigned long lastRebootCheck = 0;
unsigned long rebootStartTime = 0;
bool rebootScheduled = false;
int rebootDelay = 0;
void setup() {
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH); // Начальное состояние реле (выключено)
pinMode(buttonPin, INPUT_PULLUP); // Настройка кнопки с подтяжкой
Serial.begin(115200);
Serial.println("Начинаем настройку...");
pinMode(resetButtonPin, INPUT_PULLUP);
if (!SPIFFS.begin(true)) {
Serial.println("Ошибка инициализации SPIFFS");
return;
}
Serial.println("SPIFFS инициализировано успешно.");
if (!SPIFFS.exists(wifi_file)) createDefaultWifiConfig();
if (!SPIFFS.exists(ftp_file)) createDefaultFtpConfig();
if (!SPIFFS.exists(ip_file)) createDefaultIpConfig();
if (!SPIFFS.exists(keys_file)) createDefaultKeysConfig();
if (!SPIFFS.exists(lock_time_file)) createDefaultLockTimeConfig();
if (!SPIFFS.exists(accept_file)) createDefaultAcceptConfig(); // Создание accept.cfg по умолчанию
// Проверка и инициализация файла reboot.cfg
if (!SPIFFS.exists(reboot_file)) {
createDefaultRebootConfig();
} else {
File rebootFile = SPIFFS.open(reboot_file, "r");
if (rebootFile) {
String rebootStr = rebootFile.readStringUntil('\n');
rebootStr.trim(); // Обрезаем пробелы
rebootFile.close();
if (rebootStr != "0") {
createDefaultRebootConfig();
}
}
}
if (digitalRead(resetButtonPin) == LOW) {
delay(1000);
if (digitalRead(resetButtonPin) == LOW) {
resetConfigurations();
delay(2000);
}
}
readIpConfig();
readWifiConfig();
readFtpConfig();
readKeysConfig(); // Считываем ключи в память
readLockTimeConfig();
wg.begin(26, 27); // Инициализация Wiegand
}
void loop() {
ftpServer.handleFTP();
checkReboot(); // Проверяем необходимость перезагрузки
// Проверка нажатия кнопки для активации реле
if (digitalRead(buttonPin) == LOW) {
readLockTimeConfig(); // Чтение времени открытия замка
Serial.println("Кнопка нажата!");
activateRelay(lockTime); // Включаем реле на время, указанное в lock_time.cfg
}
if (wg.available()) {
long cardCode = wg.getCode();
readLockTimeConfig();
Serial.print("DECIMAL = ");
Serial.print(cardCode);
Serial.print(", Type W");
Serial.println(wg.getWiegandType());
if (isKeyMatched(cardCode)) {
readLockTimeConfig();
Serial.println("Ключ совпал");
activateRelay(lockTime);
} else {
readLockTimeConfig();
Serial.println("Ключ не найден в базе");
checkAndAddUnknownKey(cardCode); // Проверка accept.cfg и добавление нового ключа
}
}
}
void checkAndAddUnknownKey(long cardCode) {
int acceptValue = readAcceptConfig();
if (acceptValue == 1) {
addKeyToKeysFile(cardCode);
activateRelay(lockTime);
Serial.println("Новый ключ добавлен в keys.cfg и дверь открыта.");
} else {
Serial.println("Добавление новых ключей отключено.");
}
}
void createDefaultAcceptConfig() {
Serial.println("Создание файла accept.cfg с настройками по умолчанию...");
File acceptFile = SPIFFS.open(accept_file, "w");
if (acceptFile) {
acceptFile.println("0"); // Значение по умолчанию: 0
acceptFile.close();
Serial.println("Файл accept.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл accept.cfg.");
}
}
int readAcceptConfig() {
File acceptFile = SPIFFS.open(accept_file, "r");
if (acceptFile) {
String acceptStr = acceptFile.readStringUntil('\n');
acceptFile.close();
return acceptStr.toInt();
} else {
Serial.println("Не удалось открыть файл accept.cfg.");
return 0; // Если файл не доступен, возвращаем значение 0
}
}
void addKeyToKeysFile(long cardCode) {
File keysFile = SPIFFS.open(keys_file, "a"); // Открываем файл для добавления
if (keysFile) {
keysFile.println(cardCode); // Добавляем новый ID карты
keysFile.close();
keysSet.insert(cardCode); // Добавляем ключ в множество для быстрого доступа
Serial.println("Новый ключ добавлен в keys.cfg: " + String(cardCode));
} else {
Serial.println("Не удалось открыть файл keys.cfg для записи.");
}
}
void checkReboot() {
unsigned long currentMillis = millis();
if (currentMillis - lastRebootCheck >= 10000) { // Проверяем каждые 10 секунд
lastRebootCheck = currentMillis;
File rebootFile = SPIFFS.open(reboot_file, "r");
if (rebootFile) {
String rebootStr = rebootFile.readStringUntil('\n');
rebootDelay = rebootStr.toInt();
rebootFile.close();
Serial.println("Содержимое reboot.cfg: " + rebootStr);
Serial.println("Запланированная задержка перезагрузки: " + String(rebootDelay));
if (rebootDelay > 0 && !rebootScheduled) {
Serial.println("Запланирована перезагрузка через " + String(rebootDelay) + " секунд.");
rebootStartTime = currentMillis;
rebootScheduled = true;
}
} else {
Serial.println("Не удалось открыть файл reboot.cfg.");
}
}
if (rebootScheduled && (currentMillis - rebootStartTime >= rebootDelay * 1000)) {
SPIFFS.remove(reboot_file); // Удаляем файл перезагрузки
Serial.println("Перезагрузка устройства...");
ESP.restart();
}
}
void activateRelay(int duration) {
digitalWrite(relayPin, LOW); // Включаем реле
Serial.println("Relay is ON");
delay(duration * 1000); // Задержка по времени
digitalWrite(relayPin, HIGH); // Выключаем реле
Serial.println("Relay is OFF");
}
void createDefaultRebootConfig() {
Serial.println("Создание файла reboot.cfg с настройками по умолчанию...");
File rebootFile = SPIFFS.open(reboot_file, "w");
if (rebootFile) {
rebootFile.println("0"); // Значение по умолчанию
rebootFile.close();
Serial.println("Файл reboot.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл reboot.cfg.");
}
}
bool isKeyMatched(long cardCode) {
return keysSet.find(cardCode) != keysSet.end(); // Быстрый поиск ключа в множестве
}
void resetConfigurations() {
SPIFFS.remove(wifi_file);
SPIFFS.remove(ftp_file);
SPIFFS.remove(ip_file);
SPIFFS.remove(lock_time_file);
createDefaultWifiConfig();
createDefaultFtpConfig();
createDefaultIpConfig();
createDefaultLockTimeConfig();
Serial.println("Настройки сброшены до заводских.");
}
void createDefaultKeysConfig() {
Serial.println("Создание файла keys.cfg с настройками по умолчанию...");
File keysFile = SPIFFS.open(keys_file, "w");
if (keysFile) {
keysFile.println("9178396"); // Пример ключа
keysFile.close();
Serial.println("Файл keys.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл keys.cfg.");
}
}
void createDefaultLockTimeConfig() {
Serial.println("Создание файла lock_time.cfg с настройками по умолчанию...");
File lockTimeFile = SPIFFS.open(lock_time_file, "w");
if (lockTimeFile) {
lockTimeFile.println("5"); // Время открытия замка по умолчанию (в секундах)
lockTimeFile.close();
Serial.println("Файл lock_time.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл lock_time.cfg.");
}
}
void readKeysConfig() {
File keysFile = SPIFFS.open(keys_file, "r");
if (keysFile) {
while (keysFile.available()) {
long key = keysFile.readStringUntil('\n').toInt();
keysSet.insert(key); // Вставляем ключ в множество
}
keysFile.close();
Serial.println("Прочитанные ключи:");
for (auto key : keysSet) {
Serial.println(key); // Печатаем все ключи
}
} else {
Serial.println("Не удалось открыть файл keys.cfg.");
}
}
void readLockTimeConfig() {
File lockTimeFile = SPIFFS.open(lock_time_file, "r");
if (lockTimeFile) {
String lockTimeStr = lockTimeFile.readStringUntil('\n');
lockTime = lockTimeStr.toInt();
lockTimeFile.close();
Serial.println("Время открытия замка: " + String(lockTime) + " секунд");
} else {
Serial.println("Не удалось открыть файл lock_time.cfg.");
}
}
// Чтение и создание других конфигурационных файлов...
void createDefaultWifiConfig() {
Serial.println("Создание файла wifi.cfg с настройками по умолчанию...");
File wifiFile = SPIFFS.open(wifi_file, "w");
if (wifiFile) {
wifiFile.println("WIFINETWORK"); // SSID
wifiFile.println("12345678"); // Пароль
wifiFile.close();
Serial.println("Файл wifi.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл wifi.cfg.");
}
}
void createDefaultFtpConfig() {
Serial.println("Создание файла ftp.cfg с настройками по умолчанию...");
File ftpFile = SPIFFS.open(ftp_file, "w");
if (ftpFile) {
ftpFile.println("user"); // Имя пользователя
ftpFile.println("password"); // Пароль
ftpFile.close();
Serial.println("Файл ftp.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл ftp.cfg.");
}
}
void createDefaultIpConfig() {
Serial.println("Создание файла ip.cfg с настройками по умолчанию...");
File ipFile = SPIFFS.open(ip_file, "w");
if (ipFile) {
ipFile.println("192.168.1.108"); // IP
ipFile.println("255.255.255.0"); // Маска
ipFile.println("192.168.1.1"); // Шлюз
ipFile.close();
Serial.println("Файл ip.cfg создан успешно.");
} else {
Serial.println("Не удалось создать файл ip.cfg.");
}
}
void readWifiConfig() {
File wifiFile = SPIFFS.open(wifi_file, "r");
if (wifiFile) {
String ssid = wifiFile.readStringUntil('\n');
String password = wifiFile.readStringUntil('\n');
wifiFile.close();
ssid.trim();
password.trim();
Serial.println("Прочитанные настройки Wi-Fi:");
Serial.println("SSID: " + ssid);
Serial.println("Пароль: " + password);
Serial.println("Подключение к Wi-Fi...");
WiFi.begin(ssid.c_str(), password.c_str());
unsigned long startAttemptTime = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print("Подключение...");
if (millis() - startAttemptTime > 15000) {
Serial.println("Не удалось подключиться к Wi-Fi в течение 15 секунд.");
return;
}
}
Serial.println("Подключено к Wi-Fi: " + ssid);
} else {
Serial.println("Не удалось открыть файл wifi.cfg.");
}
}
void readFtpConfig() {
File ftpFile = SPIFFS.open(ftp_file, "r");
if (ftpFile) {
String user = ftpFile.readStringUntil('\n');
String password = ftpFile.readStringUntil('\n');
ftpFile.close();
user.trim();
password.trim();
Serial.println("Прочитанные настройки FTP:");
Serial.println("Пользователь: " + user);
Serial.println("Пароль: " + password);
ftpServer.begin(user.c_str(), password.c_str());
Serial.println("FTP-сервер запущен.");
} else {
Serial.println("Не удалось открыть файл ftp.cfg.");
}
}
void readIpConfig() {
File ipFile = SPIFFS.open(ip_file, "r");
if (ipFile) {
String ip = ipFile.readStringUntil('\n');
String mask = ipFile.readStringUntil('\n');
String gateway = ipFile.readStringUntil('\n');
ipFile.close();
ip.trim();
mask.trim();
gateway.trim();
Serial.println("Прочитанные настройки IP:");
Serial.println("IP: " + ip);
Serial.println("Маска: " + mask);
Serial.println("Шлюз: " + gateway);
IPAddress localIP, localMask, localGateway;
if (!localIP.fromString(ip) || !localMask.fromString(mask) || !localGateway.fromString(gateway)) {
Serial.println("Ошибка: некорректный IP, маска или шлюз в файле конфигурации.");
return;
}
if (!WiFi.config(localIP, localGateway, localMask)) {
Serial.println("Ошибка установки статического IP.");
} else {
Serial.println("Статический IP установлен: " + ip);
}
} else {
Serial.println("Не удалось открыть файл ip.cfg.");
}
}
Схему подключения прилогаю
Вложения
-
604.4 KB Просмотры: 8