#include <Keypad.h>
#include <TM1637Display.h>
// Пины дисплея TM1637
#define CLK 11
#define DIO 12
TM1637Display display(CLK, DIO);
// Пин пищалки (HW-508 / пин 13 со встроенным светодиодом)
const int BUZZER_PIN = 13;
// Настройка клавиатуры 4x4 (HX-543)
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] = {9, 8, 7, 6}; // Пины строк клавиатуры
byte colPins[COLS] = {5, 4, 3, 2}; // Пины столбцов клавиатуры
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Настройки игры
const String DEFUSE_CODE = "7355"; // Код обезвреживания
String inputBuffer = "";
unsigned long timeLeft = 45000; // Таймер на 45 секунд
unsigned long previousMillis = 0;
bool bombActive = true;
// Функция точного вывода на дисплей
void updateDisplay() {
if (inputBuffer.length() > 0) {
// Показываем вводимый текст (дополняя нулями слева до 4 знаков)
int val = inputBuffer.toInt();
display.showNumberDecEx(val, 0, true, 4, 0);
} else {
// Таймер ММ:СС с двоеточием посередине
int seconds = (timeLeft / 1000) % 60;
int minutes = (timeLeft / 1000) / 60;
int displayValue = (minutes * 100) + seconds;
display.showNumberDecEx(displayValue, 0b01000000, true, 4, 0);
}
}
void setup() {
Serial.begin(9600); // Включаем монитор порта для проверки клавиатуры
pinMode(BUZZER_PIN, OUTPUT);
display.setBrightness(0x0f);
updateDisplay();
}
void loop() {
if (!bombActive) return;
unsigned long currentMillis = millis();
// Логика таймера (обратный отсчет каждую секунду)
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
if (timeLeft > 0) {
timeLeft -= 1000;
if (inputBuffer.length() == 0) {
updateDisplay();
}
tone(BUZZER_PIN, (timeLeft <= 10000) ? 2500 : 1200, 80);
} else {
// Время вышло — БУМ!
bombActive = false;
for (int i = 0; i < 5; i++) {
tone(BUZZER_PIN, 300, 200);
delay(300);
}
uint8_t boomSegments[] = { 0x7c, 0x5c, 0x5c, 0x3f }; // b00n
display.setSegments(boomSegments);
}
}
// Чтение нажатий с клавиатуры
char key = keypad.getKey();
if (key) {
// Выводим в монитор порта то, что реально нажалось (для проверки шлейфа)
Serial.print("Нажата кнопка: ");
Serial.println(key);
tone(BUZZER_PIN, 1800, 40); // Звук нажатия
if (key == '*') {
// Сброс введенного буфера
inputBuffer = "";
updateDisplay();
}
else if (key == '#') {
// Проверка кода по нажатию решетки '#'
if (inputBuffer == DEFUSE_CODE) {
bombActive = false;
noTone(BUZZER_PIN);
tone(BUZZER_PIN, 2000, 150);
delay(200);
tone(BUZZER_PIN, 3000, 300);
uint8_t goodSegments[] = { 0x3d, 0x79, 0x3f, 0x5e }; // GOOD
display.setSegments(goodSegments);
} else {
// Ошибка: неверный код (штраф — минус 5 секунд)
if (timeLeft > 5000) timeLeft -= 5000; else timeLeft = 0;
inputBuffer = "";
tone(BUZZER_PIN, 150, 400);
updateDisplay();
}
}
else if (key >= '0' && key <= '9') {
if (inputBuffer.length() < 4) {
inputBuffer += key;
updateDisplay();
}
}
}
}