#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// Пины для светодиодов
const int redLedPin = 11;
const int yellowLedPin = 10;
const int greenLedPin = 9;
// Пины для пищалки
const int buzzerPin = 13;
// Пин для датчика движения
const int pirSensorPin = 12;
// Настройки для LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Настройки для клавиатуры
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 rowPins[ROWS] = {8, 7, 6, 5};
byte colPins[COLS] = {4, 3, 2, 1};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Переменные для хранения паролей
String newCode = "";
String confirmCode = "";
String savedCode = "";
// Состояние системы
enum State {ENTER_NEW_CODE, CONFIRM_NEW_CODE, ARMED, ENTER_OLD_CODE, DISARM, ENTER_CODE_TURN_OFF, ENTER_CODE_TURN_ON};
State state = ENTER_NEW_CODE;
bool buzzerActive = false;
void setup() {
pinMode(redLedPin, OUTPUT);
pinMode(yellowLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(pirSensorPin, INPUT);
lcd.init();
lcd.backlight();
showEnterNewCodeScreen();
}
void loop() {
char key = keypad.getKey();
if (key) {
handleKeyPress(key);
}
if (state == ARMED) {
int pirState = digitalRead(pirSensorPin);
if (pirState == HIGH) {
tone(buzzerPin, 1000);
buzzerActive = true;
}
}
if (buzzerActive && state == ARMED) {
int pirState = digitalRead(pirSensorPin);
if (pirState == LOW) {
noTone(buzzerPin);
buzzerActive = false;
}
}
}
void handleKeyPress(char key) {
if (state == ENTER_NEW_CODE) {
handleEnterNewCode(key);
} else if (state == CONFIRM_NEW_CODE) {
handleConfirmNewCode(key);
} else if (state == ARMED) {
handleArmedState(key);
} else if (state == ENTER_OLD_CODE) {
handleEnterOldCode(key);
} else if (state == DISARM) {
handleDisarmState(key);
} else if (state == ENTER_CODE_TURN_OFF) {
handleEnterCodeTurnOff(key);
} else if (state == ENTER_CODE_TURN_ON) {
handleEnterCodeTurnOn(key);
}
}
void handleEnterNewCode(char key) {
if (key >= '0' && key <= '9' && newCode.length() < 5) {
newCode += key;
updateCodeDisplay(newCode);
} else if (key == '*') {
if (newCode.length() > 0) {
newCode = newCode.substring(0, newCode.length() - 1);
updateCodeDisplay(newCode);
}
}
if (newCode.length() == 5) {
delay(2000);
state = CONFIRM_NEW_CODE;
showConfirmNewCodeScreen();
}
}
void handleConfirmNewCode(char key) {
if (key >= '0' && key <= '9' && confirmCode.length() < 5) {
confirmCode += key;
updateCodeDisplay(confirmCode);
} else if (key == '*') {
if (confirmCode.length() > 0) {
confirmCode = confirmCode.substring(0, confirmCode.length() - 1);
updateCodeDisplay(confirmCode);
}
}
if (confirmCode.length() == 5) {
if (newCode == confirmCode) {
savedCode = newCode;
showSavingCodeScreen();
delay(3000);
state = ARMED;
showArmedScreen();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Codes do not match");
delay(2000);
state = ENTER_NEW_CODE;
showEnterNewCodeScreen();
}
}
}
void handleArmedState(char key) {
if (key == 'A') {
state = ENTER_OLD_CODE;
showEnterOldCodeScreen();
} else if (key == 'B') {
state = ENTER_CODE_TURN_OFF;
showEnterCodeTurnOffScreen();
} else if (key == 'C') {
}
}
void handleEnterOldCode(char key) {
static String oldCode = "";
if (key == 'D') {
state = ARMED;
showArmedScreen();
oldCode = "";
return;
}
if (key >= '0' && key <= '9' && oldCode.length() < 5) {
oldCode += key;
updateCodeDisplay(oldCode);
}
if (oldCode.length() == 5) {
if (oldCode == savedCode) {
state = ENTER_NEW_CODE;
newCode = "";
confirmCode = "";
oldCode = ""; // Сброс старого кода
showEnterNewCodeScreen();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Incorrect code");
delay(2000);
state = ARMED;
showArmedScreen();
oldCode = ""; // Сброс старого кода
}
}
}
void handleDisarmState(char key) {
if (key == 'A') {
state = ENTER_OLD_CODE;
showEnterOldCodeScreen();
} else if (key == 'B') {
state = ENTER_CODE_TURN_ON;
showEnterCodeTurnOnScreen();
} else if (key == 'C') {
toggleBuzzer();
}
}
void handleEnterCodeTurnOff(char key) {
static String turnOffCode = "";
if (key == 'D') {
state = DISARM;
showDisarmedScreen();
turnOffCode = ""; // Sброс кода отключения
return;
}
if (key >= '0' && key <= '9' && turnOffCode.length() < 5) {
turnOffCode += key;
updateCodeDisplay(turnOffCode);
}
if (turnOffCode.length() == 5) {
if (turnOffCode == savedCode) {
state = DISARM;
showDisarmedScreen();
turnOffCode = ""; // Sброс кода отключения
noTone(buzzerPin); // Stop the buzzer sound
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Incorrect code");
delay(2000);
state = ARMED;
showArmedScreen();
turnOffCode = ""; // Sброс кода отключения
}
}
}
void handleEnterCodeTurnOn(char key) {
static String turnOnCode = "";
if (key == 'D') {
state = DISARM;
showDisarmedScreen();
turnOnCode = ""; // Сброс кода включения
return;
}
if (key >= '0' && key <= '9' && turnOnCode.length() < 5) {
turnOnCode += key;
updateCodeDisplay(turnOnCode);
}
if (turnOnCode.length() == 5) {
if (turnOnCode == savedCode) {
state = ARMED;
showArmedScreen();
turnOnCode = ""; // Сброс кода включения
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Incorrect code");
delay(2000);
state = DISARM;
showDisarmedScreen();
turnOnCode = ""; // Сброс кода включения
}
}
}
void updateCodeDisplay(String code) {
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
for (int i = 0; i < code.length(); i++) {
lcd.print('*');
}
}
void showEnterNewCodeScreen() {
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Create new code");
lcd.setCursor(0, 2);
lcd.print("_____");
lcd.setCursor(0, 3);
lcd.print("* = erase");
}
void showConfirmNewCodeScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Confirm the code");
lcd.setCursor(0, 2);
lcd.print("_____");
confirmCode = "";
lcd.setCursor(0, 3);
lcd.print("* = erase");
}
void showSavingCodeScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Saving the code");
blinkYellowLed();
}
void showArmedScreen() {
digitalWrite(redLedPin, HIGH);
digitalWrite(yellowLedPin, LOW);
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm is armed");
lcd.setCursor(0, 1);
lcd.print("A = new code");
lcd.setCursor(0, 2);
lcd.print("B = turn off alarm");
}
void showDisarmedScreen() {
digitalWrite(redLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
digitalWrite(greenLedPin, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Alarm is disarmed");
lcd.setCursor(0, 1);
lcd.print("A = new code");
lcd.setCursor(0, 2);
lcd.print("B = turn on alarm");
}
void showEnterOldCodeScreen() {
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter old code");
lcd.setCursor(0, 2);
lcd.print("_____");
lcd.setCursor(0, 3);
lcd.print("D = return * = erase");
}
void showEnterCodeTurnOffScreen() {
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter the code");
lcd.setCursor(0, 2);
lcd.print("_____");
lcd.setCursor(0, 3);
lcd.print("D = return * = erase");
}
void showEnterCodeTurnOnScreen() {
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter the code");
lcd.setCursor(0, 2);
lcd.print("_____");
lcd.setCursor(0, 3);
lcd.print("D = return * = erase");
}
void toggleBuzzer() {
static bool isBuzzerOn = false;
isBuzzerOn = !isBuzzerOn;
if (isBuzzerOn) {
tone(buzzerPin, 1000);
} else {
noTone(buzzerPin);
}
}
void blinkYellowLed() {
for (int i = 0; i < 3; i++) {
digitalWrite(yellowLedPin, HIGH);
delay(500);
digitalWrite(yellowLedPin, LOW);
delay(500);
}
}