#define default_minutes 10 // предустановленные минуты (для режима игры №1)
#define default_seconds 30 // предустановленные секунды (для режима игры №1)
#define led_r 12
#define led_g 11
#define speaker_pin 2
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
//#include <avr/pgmspace.h>
//#include <LCDI2C_UTF8.h>
//#include <ROM_Standard_RU.h>
#define I2C_ADDR 0x27 //Адрес LCD
#define LCD_COLUMNS 16 //Количество ячеек
#define LCD_LINES 2 //Количество строк
unsigned long previousMillisCountDown, last_time; // таймер для милис
const unsigned long intervalCountDown = 1000; // интервал изменения обратного отсчета
int countDown = 60; // стартовое значение обратного отсчета
int minutes, seconds, milseconds;
boolean flag , flag_t, flag_b;
String pass, set_min;
byte lcdbuffer[8];
LiquidCrystal_I2C lcd(0x27,16,2); // установка адреса LCD 0x27 для 16 символов и 2 строки
/*установки клавиатуры*/
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
uint8_t colPins[COLS] = { 6, 5, 4, 3 }; // Пины C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 10, 9, 8, 7 }; // Пины R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
/*различные символы*/
uint8_t bell[8] = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4};
uint8_t note[8] = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0};
uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};
uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
uint8_t duck[8] = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0};
uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4}; // символ в HEX
uint8_t lookOn[8] = { // символ в битах
B00110,
B01001,
B01000,
B01000,
B01111,
B01111,
B01111,
B00000
};
uint8_t P_big[8] = {0x1F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00}; //П
uint8_t U_big[8] = { 0x11, 0x11, 0x11, 0x0A, 0x04, 0x08, 0x10, 0x00}; //У
uint8_t i_smal[8] = {0x00, 0x00, 0x11, 0x13, 0x15, 0x19, 0x11, 0x00}; //и
uint8_t v_smal[8] = {0x00, 0x00, 0x1C, 0x12, 0x1C, 0x12, 0x1C, 0x00}; //в
uint8_t t_smal[8] = {0x00, 0x00, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x00}; //т
uint8_t yu_smal[8] = {0x00, 0x00, 0x12, 0x15, 0x1D, 0x15, 0x12, 0x00}; //ю
uint8_t d_smal[8] = {0x00, 0x00, 0x0F, 0x05, 0x09, 0x1F, 0x11, 0x00}; //д
uint8_t ya_smal[8] = {0x00, 0x00, 0x0F, 0x11, 0x0F, 0x05, 0x09, 0x00}; //я
uint8_t g_smal[8] = {0x00, 0x00, 0x1F, 0x11, 0x10, 0x10, 0x10, 0x00}; //г
uint8_t l_smal[8] = {0x00, 0x00, 0x07, 0x05, 0x09, 0x09, 0x11, 0x00}; //л
uint8_t ii_smal[8] = {0x00, 0x00, 0x11, 0x11, 0x19, 0x15, 0x19, 0x00}; //ы
uint8_t sh_smal[8] = {0x00, 0x00, 0x15, 0x15, 0x15, 0x15, 0x1F, 0x00}; //ш
uint8_t n_smal[8] = {0x00, 0x00, 0x11, 0x11, 0x1F, 0x11, 0x11, 0x00}; //н
uint8_t yi_smal[8] = {0x00, 0x0A, 0x04, 0x11, 0x13, 0x15, 0x19, 0x00}; //й
uint8_t p_smal[8] = {0x00, 0x00, 0x1F, 0x11, 0x11, 0x11, 0x11, 0x00}; //п
uint8_t b_smal[8] = {0x03, 0x0C, 0x10, 0x1E, 0x11, 0x11, 0x0E, 0x00}; //б
uint8_t zh_smal[8] = {0x00, 0x00, 0x15, 0x15, 0x0E, 0x15, 0x15, 0x00}; //ж
/*сообщение приветствия*/
void showStartupMessage() {
lcd.createChar(1, P_big);
lcd.createChar(2, i_smal);
lcd.createChar(3, g_smal);
lcd.createChar(6, v_smal);
lcd.createChar(4, t_smal);
lcd.createChar(5, ya_smal);
lcd.setCursor(0, 0);
lcd.print(F("\x01p\x02\x06\x65\x04 Bap\x05\x03o\x06!")); //"Привет Варягов!""
delay(1000);
lcd.setCursor(0, 1);
String message = "LCD1602_Timer v0.1";
for (byte i = 0; i < message.length(); i++) { //вывод символов по очереди
lcd.print(message[i]);
delay(100);
}
delay(1000);
}
/*
void CustomChar(){
lcd.backlight();
lcd.clear();
lcd.createChar(2, i_smal);
lcd.createChar(3, l_smal);
lcd.createChar(4, ii_smal);
lcd.createChar(6, v_smal);
lcd.setCursor(0, 0); // установка курсора
lcd.print(F()"\x08 C\x02m\x06o\x03\x04...")); // \x08" перевод значка в байтовом формате "Символы"
lcd.createChar(0, bell);
lcd.createChar(1, note);
lcd.createChar(2, clock);
lcd.createChar(3, heart);
lcd.createChar(4, duck);
lcd.createChar(5, check);
lcd.createChar(6, cross);
lcd.createChar(7, retarrow);
lcd.createChar(8, lookOn);
lcd.home();
lcd.setCursor(0, 1); // установка курсора
uint8_t i = 0;
for (int j=0; j<9; j++) {
lcd.write(i+j); // вывод всех своих значков
}
}
*/
void lock() {
digitalWrite(led_r, HIGH);
}
void unlock() {
digitalWrite(led_r, LOW);
digitalWrite(led_g, HIGH);
digitalWrite(speaker_pin, LOW);
lcd.createChar(1, d_smal);
lcd.createChar(2, i_smal);
lcd.createChar(3, p_smal);
lcd.createChar(4, ya_smal);
lcd.createChar(5, n_smal);
lcd.createChar(6, t_smal);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Ko\x01 \x03p\x02\x05\x04\x06!")); //"Код принят!"
lcd.setCursor(0, 1);
lcd.print(F("Ko\x01 \x03p\x02\x05\x04\x06!")); //"Обезврежено!"
flag = 0;
flag_t = 0;
flag_b = 1;
delay(1000);
defuse();
delay(10000);
lcd.noBacklight(); // выключение подсветки
}
void setup()
{
lcd.init(); // инициализация монитора lcd
lcd.backlight(); // включение подсветки
lcd.begin(16, 2);
pinMode(led_r, OUTPUT);
pinMode(led_g, OUTPUT);
// Serial.begin(9600); // инициализация порта для ноута
showStartupMessage(); // сообщение приветствия
flag_b = 1; // запал
while (setNewCode() == false) { // установка пароля
}
// Serial.println(pass); // вывод установленного кода на компьютер
showWaitScreen(500);
// while (digitalRead((12)) != LOW) {
// lcd.home();
// lcd.print(F("TURN ON"));
// }
set_time();
delay(1000);
lcd.noBacklight(); // выключение подсветки дисплея
}
/*Считывание пароля с клавиатуры*/
String inputSecretCode() {
// lcd.clear();
lcd.setCursor(5, 1);
lcd.print(F("[____]"));
String result = "";
int i = 6;
while (result.length() < 4) {
lcd.setCursor(i, 1);
char key = keypad.getKey(); // считывание символа с клавиатуры
if (key >= '0' && key <= '9') {
i++;
tone(speaker_pin, 4000, 100);
lcd.print(key); //вывод в порт LCD
result += key;
// Serial.println(key); // вывод символа в порт экрана
}
}
return result;
}
/*Установка таймера*/
void set_time() {
lcd.clear();
lcd.setCursor(4,0);
lcd.print(F("[__:__]"));
lcd.createChar(3, v_smal);
lcd.createChar(4, d_smal);
lcd.createChar(5, yi_smal);
lcd.createChar(6, clock);
lcd.setCursor(0,1);
lcd.print(F("B\x03o\x04 Ta\x05mepa \x06")); // "Ввод таймера"
String time_str;
int i=5;
while (time_str.length() < 2) {
lcd.setCursor(i, 0);
char key = keypad.getKey(); // считывание символа с клавиатуры
if (key >= '0' && key <= '9') {
i++;
lcd.print(key); //вывод в порт LCD
time_str += key; // Запомнили минуты в строку
}
}
i++; //Перескакивание через двоеточие
while (time_str.length() < 4) {
lcd.setCursor(i, 0);
char key = keypad.getKey(); // считывание символа с клавиатуры
if (key >= '0' && key <= '9') {
i++;
lcd.print(key); //вывод в порт LCD
time_str += key; //Прибавили секунды в строку
}
}
// Serial.println(time_str); // вывод строки в порт экрана
minutes = (time_str[0] - '0') * 10 + (time_str[1] - '0'); //разбиение введенного числа на минуты и секунды
seconds = (time_str[2] - '0') * 10 + (time_str[3] - '0');
// Serial.println(minutes);
// Serial.println(seconds);
ConfirmTimer();
lcd.clear();
return time_str;
}
/*Проверка установленного таймера*/
void ConfirmTimer(){
if (minutes < 1 || seconds > 59){
lcd.createChar(1, sh_smal);
lcd.createChar(2, i_smal);
lcd.createChar(3, b_smal);
lcd.createChar(4, yi_smal);
lcd.clear();
lcd.print(F("O\x01\x02\x03ka Ta\x04mepa")); //"Ошибка Tаймера"
delay(2000);
set_time();
} else {
flag_t = 1;
get_time();
previousMillisCountDown = millis();
}
}
/*Вывод обратного отсчета в монитор LCD*/
void print_time(){
// lcd.clear();
lcd.setCursor(4,0); // установка положения
lcd.print(F("[__:__]"));
lcd.setCursor(5,0);
if (minutes < 10){
lcd.print(F("0"));
lcd.setCursor(6,0);
}
lcd.print(minutes); // вывод таймера на дисплей
lcd.setCursor(8,0);
if (seconds < 10){
lcd.print(F("0"));
lcd.setCursor(9,0);
}
lcd.print(seconds);
}
/*Обратный отсчет*/
void get_time(){
unsigned long currentMillis = millis(); //Переменной присваивается значение, прошедшее с запуска системы
if (currentMillis - previousMillisCountDown >= intervalCountDown) {
previousMillisCountDown += intervalCountDown; // for a clock-accurate millis timer
print_time();
seconds--; // уменьшение таймера на секунду
if (seconds < 0) {
seconds = 59;
minutes--;
}
if (minutes == 0 && seconds < 1) {
flag_t = 0;
flag_b = 0;
musik_unlook();
}
if (minutes == 0 && seconds <= 59) { //если минут 0 и секунд меньше 59
tone(speaker_pin, 3000, 100); //пищать! 3000-тон, 100-длительность
}
if (minutes <30 && seconds == 59) { //если меньше 30 минут
tone(speaker_pin, 3000, 500); //пищать!
}
}
}
/*Установка нового кода*/
bool setNewCode() { //Проверка и установка кода
lcd.backlight(); //Включение подсветки
lcd.createChar(1, v_smal);
lcd.createChar(2, d_smal);
lcd.createChar(3, P_big);
lcd.createChar(4, zh_smal);
lcd.createChar(5, t_smal);
lcd.createChar(6, n_smal);
lcd.createChar(7, i_smal);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("B\x01\x65\x02\x07\x05\x65 ko\x02:")); // "Введите код:"
delay(1000);
String newCode = inputSecretCode();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("\x03o\x02\x05\x01\x65p\x04\x02\x65\x06\x07\x65")); // "Подтверждение"
delay(1000);
String confirmCode = inputSecretCode();
if (newCode == confirmCode) {
pass = newCode;
flag = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Code sets")); // "Код активирован"
delay(2000);
lcd.clear();
lock();
return true;
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Code mismatch")); // "Код не совпал"
lcd.setCursor(0, 1);
lcd.print(F("Safe not locked!")); // "Не активировано"
delay(2000);
return false;
}
}
bool EntDefuseCode() { //Проверка кода
if (flag == 1) {
lcd.backlight();
lcd.createChar(1, v_smal);
lcd.createChar(2, d_smal);
lcd.createChar(3, P_big);
lcd.createChar(4, zh_smal);
lcd.createChar(5, t_smal);
lcd.createChar(6, n_smal);
lcd.createChar(7, i_smal);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("B\x01\x65\x02\x07\x05\x65 ko\x02:")); // "Введите код:"
delay(1000);
String newCode = inputSecretCode();
if (newCode == pass) {
showWaitScreen(500);
unlock();
delay(2000);
return true;
} else {
showWaitScreen(500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Code ERROR")); // Код НЕ ВЕРНЫЙ!
delay(2000);
lcd.clear();
lcd.noBacklight();
return false;
}
}else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Reload Game"));
delay(5000);
lcd.noBacklight();
}
}
void showWaitScreen(int delayMillis) { //Экран задержки проверки кода
lcd.setCursor(2, 1);
lcd.print(F("[..........]"));
lcd.setCursor(3, 1);
for (byte i = 0; i < 10; i++) {
delay(delayMillis);
lcd.print(F("*"));
}
}
void musik_unlook() {
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 174, 374.999625);
delay(416.66625);
tone(speaker_pin, 195, 124.999875);
delay(138.88875);
tone(speaker_pin, 220, 499.9995);
delay(555.555);
tone(speaker_pin, 146, 249.99975);
delay(277.7775);
tone(speaker_pin, 146, 249.99975);
delay(277.7775);
tone(speaker_pin, 195, 499.9995);
delay(555.555);
tone(speaker_pin, 174, 374.999625);
delay(416.66625);
tone(speaker_pin, 155, 124.999875);
delay(138.88875);
tone(speaker_pin, 174, 499.9995);
delay(555.555);
tone(speaker_pin, 116, 249.99975);
delay(277.7775);
tone(speaker_pin, 116, 249.99975);
delay(277.7775);
tone(speaker_pin, 130, 499.9995);
delay(555.555);
tone(speaker_pin, 130, 374.999625);
delay(416.66625);
tone(speaker_pin, 146, 124.999875);
delay(138.88875);
tone(speaker_pin, 155, 499.9995);
delay(555.555);
tone(speaker_pin, 155, 374.999625);
delay(416.66625);
tone(speaker_pin, 174, 124.999875);
delay(138.88875);
tone(speaker_pin, 195, 499.9995);
delay(555.555);
tone(speaker_pin, 220, 374.999625);
delay(416.66625);
tone(speaker_pin, 233, 124.999875);
delay(138.88875);
tone(speaker_pin, 261, 749.99925);
delay(833.3325);
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 293, 499.9995);
delay(555.555);
tone(speaker_pin, 261, 374.999625);
delay(416.66625);
tone(speaker_pin, 233, 124.999875);
delay(138.88875);
tone(speaker_pin, 261, 499.9995);
delay(555.555);
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 220, 374.999625);
delay(416.66625);
tone(speaker_pin, 195, 124.999875);
delay(138.88875);
tone(speaker_pin, 220, 499.9995);
delay(555.555);
tone(speaker_pin, 146, 374.999625);
delay(416.66625);
tone(speaker_pin, 146, 124.999875);
delay(138.88875);
tone(speaker_pin, 195, 499.9995);
delay(555.555);
tone(speaker_pin, 174, 374.999625);
delay(416.66625);
tone(speaker_pin, 155, 124.999875);
delay(138.88875);
tone(speaker_pin, 174, 499.9995);
delay(555.555);
tone(speaker_pin, 116, 374.999625);
delay(416.66625);
tone(speaker_pin, 116, 124.999875);
delay(138.88875);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 220, 374.999625);
delay(416.66625);
tone(speaker_pin, 195, 124.999875);
delay(138.88875);
tone(speaker_pin, 174, 999.999);
delay(1111.11);
tone(speaker_pin, 293, 999.999);
delay(1111.11);
tone(speaker_pin, 261, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 249.99975);
delay(277.7775);
tone(speaker_pin, 220, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 249.99975);
delay(277.7775);
tone(speaker_pin, 261, 749.99925);
delay(833.3325);
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 174, 999.999);
delay(1111.11);
tone(speaker_pin, 233, 999.999);
delay(1111.11);
tone(speaker_pin, 220, 249.99975);
delay(277.7775);
tone(speaker_pin, 195, 249.99975);
delay(277.7775);
tone(speaker_pin, 174, 249.99975);
delay(277.7775);
tone(speaker_pin, 195, 249.99975);
delay(277.7775);
tone(speaker_pin, 220, 749.99925);
delay(833.3325);
tone(speaker_pin, 146, 249.99975);
delay(277.7775);
tone(speaker_pin, 146, 999.999);
delay(1111.11);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 195, 374.999625);
delay(416.66625);
tone(speaker_pin, 220, 124.999875);
delay(138.88875);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 195, 374.999625);
delay(416.66625);
tone(speaker_pin, 220, 124.999875);
delay(138.88875);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 195, 374.999625);
delay(416.66625);
tone(speaker_pin, 233, 124.999875);
delay(138.88875);
tone(speaker_pin, 311, 999.999);
delay(1111.11);
tone(speaker_pin, 311, 999.999);
delay(1111.11);
tone(speaker_pin, 293, 249.99975);
delay(277.7775);
tone(speaker_pin, 261, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 249.99975);
delay(277.7775);
tone(speaker_pin, 261, 249.99975);
delay(277.7775);
tone(speaker_pin, 293, 749.99925);
delay(833.3325);
tone(speaker_pin, 233, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 999.999);
delay(1111.11);
tone(speaker_pin, 261, 999.999);
delay(1111.11);
tone(speaker_pin, 233, 249.99975);
delay(277.7775);
tone(speaker_pin, 220, 249.99975);
delay(277.7775);
tone(speaker_pin, 195, 249.99975);
delay(277.7775);
tone(speaker_pin, 220, 249.99975);
delay(277.7775);
tone(speaker_pin, 233, 749.99925);
delay(833.3325);
tone(speaker_pin, 195, 249.99975);
delay(277.7775);
tone(speaker_pin, 195, 999.999);
delay(1111.11);
tone(speaker_pin, 233, 499.9995);
delay(555.555);
tone(speaker_pin, 220, 374.999625);
delay(416.66625);
tone(speaker_pin, 195, 124.999875);
delay(138.88875);
tone(speaker_pin, 174, 499.9995);
delay(555.555);
tone(speaker_pin, 116, 374.999625);
delay(416.66625);
tone(speaker_pin, 116, 124.999875);
delay(138.88875);
tone(speaker_pin, 174, 999.999);
delay(1111.11);
tone(speaker_pin, 195, 499.9995);
delay(555.555);
tone(speaker_pin, 220, 499.9995);
delay(555.555);
tone(speaker_pin, 233, 1999.998);
delay(2222.22);
}
void defuse() {
tone(speaker_pin, 5000, 100);
delay(200);
tone(speaker_pin, 4000, 100);
delay(200);
tone(speaker_pin, 6000, 100);
delay(200);
}
void loop() {
char key = keypad.getKey();
if (key == '*') {
EntDefuseCode();
}
// if (key == 'C'){
// CustomChar();
// }
if (key == 'D' && flag == 0){
flag_b = 1; // запал
digitalWrite(led_g, LOW);
while (setNewCode() == false) { // установка пароля
}
//Serial.println(pass); // вывод установленного кода
showWaitScreen(500);
set_time();
lcd.noBacklight(); // выключение подсветки дисплея
}
if(flag_b == 1 && flag_t == 1){
get_time();
}
if(flag_b == 0 && flag_t == 1){
print_time();
}
if(flag_b == 0 && flag_t == 0){
print_time();
}
}