#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
// Пины и инициализация компонентов
const int greenLED = 12;
const int redLED = 13;
const int buzzer = 6;
const int servoPin = 7;
Servo myServo;
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[KEYPAD_ROWS] = {5, 4, 3, 2};
byte colPins[KEYPAD_COLS] = {A0, A1, A2, A3};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
// PIN-коды
String userPin = "123456";
String adminPin = "123ABC";
String enteredCode = "";
// Статистика
int accessAttempts = 0;
int successfulAttempts = 0;
int failedAttempts = 0;
void showMessage(String line1, String line2 = "", String line3 = "", String line4 = "") {
lcd.clear();
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
lcd.setCursor(0, 2);
lcd.print(line3);
lcd.setCursor(0, 3);
lcd.print(line4);
}
void setup() {
lcd.begin(20, 4);
showMessage("WELCOME!", "");
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(buzzer, OUTPUT);
myServo.attach(servoPin);
myServo.write(0);
delay(2000);
promptForCode();
}
void loop() {
handleKeypadInput();
}
// === Утилитарные функции ===
void promptForCode() {
showMessage("ENTER PIN-CODE:", "[______]");
enteredCode = "";
}
void handleKeypadInput() {
char key = keypad.getKey();
if (!key) return;
if (key == '#') { // Подтверждение
processCode();
} else if (key == '*') { // Сброс
promptForCode();
} else if (enteredCode.length() < 6) { // Добавление символов
enteredCode += key;
updateCodeDisplay();
}
}
void updateCodeDisplay() {
lcd.setCursor(0, 1);
lcd.print("[");
for (size_t i = 0; i < enteredCode.length(); i++) lcd.print("*");
for (size_t i = enteredCode.length(); i < 6; i++) lcd.print("_");
lcd.print("]");
}
void processCode() {
if (enteredCode == userPin) {
logAttempt(true);
userMenu();
} else if (enteredCode == adminPin) {
adminMenu();
} else {
logAttempt(false);
accessDenied();
}
promptForCode();
}
void accessDenied() {
showMessage("Access Denied");
digitalWrite(redLED, HIGH);
tone(buzzer, 500, 500);
delay(1000);
digitalWrite(redLED, LOW);
}
// === Меню пользователя ===
void userMenu() {
showMessage("User Menu:", "1:Play Song", "*:Logout");
while (true) {
char userKey = keypad.getKey();
if (userKey == '1') {
playSong();
} else if (userKey == '*') {
return;
}
}
}
void playSong() {
int melody[] = {
262, 262, 294, 262, 349, 330, // Happy Birthday to you
262, 262, 294, 262, 392, 349, // Happy Birthday to you
262, 262, 523, 440, 349, 330, 294, // Happy Birthday dear (name)
466, 466, 440, 349, 392, 349 // Happy Birthday to you
};
int duration[] = {
500, 500, 1000, 1000, 1000, 2000, // Happy Birthday to you
500, 500, 1000, 1000, 1000, 2000, // Happy Birthday to you
500, 500, 1000, 1000, 500, 500, 2000, // Happy Birthday dear (name)
500, 500, 1000, 1000, 1000, 2000 // Happy Birthday to you
};
for (int i = 0; i < sizeof(melody) / sizeof(melody[0]); i++) {
tone(buzzer, melody[i], duration[i]);
delay(duration[i] + 100); // Небольшая пауза между нотами
}
noTone(buzzer); // Выключить звук
lcd.setCursor(0, 2);
lcd.print("Playing Song...");
delay(2000);
lcd.setCursor(0, 2);
lcd.print("*:Logout ");
}
// === Меню администратора ===
void adminMenu() {
showMessage("Admin Menu:", "1:Set UserPIN", "2:Set AdminPIN", "3:Statistics");
while (true) {
char adminKey = keypad.getKey();
if (adminKey == '1') {
setPin(false);
} else if (adminKey == '2') {
setPin(true);
} else if (adminKey == '3') {
showStats();
} else if (adminKey == '*') {
return;
}
}
}
void setPin(bool isAdmin) {
String newPin = "";
showMessage(isAdmin ? "Set Admin PIN:" : "Set User PIN:", "[______]");
while (newPin.length() < 6) {
char key = keypad.getKey();
if (key) {
newPin += key;
updateCodeDisplay();
}
}
if (isAdmin) adminPin = newPin;
else userPin = newPin;
showMessage(isAdmin ? "Admin PIN Set" : "User PIN Set");
delay(2000);
}
void showStats() {
showMessage("Attempts: " + String(accessAttempts),
"Successes: " + String(successfulAttempts),
"Fails: " + String(failedAttempts));
delay(5000);
}
// === Логирование попыток ===
void logAttempt(bool success) {
accessAttempts++;
if (success) successfulAttempts++;
else failedAttempts++;
}