#include <Keypad.h>
#include <Servo.h>
#include "SafeState.h"
#include "icons.h"
#define SERVO_PIN 6
#define SERVO_LOCK_POS 20
#define SERVO_UNLOCK_POS 90
Servo lockServo;
#define LED1 13 // красный светодиод
#define RELAY 11 // реле на замок
#define NUM_KEYS 4 // количество знаков в коде
bool doorOpen = false; // Флаг, отслеживающий состояние двери
unsigned long lastKeyPressTime = 0;
const int buttonPin = 12; // Пин, к которому подключена кнопка
int buttonState = 0;
char key;
char myarraw[NUM_KEYS] = { '1', '2', '3', '4'}; // массив с верным кодом
char button_pressed[NUM_KEYS]; //массив для хранения нажатых кнопок
int k=0; // счетчик нажатий
int s=0; // счетчик совпадений нажатых кнопок с верными
const byte ROWS = 2; // количество строк в матрице клавиатуры
const byte COLS = 2; // количество столбцов
char keys[ROWS][COLS] = { // таблица соответствия кнопок символам
{'1','2'},
{'3','4'}};
byte rowPins[ROWS] = {5,4}; // пины подключенных строк
byte colPins[COLS] = {9,8}; // пины подключенных столбцов
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // создаем объект клавиатуры для работы с ней
SafeState safeState;
void setup() {
pinMode(buttonPin, INPUT);
pinMode(RELAY, OUTPUT);
pinMode(LED1, OUTPUT); // красный светодиод
//pinMode(RELAY, OUTPUT); // реле управления замком
//digitalWrite(RELAY, HIGH); // вход реле инверсный, поэтому его сразу включаем (?!)
lockServo.attach(SERVO_PIN);
/* Make sure the physical lock is sync with the EEPROM state */
Serial.begin(115200);
if (safeState.locked()) {
unlock();
} else {
lock();
}
}
void OpenDoor(){
unlock();
for (int i = 0; i < 5; i++) {
digitalWrite(LED1, HIGH);
tone(RELAY,1020,200);
delay(200);
digitalWrite(LED1, LOW);
delay(200);
}
lock();
}
void lock() {
lockServo.write(SERVO_LOCK_POS);
safeState.lock();
}
void unlock() {
lockServo.write(SERVO_UNLOCK_POS);
}
void loop ()
{ key = keypad.getKey(); // спрашиваем у клавиатуры, есть нажатая кнопка?
if (digitalRead(buttonPin) && !doorOpen) {
OpenDoor();
k=0; // обнуляем счетчики, чтобы начать все заново
s=0; //
doorOpen = true; // Устанавливаем флаг "дверь открыта"
}
if ( key != NO_KEY ) // если она все-таки есть
{
lastKeyPressTime = millis();
button_pressed [k] = key; //сохраняем эту кнопочку в массиве
k = k + 1; // запоминаем сколько уже кнопок нажали
if(k == NUM_KEYS) // если нажали нужное количество кнопок
{for ( uint8_t i = 0; i < NUM_KEYS; i++) // пройдемся по всему массиву
{
if (button_pressed[i] == myarraw[i]) // и проверим нажатые кнопки с верным кодом
{s = s + 1; // плюсуем счетчик совпадений
}
}
if(s == NUM_KEYS) //если у нас все кнопки совпали с кодом, то включаем реле
{
OpenDoor();
k=0; //сбрасываем счетчик нажатий нашей переменной
s=0; // сбрасываем счетчик совпадений нашей переменной
} else { // если не все кнопки совпали с верным кодом
digitalWrite (LED1, HIGH); // включаем красный светик (пользователь ввел неверный код)
tone(RELAY,1020,5000);
digitalWrite (LED1, LOW); // гасим красн светик
k=0; // обнуляем счетчики, чтобы начать все заново
s=0; //
}
}
}
else{
unsigned long currentTime = millis(); // Текущее время
if ((currentTime - lastKeyPressTime >= 10000) and k > 0) { // Если прошло 10 секунд с последнего нажатия кнопки
k = 0; // Обнуляем счетчик нажатий
s = 0; // Обнуляем счетчик совпадений
tone(RELAY, 555, 250);
delay(100);
noTone(RELAY); // Остановка звука
lastKeyPressTime = millis(); // Обновляем время последнего нажатия кнопки
}
}
if (!digitalRead(buttonPin) && doorOpen) { // Если кнопка отпущена и дверь открыта
doorOpen = false; // Устанавливаем флаг "дверь закрыта"
}
}