Кодовий замок: клавіатура 4×4, LCD і PIN-код
Мембранна клавіатура 4×4 займає лише 8 виводів завдяки матричному скануванню. Збираємо кодовий замок: введення PIN зі зірочками на LCD, «#» — підтвердити, «*» — стерти, світлодіод замість електромагнітного замка.
Про проєкт
16 кнопок — 16 виводів? Ні, достатньо восьми: кнопки мембранної клавіатури з'єднані в матрицю 4 рядки × 4 стовпці. Збираємо кодовий замок із виводом на LCD 1602 і «замком», який відкривається на 2 секунди після правильного PIN.
Що знадобиться
- ESP32 DevKit
- Мембранна клавіатура 4×4
- LCD 1602 з I2C-перехідником
- Світлодіод + резистор 220 Ом (у реальному проєкті — реле або MOSFET і електромагнітний замок)
- Бібліотеки Keypad і LiquidCrystal_I2C
Схема
| Клавіатура | R1 | R2 | R3 | R4 | C1 | C2 | C3 | C4 |
|---|---|---|---|---|---|---|---|---|
| ESP32 | GPIO19 | GPIO18 | GPIO5 | GPIO17 | GPIO16 | GPIO4 | GPIO13 | GPIO14 |
- LCD: VCC → 3V3, GND → GND, SDA → GPIO21, SCL → GPIO22.
- «Замок»: GPIO26 → 220 Ом → світлодіод → GND.
Шлейф клавіатури має 8 контактів: зліва направо (кнопками до себе) спершу чотири рядки, потім чотири стовпці.
Як сканується матриця
Бібліотека по черзі опускає в LOW один стовпець, а рядки читає з підтяжкою INPUT_PULLUP. Якщо рядок R2 прочитався як LOW, поки активний стовпець C3, натиснуто клавішу на перетині — «6». Весь цикл займає мікросекунди, тож для користувача це непомітно.
keypad.getKey() повертає символ один раз на натискання (антидребезг усередині) або 0, якщо нічого не натиснуто.
Код
// Кодовий замок: клавіатура 4×4 + LCD 1602, PIN 1234
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
const byte ROWS = 4, COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'},
};
byte rowPins[ROWS] = {19, 18, 5, 17};
byte colPins[COLS] = {16, 4, 13, 14};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int LOCK = 26;
const String PIN_CODE = "1234";
String entered;
void show() {
lcd.clear();
lcd.print("PIN: ");
for (unsigned int i = 0; i < entered.length(); i++) lcd.print('*'); // цифри не показуємо
}
void setup() {
lcd.init();
lcd.backlight();
pinMode(LOCK, OUTPUT);
show();
}
void loop() {
char k = keypad.getKey();
if (!k) return;
if (k == '#') { // підтвердити
lcd.clear();
if (entered == PIN_CODE) {
lcd.print("Access granted");
digitalWrite(LOCK, HIGH); // відкрити замок на 2 с
delay(2000);
digitalWrite(LOCK, LOW);
} else {
lcd.print("Wrong PIN");
delay(1500);
}
entered = "";
show();
} else if (k == '*') { // стерти
entered = "";
show();
} else if (entered.length() < 8) {
entered += k;
show();
}
}
Як зробити по-справжньому
- Замок. Електромагнітна засувка на 12 В бере 0.3–1 А: вмикайте її через MOSFET або реле, з діодом паралельно котушці.
- Захист від перебору. Після трьох помилок блокуйте введення на хвилину, а далі збільшуйте паузу вдвічі.
- PIN не в коді. Зберігайте його в
Preferences(флеш ESP32) і дайте можливість змінити: наприклад, «A» + старий PIN + новий PIN. - Живлення. Замок, що відкривається від будь-якого збою, — погана ідея. Подумайте, що станеться, якщо ESP32 перезавантажиться, коли вихід у HIGH.