#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] =
{
{'1', '4', '7', '#'},
{'2', '5', '8', '0'},
{'3', '6', '9', '*'},
{'A', 'B', 'C', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {9, 8, 7, 6};
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
//Класс с глобальными переменными
class Global
{
private:
public:
int a = 0;
long MinDelay = 0;
char customKey = ' ';
int Setup = 0;
};
Global global;
//Класс Дисплея
class Screen
{
private:
public:
int SizeOfPinCode = 16;
int DisplaySize = 16;
void Display_Reset()
{
for (int i = 0; i < DisplaySize; i++)
{
lcd.setCursor(i, 1);
lcd.print(' ');
}
}
};
Screen screen;
//Класс Клавиатуры
class KeyPad
{
//Локальные переменные данного класса
private:
int in;
char CODE[16] = {'8', '3', '4', '0'};
char IN[16];
char NUM[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
//Публичные переменные и действия к которым можно обращаться
public:
const size_t n = sizeof(NUM) / sizeof(NUM[0]);
//Очистка Входного массива IN
void IN_Reset()
{
for (int i = 0; i < sizeof(IN); i++)
{
IN[i] = ' ';
}
}
void caseB_support(int status)
{
lcd.clear();
if (status == screen.SizeOfPinCode)
{
lcd.setCursor(3, 0);
lcd.print("Enter New");
lcd.setCursor(3, 1);
lcd.print("Password");
}
else if (status < screen.SizeOfPinCode)
{
lcd.setCursor(3, 0);
lcd.print("Enter Old");
lcd.setCursor(3, 1);
lcd.print("Password");
}
delay(3500);
lcd.clear();
IN_Reset();
Num_Mix(n);
global.a = 0;
}
//Функция Проверки пароля
int PinCheck()
{
int c = 0;
for (int i = 0; i < screen.SizeOfPinCode; i++)
{
if (IN[i] == CODE[i])
{
c++;
}
}
return c;
}
//Функция Перемешивания раскладки *далее Num_Mix
void Num_Mix(int nums)
{
for (size_t i = 0; i < nums; i++)
{
size_t j = random(0, nums);
char t = NUM[i];
NUM[i] = NUM[j];
NUM[j] = t;
}
for (int i = 0; i < 10; i++)
{
lcd.setCursor(0, 0);
lcd.print("Keys");
lcd.setCursor(i + 5, 0);
lcd.print(NUM[i]);
}
global.MinDelay = millis();
lcd.setCursor(0, 1);
}
//Функция проверки введённого пароля
void caseA()
{
if (global.Setup == 1)
{
if (PinCheck() == screen.SizeOfPinCode)
{
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Login");
lcd.setCursor(2, 1);
lcd.print("Successful");
}
else if (PinCheck() < screen.SizeOfPinCode)
{
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Access");
lcd.setCursor(5, 1);
lcd.print("Denied");
}
delay(3500);
lcd.clear();
IN_Reset();
Num_Mix(n);
global.a = 0;
}
else if (global.Setup == 2)
{
for (int i = 0; i < screen.SizeOfPinCode; i++)
{
CODE[i] = IN[i];
}
lcd.clear();
IN_Reset();
Num_Mix(n);
global.Setup = 1;
global.a = 0;
}
}
//Функция задавания пароля
void caseB()
{
PinCheck();
if (PinCheck() == screen.SizeOfPinCode)
{
caseB_support(PinCheck());
global.Setup = 2;
}
else if (PinCheck() < screen.SizeOfPinCode)
{
caseB_support(PinCheck());
}
}
//Функция стирания всех символов клавиатуры
void caseC()
{
lcd.clear();
global.a = 0;
IN_Reset();
Num_Mix(n);
}
//Функция стирания последнего символа
void caseD()
{
global.a--;
lcd.setCursor(global.a, 1);
lcd.print(' ');
}
// Ввод-Вывод данных
void caseDefault()
{
int in = global.customKey - ' ' - 16;
if (in == 0)
{
in = 10;
}
IN[global.a] = NUM[in - 1];
lcd.setCursor(global.a, 1);
lcd.print(IN[global.a]);
global.a++;
}
};
KeyPad Keypad;
//Класс Основной программы
class Prog
{
private:
public:
void Loop()
{
global.customKey = customKeypad.getKey();
if (global.customKey)
{
switch (global.customKey)
{
//Функция стирания последнего символа
case 'D':
Keypad.caseD();
break;
//Функция стирания всех символов клавиатуры
case 'C':
Keypad.caseC();
break;
//Функция проверки введённого пароля
case 'A':
Keypad.caseA();
break;
//Функция задавания пароля
case 'B':
Keypad.caseB();
break;
// ввод данных
default:
Keypad.caseDefault();
break;
}
//блок контроля координаты a
if (global.a == screen.DisplaySize)
{
global.a = 0;
screen.Display_Reset();
Keypad.IN_Reset();
}
if (global.a == -1)
{
global.a = 0;
}
}
//Блок Num_Mix каждые 60 секунд
if (millis() - global.MinDelay > 60000 && global.Setup == 1)
{
Keypad.Num_Mix(Keypad.n);
}
//Проверка инициализации
if (global.customKey && global.Setup == 0)
{
global.a = 0;
global.Setup = 1;
lcd.clear();
Keypad.Num_Mix(Keypad.n);
}
}
//Инициализация
void Init()
{
lcd.setCursor(5, 0);
lcd.print("Press");
lcd.setCursor(4, 1);
lcd.print("any key");
}
};
Prog prog;
//Инициализация
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.cursor();
prog.Init();
}
//Тело скрипта
void loop()
{
prog.Loop();
}