Безопасность играет важную роль в жизни современного общества, а цифровые кодовые замки являются важным элементом различных систем безопасности. Один из примеров реализации подобного цифрового кодового замка на плате Arduino и матричной клавишной панели мы рассмотрим в этой статье.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Модуль клавиатуры (матричная клавишная панель).
- Зуммер (звонок) (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Транзистор BC547 (купить на AliExpress).
- Резистор 1 кОм (купить на AliExpress).
- Макетная плата.
- Источник питания.
- Соединительные провода.
В представленном проекте мы будем использовать технологию мультиплексирования для подключения клавиатуры (с помощью которой и будет вводиться пароль) к плате Arduino Uno. Мы будем использовать клавиатуру 4х4 которая содержит 16 кнопок (клавиш). В обычном режиме для подключения 16 кнопок к плате Arduino нам бы понадобилось 16 контактов, но с использованием технологии мультиплексирования нам будет достаточно 8 контактов для подключения 16 кнопок. Более подробно об этом можно прочитать в статье про подключение клавишной панели к Arduino.
Технология мультиплексирования является простым и эффективным способом уменьшения числа используемых контактов микроконтроллера при взаимодействии с большим числом кнопок (клавиш). В основном в этой технологии используется два простых приема: сначала сканируются строки, а потом сканируются столбцы. Но поскольку в Arduino мы используем специальную библиотеку для работы с клавиатурой, используя технологию мультиплексирования, нам нет необходимости писать специальный код для реализации этой технологии, по сравнению, например, с подключением клавишной панели к микроконтроллеру AVR.
Схема устройства
Схема устройства представлена на следующем рисунке и содержит в своем составе Arduino, модуль клавиатуры, буззер (звонок) и ЖК дисплей. Плата Arduino управляет всеми процессами работы схемы: считывание пароля с модуля клавиатуры, сравнение паролей, включение/выключение буззера и передача статуса на ЖК дсиплей. Клавиатура используется для ввода пароля. Буззер используется для индикации, а ЖК дисплей используется для отображения статуса операции и различных сообщений. Буззер управляется с помощью NPN транзистора.
Столбцы модуля клавиатуры непосредственно подключены к контактам 4, 5, 6, 7, а строки – к контактам 3, 2, 1, 0 платы arduino uno. ЖК дисплей подключен к плате Arduino в 4-битном режиме. Управляющие контакты RS, RW и En подключены к контактам Arduino 13, GND и 12. Контакты данных ЖК дисплея D4-D7 подключены к контактам 11, 10, 9 и 8 arduino. Буззер подключен к контакту 14(A1) arduino с помощью NPN транзистора BC547.
Работа схемы
В нашем проекте мы будем использовать встроенную в плату Arduino память EEPROM для хранения пароля. Поэтому когда мы будем подавать питание на нашу схему первым делом программа будет считывать остаточные данные из памяти EEPROM, сравнивать их с введенным паролем и выдавать сообщение на ЖК дисплей что доступ запрещен (Access Denied) потому что пароли не совпадают. Для устранения этой проблемы нам необходимо установить пароль по умолчанию (default password) на первый раз (начальное включение) с помощью следующего кода:
1 2 3 4 5 6 |
for(int j=0;j<4;j++) EEPROM.write(j, j+49); lcd.print("Enter Ur Passkey:"); lcd.setCursor(0,1); for(int j=0;j<4;j++) pass[j]=EEPROM.read(j); |
Этот код установит пароль “1234” в EEPROM платы Arduino.
После первого запуска нам необходимо удалить этот код из программы и снова записать код в Arduino и запустить программу на выполнение. Теперь наша система запустится без ошибок. Для второго запуска теперь у нас будет пароль “1234”. Теперь вы можете изменить его при помощи нажатия клавиши #, после этого вам будет нужно ввести текущий пароль, а потом ввести новый пароль.
В дальнейшем, когда вы будете вводить ваш пароль, система будет сравнивать введенный пароль с паролем, который хранится в памяти EEPROM платы arduino. Если пароли совпадают, то на ЖК дисплей выдается сообщение “access granted” (доступ разрешен), а если пароль неправильный, на ЖК дисплей выдается сообщение “Access Denied” (доступ запрещен) и буззер будет выдавать звуковой сигнал некоторое время. Также буззер будет выдавать одиночный (короткий) звуковой сигнал всегда когда вы будете нажимать какую-нибудь клавишу на клавиатуре.
Исходный код программы
В программе мы будем использовать специальную библиотеку для подключения клавиатуры (клавишной панели) к arduino.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include <Keypad.h> #include<LiquidCrystal.h> #include<EEPROM.h> const byte ROWS = 4; //четыре строки const byte COLS = 4; //четыре столбца char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {3, 2, 1, 0}; // подключение к контактам строк клавиатуры byte colPins[COLS] = {4, 5, 6, 7}; // подключение к контактам столбцов клавиатуры //инициализация переменных класса NewKeypad Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); |
Мы подключили библиотеку для работы с ЖК дисплеем (LiquidCrystal.h), библиотеку для работы с клавиатурой (Keypad.h) и библиотеку для работы с памятью EEPROM (EEPROM.h) и затем инициализировали необходимые для работы переменные и контакты.
1 2 3 4 5 6 |
#define buzzer 15 LiquidCrystal lcd(13,12,11,10,9,8); char password[4]; char pass[4],pass1[4]; int i=0; char customKey=0; |
Затем мы инициализировали ЖК дисплей и задали направление работы нужных нам контактов в функции setup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void setup() { lcd.begin(16,2); pinMode(led, OUTPUT); pinMode(buzzer, OUTPUT); pinMode(m11, OUTPUT); pinMode(m12, OUTPUT); lcd.print(" Electronic "); lcd.setCursor(0,1); lcd.print(" Keypad Lock "); delay(2000); lcd.clear(); lcd.print("Enter Ur Passkey:"); lcd.setCursor(0,1); |
После этого мы будем считывать значения с клавиатуры в функции loop.
1 2 3 4 5 6 7 8 9 |
customKey = customKeypad.getKey(); if(customKey=='#') change(); if (customKey) { password[i++]=customKey; lcd.print(customKey); beep(); } |
А затем мы сравниваем введенный пароль с сохраненным паролем используя метод сравнения строк.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
if(i==4) { delay(200); for(int j=0;j<4;j++) pass[j]=EEPROM.read(j); if(!(strncmp(password, pass,4))) { digitalWrite(led, HIGH); beep(); lcd.clear(); lcd.print("Passkey Accepted"); delay(2000); lcd.setCursor(0,1); lcd.print("#.Change Passkey"); delay(2000); lcd.clear(); lcd.print("Enter Passkey:"); lcd.setCursor(0,1); i=0; digitalWrite(led, LOW); } |
Далее в следующем участке кода представлена функция для смены пароля и функция активации буззера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void change() { int j=0; lcd.clear(); lcd.print("UR Current Passk"); lcd.setCursor(0,1); while(j<4) { char key=customKeypad.getKey(); if(key) { pass1[j++]=key; lcd.print(key); void beep() { digitalWrite(buzzer, HIGH); delay(20); digitalWrite(buzzer, LOW); } |
Далее представлен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
#include <Keypad.h> #include<LiquidCrystal.h> #include<EEPROM.h> #define buzzer 15 LiquidCrystal lcd(13,12,11,10,9,8); char password[4]; char pass[4],pass1[4]; int i=0; char customKey=0; const byte ROWS = 4; //four rows const byte COLS = 4; //four columns char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad byte colPins[COLS] = {4, 5, 6, 7}; //connect to the column pinouts of the keypad //initialize an instance of class NewKeypad Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); void setup() { lcd.begin(16,2); pinMode(led, OUTPUT); pinMode(buzzer, OUTPUT); pinMode(m11, OUTPUT); pinMode(m12, OUTPUT); lcd.print(" Electronic "); lcd.setCursor(0,1); lcd.print(" Keypad Lock "); delay(2000); lcd.clear(); lcd.print("Enter Ur Passkey:"); lcd.setCursor(0,1); for(int j=0;j<4;j++) EEPROM.write(j, j+49); for(int j=0;j<4;j++) pass[j]=EEPROM.read(j); } void loop() { customKey = customKeypad.getKey(); if(customKey=='#') change(); if (customKey) { password[i++]=customKey; lcd.print(customKey); beep(); } if(i==4) { delay(200); for(int j=0;j<4;j++) pass[j]=EEPROM.read(j); if(!(strncmp(password, pass,4))) { digitalWrite(led, HIGH); beep(); lcd.clear(); lcd.print("Passkey Accepted"); delay(2000); lcd.setCursor(0,1); lcd.print("#.Change Passkey"); delay(2000); lcd.clear(); lcd.print("Enter Passkey:"); lcd.setCursor(0,1); i=0; digitalWrite(led, LOW); } else { digitalWrite(buzzer, HIGH); lcd.clear(); lcd.print("Access Denied..."); lcd.setCursor(0,1); lcd.print("#.Change Passkey"); delay(2000); lcd.clear(); lcd.print("Enter Passkey:"); lcd.setCursor(0,1); i=0; digitalWrite(buzzer, LOW); } } } void change() { int j=0; lcd.clear(); lcd.print("UR Current Passk"); lcd.setCursor(0,1); while(j<4) { char key=customKeypad.getKey(); if(key) { pass1[j++]=key; lcd.print(key); beep(); } key=0; } delay(500); if((strncmp(pass1, pass, 4))) { lcd.clear(); lcd.print("Wrong Passkey..."); lcd.setCursor(0,1); lcd.print("Better Luck Again"); delay(1000); } else { j=0; lcd.clear(); lcd.print("Enter New Passk:"); lcd.setCursor(0,1); while(j<4) { char key=customKeypad.getKey(); if(key) { pass[j]=key; lcd.print(key); EEPROM.write(j,key); j++; beep(); } } lcd.print(" Done......"); delay(1000); } lcd.clear(); lcd.print("Enter Ur Passk:"); lcd.setCursor(0,1); customKey=0; } void beep() { digitalWrite(buzzer, HIGH); delay(20); digitalWrite(buzzer, LOW); } |