#include <Keypad.h>
#include <TM1637Display.h>
// Пины дисплея TM1637
#define CLK 11
#define DIO 12
TM1637Display display(CLK, DIO);
// Пин пищалки
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"; // Код обезвреживания (классика CS: 7355)
String inputBuffer = "";
unsigned long timeLeft = 45000; // Таймер на 45 секунд (в миллисекундах)
unsigned long previousMillis = 0;
bool bombActive = true;
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
display.setBrightness(0x0f); // Максимальная яркость дисплея
// Выводим начальное время 00:45 с двоеточием посередине
display.showNumberDecEx(4500, 0b01000000, true);
}
void loop() {
if (!bombActive) return;
unsigned long currentMillis = millis();
// Логика таймера (обратный отсчет каждую секунду)
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
if (timeLeft > 0) {
timeLeft -= 1000;
int seconds = (timeLeft / 1000) % 60;
int minutes = (timeLeft / 1000) / 60;
int displayValue = minutes * 100 + seconds;
// Обновляем дисплей с разделительным двоеточием
display.showNumberDecEx(displayValue, 0b01000000, true);
// Пикаем каждый цикл (в последние 10 секунд — чаще и выше)
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);
}
// Вывод текста b00n на экран (кастомные сегменты)
uint8_t boomSegments[] = { 0x7c, 0x5c, 0x5c, 0x3f };
display.setSegments(boomSegments);
}
}
// Чтение нажатий с клавиатуры
char key = keypad.getKey();
if (key) {
tone(BUZZER_PIN, 1800, 40); // Звук нажатия клавиши
if (key == '#') {
// Проверка введенного кода при нажатии '#'
if (inputBuffer == DEFUSE_CODE) {
bombActive = false;
noTone(BUZZER_PIN);
// Победный звук
tone(BUZZER_PIN, 2000, 150);
delay(200);
tone(BUZZER_PIN, 3000, 300);
// Вывод надписи GOOD
uint8_t goodSegments[] = { 0x3d, 0x79, 0x3f, 0x5e };
display.setSegments(goodSegments);
} else {
// Ошибка: неверный код (штраф — минус 5 секунд)
if (timeLeft > 5000) timeLeft -= 5000; else timeLeft = 0;
inputBuffer = "";
tone(BUZZER_PIN, 150, 400); // Звук ошибки
}
} else if (key == '*') {
// Сброс введенного буфера
inputBuffer = "";
int seconds = (timeLeft / 1000) % 60;
int minutes = (timeLeft / 1000) / 60;
display.showNumberDecEx(minutes * 100 + seconds, 0b01000000, true);
} else {
// Добавление цифры в буфер (максимум 4 символа)
if (inputBuffer.length() < 4) {
inputBuffer += key;
// Показываем вводимые цифры без двоеточия
display.showNumberDecEx(inputBuffer.toInt(), 0, false);
}
}
}
}