Безопасность является одной из основных проблем в современном обществе, и цифровые замки стали важной частью нынешних систем безопасности. Существует много типов систем безопасности, например, на основе датчиков движения, на основе радиочастотных меток, цифровых кодовых замков и т.д. В этом проекте мы рассмотрим подключение модуля датчика отпечатка пальцев к плате Arduino и создадим биометрическую систему безопасности c использованием Arduino и датчика отпечатков пальцев. Отпечаток пальца считается одним из самых безопасных способов для блокировки или разблокировки любой системы, поскольку он однозначно идентифицирует конкретного человека и его достаточно сложно скопировать.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- Модуль датчика отпечатков пальцев (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Серводвигатель (сервомотор) (купить на AliExpress).
- Кнопка (4 шт.)
- Светодиод (2 шт.) (купить на AliExpress).
- Резистор 1 кОм (3 шт.) (купить на AliExpress).
- Резистор 2,2 кОм (купить на AliExpress).
- Источник питания.
- Макетная плата.
- Соединительные провода.
- Картонная коробка.
Реклама: ООО «АЛИБАБА.КОМ (РУ)» ИНН: 7703380158
Модуль отпечатков пальцев и Arduino
Модуль отпечатков пальцев или сканер отпечатков пальцев — это модуль, который захватывает печатное изображение пальца, а затем преобразует его в эквивалентный шаблон и сохраняет их в своей памяти на выбранном идентификаторе (местоположении) с помощью Arduino. Весь процесс управляется платой Arduino: считывание изображения отпечатка пальца, конвертирование его в шаблоны, хранение местоположения и т.д.
В этом проекте биометрической системы безопасности на основе платы Arduino мы использовали модуль датчика отпечатков пальцев для получения отпечатков пальцев (или отпечатка большого пальца) в качестве входных данных в системе. Мы будем использовать 4 кнопки: регистрация/назад, удаление/OK, вверх и вниз. Каждая кнопка имеет двойные функции. Кнопка для регистрации (enroll) используется для регистрации нового отпечатка пальца в системе и возвращения назад. Когда пользователь хочет зарегистрировать новый палец, то ему нужно нажать клавишу enroll, а затем ЖК-дисплей запросит идентификатор или местоположение, где пользователь хочет сохранить отпечаток пальца. Но если в это время пользователь не хочет продолжать дальше, то он/она может снова нажать клавишу enroll, чтобы вернуться назад (то есть клавиша (кнопка) enroll в этой ситуации выполняет роль клавиши возврата). То есть кнопка enroll имеет как функцию регистрации, так и функцию возврата. Клавиша DEL/OK также имеет двойную функцию: когда пользователь регистрирует новый палец, то ему/ей нужно выбрать идентификатор пальца или местоположение, используя еще две клавиши, а именно UP/MATCH и DOWN/MATCH (которые также имеют двойные функции), после чего пользователю нужно нажать клавишу DEL/OK (на этот раз эта клавиша ведет себя как OK), чтобы продолжить с выбранным идентификатором или местоположением. Клавиши UP/DOWN также поддерживают функцию сопоставления отпечатков пальцев. Немного трудновато написано, но все станет ясно если вы посмотрите видео, приведенное в конце статьи – там все эти процессы показаны более подробно.
В этом проекте мы используем картонную коробку и сервомотор, которые работают как ворота (безопасности) и открываются только тогда, когда система считывает правильный отпечаток пальца. Желтый светодиод показывает, что ворота закрыты, а зеленый светодиод — что ворота открыты.
Объяснение работы проекта
Работа рассматриваемого нами дверного замка на основе датчика отпечатка пальцев достаточно проста. В этом проекте мы использовали ворота, которые будут открыты, когда мы помещаем сохраненный палец в модуль отпечатков пальцев. Но перед этим пользователю необходимо зарегистрировать палец в системе. Для этого пользователю необходимо нажать клавишу ENROLL, а затем ЖК-дисплей запросит у него местоположение/ID (идентификатор), где будет храниться отпечаток пальца. После этого пользователю необходимо ввести идентификатор/ (местоположение) с помощью клавиш UP/DOWN. После выбора Location (местоположения)/ID пользователю необходимо нажать клавишу OK. Теперь ЖК-дисплей попросит разместить палец над модулем отпечатков пальцев. После этого пользователю нужно положить свой палец на модуль отпечатков пальцев. Затем ЖК-дисплей попросит удалить палец из модуля отпечатков пальцев и снова попросит разместить палец. Теперь пользователю нужно снова положить палец на модуль отпечатков пальцев. После этого модуль отпечатков пальцев захватывает изображение пальца, преобразует его в шаблоны и сохраняет его по выбранному идентификатору в памяти модуля отпечатков пальцев. Теперь пользователь может открыть ворота, поместив тот же палец, который он добавил (зарегистрировал в системе). После помещения пальца в датчик отпечатков пальцев необходимо нажать кнопку MATCH (UP/Down key). Аналогичным способом можно добавить и другие отпечатки пальцев в систему. Более подробно все эти процессы показаны в видео в конце статьи.
Если пользователь хочет удалить любой из сохраненных идентификаторов, то ему нужно нажать клавишу DEL — после нажатия клавиши DEL ЖК-дисплей попросит выбрать местоположение/идентификатор, который необходимо удалить. После этого пользователю необходимо выбрать ID (идентификатор) и нажать клавишу OK (та же клавиша DEL). После завершения этого шага на ЖК дисплее высветится надпись о том, что палец (с выбранным идентификатором) был успешно из системы. После этого пользователь может проверить, был ли он (его палец) удален или нет, поместив тот же палец на модуль отпечатков пальцев и нажав клавишу MATCH (UP/Down key).
Когда помещенный палец будет действителен (зарегистрирован в системе), зеленый светодиод будет светиться в течение пяти секунд и ворота откроются на это же время. Через 5 секунд ворота закроются автоматически. Эти параметры (интервалы открытия и закрытия ворот) вы легко можете изменить в программе по своему желанию. Серводвигатель отвечает за открытие и закрытие ворот.
Работа схемы
Схема нашей биометрической системы безопасности на основе платы Arduino представлена на следующем рисунке. Плата Arduino управляет всеми процессами в схеме: считывает нажатия кнопок, отображает информацию на ЖК дисплее, принимает информацию от датчика отпечатков пальцев, дает команды сервомотору.
Примечание: здесь D14, D15, D16, D17 являются контактами A0, A1, A2, A3 соответственно.
Питание 5 В используется для питания модуля датчика отпечатков пальцев и оно берется с платы Arduino. Сервомотор подключен к цифровому контакту D5 платы Arduino, на котором можно задействовать широтно-импульсную модуляцию, с помощью которой и управляется сервомотор. ЖК дисплей подключен к плате Arduino в 4-битном режиме и его контакты RS, EN, D4, D5, D6 и D7 непосредственно соединены с цифровыми контактами D13, D12, D11, D10, D9 и D8 платы Arduino.
Объяснение работы программы
В программе мы использовали Adafruit Fingerprint Sensor Library для подключения модуля датчика отпечатков пальцев к плате Arduino. Полный код программы приведен в конце статьи, здесь же объяснены его наиболее важные части.
Следующий фрагмент кода используется для считывания отпечатка пальца и выполнение определенных действий в зависимости от результата проверки отпечатка пальца (есть ли он в системе или нет). Если отпечаток пальца корректен, то ворота открываются, иначе ничего не происходит.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
for(int i=0;i<5;i++) { lcd.clear(); lcd.print("Place Finger"); delay(2000); int result=getFingerprintIDez(); if(result>=0) { digitalWrite(openLight, HIGH); digitalWrite(closeLight, LOW); lcd.clear(); lcd.print("Allowed"); lcd.setCursor(0,1); lcd.print("Gete Opened "); myServo.write(0); delay(5000); myServo.write(180); digitalWrite(closeLight, HIGH); digitalWrite(openLight, LOW); lcd.setCursor(0,1); lcd.print("Gate Closed "); |
Функция void checkKeys() используется для проверки того, нажата ли кнопка Enroll или DEL. Если нажата кнопка ENROL (регистрация), то вызывается функция Enroll(), а если нажата кнопка DEL – то вызывается функция delet().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void checkKeys() { if(digitalRead(enroll) == 0) { lcd.clear(); lcd.print("Please Wait"); delay(1000); while(digitalRead(enroll) == 0); Enroll(); } else if(digitalRead(del) == 0) { lcd.clear(); lcd.print("Please Wait"); delay(1000); delet(); } } |
Функция delet() служит для ввода идентификатора (ID) пальца, который нужно удалить из системы, и для вызова функции uint8_t deleteFingerprint(uint8_t id), которая удаляет запись с выбранным идентификатором из системы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
void delet() { int count=0; lcd.clear(); lcd.print("Delete Finger "); lcd.setCursor(0,1); lcd.print("Location:"); while(1) { lcd.setCursor(9,1); lcd.print(count); if(digitalRead(up) == 0) { count++; if(count>25) count=0; delay(500); } .... ..... ..... ..... |
Функция uint8_t deleteFingerprint(uint8_t id) удаляет запись с выбранным идентификатором из системы.
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 |
uint8_t deleteFingerprint(uint8_t id) { uint8_t p = -1; lcd.clear(); lcd.print("Please wait"); p = finger.deleteModel(id); if (p == FINGERPRINT_OK) { Serial.println("Deleted!"); lcd.clear(); lcd.print("Figer Deleted"); lcd.setCursor(0,1); lcd.print("Successfully"); delay(1000); } else { Serial.print("Something Wrong"); lcd.clear(); lcd.print("Something Wrong"); lcd.setCursor(0,1); lcd.print("Try Again Later"); delay(2000); return p; } } |
Функция uint8_t getFingerprintEnroll() используется для считывания отпечатка пальца, конвертирования его в шаблон и сохранения его с выбранным идентификатором (ID) в память модуля датчика отпечатков пальцев.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
uint8_t getFingerprintEnroll() { int p = -1; lcd.clear(); lcd.print("finger ID:"); lcd.print(id); lcd.setCursor(0,1); lcd.print("Place Finger"); delay(2000); while (p != FINGERPRINT_OK) { p = finger.getImage(); ..... ..... ....... .... |
Исходный код программы
В этом разделе представлен полный код программы для рассмотренной нами биометрической системы безопасности на основе платы Arduino.
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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
#include<LiquidCrystal.h> // библиотека для работы с ЖК дисплеем LiquidCrystal lcd(13,12,11,10,9,8); // контакты к которым подключен ЖК дисплей #include <SoftwareSerial.h> // библиотека чтобы организовать последовательную связь SoftwareSerial fingerPrint(2, 3); // на контактах 2 и 3 #include<Servo.h> // библиотека для работы с сервомотором Servo myServo; // даем имя нашему сервомотору #include <Adafruit_Fingerprint.h> // библиотека для работы с модулем датчика отпечатков пальцев uint8_t id; Adafruit_Fingerprint finger = Adafruit_Fingerprint(&fingerPrint); #define enroll 14 #define del 15 #define up 16 #define down 17 #define openLight 6 #define closeLight 7 #define servoPin 5 void setup() { delay(1000); myServo.attach(servoPin); myServo.write(180); pinMode(enroll, INPUT_PULLUP); pinMode(up, INPUT_PULLUP); pinMode(down, INPUT_PULLUP); pinMode(del, INPUT_PULLUP); pinMode(openLight, OUTPUT); pinMode(closeLight, OUTPUT); lcd.begin(16,2); lcd.print("Security System"); lcd.setCursor(0,1); lcd.print("by Finger Print"); delay(2000); lcd.clear(); lcd.print("Circuit Digest"); lcd.setCursor(0,1); lcd.print("Saddam Khan"); delay(2000); finger.begin(57600); Serial.begin(9600); lcd.clear(); lcd.print("Finding Module"); lcd.setCursor(0,1); delay(1000); if (finger.verifyPassword()) { Serial.println("Found fingerprint sensor!"); // датчик отпечатков пальцев найден lcd.clear(); lcd.print("Found Module "); delay(1000); } else { Serial.println("Did not find fingerprint sensor :("); // датчик отпечатков пальцев не найден lcd.clear(); lcd.print("module not Found"); lcd.setCursor(0,1); lcd.print("Check Connections"); while (1); } } void loop() { lcd.setCursor(0,0); lcd.print("Press UP/Down "); lcd.setCursor(0,1); lcd.print("to start System"); digitalWrite(closeLight, HIGH); if(digitalRead(up)==0 || digitalRead(down)==0) { for(int i=0;i<5;i++) { lcd.clear(); lcd.print("Place Finger"); delay(2000); int result=getFingerprintIDez(); if(result>=0) { digitalWrite(openLight, HIGH); digitalWrite(closeLight, LOW); lcd.clear(); lcd.print("Allowed"); lcd.setCursor(0,1); lcd.print("Gete Opened "); myServo.write(0); delay(5000); myServo.write(180); digitalWrite(closeLight, HIGH); digitalWrite(openLight, LOW); lcd.setCursor(0,1); lcd.print("Gate Closed "); return; } } } checkKeys(); delay(1000); } void checkKeys() { if(digitalRead(enroll) == 0) { lcd.clear(); lcd.print("Please Wait"); delay(1000); while(digitalRead(enroll) == 0); Enroll(); } else if(digitalRead(del) == 0) { lcd.clear(); lcd.print("Please Wait"); delay(1000); delet(); } } void Enroll() { int count=0; lcd.clear(); lcd.print("Enroll Finger "); lcd.setCursor(0,1); lcd.print("Location:"); while(1) { lcd.setCursor(9,1); lcd.print(count); if(digitalRead(up) == 0) { count++; if(count>25) count=0; delay(500); } else if(digitalRead(down) == 0) { count--; if(count<0) count=25; delay(500); } else if(digitalRead(del) == 0) { id=count; getFingerprintEnroll(); return; } else if(digitalRead(enroll) == 0) { return; } } } void delet() { int count=0; lcd.clear(); lcd.print("Delete Finger "); lcd.setCursor(0,1); lcd.print("Location:"); while(1) { lcd.setCursor(9,1); lcd.print(count); if(digitalRead(up) == 0) { count++; if(count>25) count=0; delay(500); } else if(digitalRead(down) == 0) { count--; if(count<0) count=25; delay(500); } else if(digitalRead(del) == 0) { id=count; deleteFingerprint(id); return; } else if(digitalRead(enroll) == 0) { return; } } } uint8_t getFingerprintEnroll() { int p = -1; lcd.clear(); lcd.print("finger ID:"); lcd.print(id); lcd.setCursor(0,1); lcd.print("Place Finger"); delay(2000); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Image taken"); // изображение захвачено lcd.clear(); lcd.print("Image taken"); break; case FINGERPRINT_NOFINGER: Serial.println("No Finger"); // нет пальца lcd.clear(); lcd.print("No Finger"); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); // ошибка связи lcd.clear(); lcd.print("Comm Error"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); lcd.clear(); lcd.print("Imaging Error"); // ошибка изображения break; default: Serial.println("Unknown error"); lcd.clear(); lcd.print("Unknown Error"); // неизвестная ошибка break; } } // OK success! p = finger.image2Tz(1); switch (p) { case FINGERPRINT_OK: Serial.println("Image converted"); lcd.clear(); lcd.print("Image converted"); break; case FINGERPRINT_IMAGEMESS: Serial.println("Image too messy"); // изображение слишком “грязное” lcd.clear(); lcd.print("Image too messy"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); lcd.clear(); lcd.print("Comm Error"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Could not find fingerprint features"); lcd.clear(); lcd.print("Feature Not Found"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Could not find fingerprint features"); lcd.clear(); lcd.print("Feature Not Found"); return p; default: Serial.println("Unknown error"); lcd.clear(); lcd.print("Unknown Error"); return p; } Serial.println("Remove finger"); lcd.clear(); lcd.print("Remove Finger"); // снимите палец с датчика delay(2000); p = 0; while (p != FINGERPRINT_NOFINGER) { p = finger.getImage(); } Serial.print("ID "); Serial.println(id); p = -1; Serial.println("Place same finger again"); // поместите тот же самый палец lcd.clear(); lcd.print("Place Finger"); lcd.setCursor(0,1); lcd.print(" Again"); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Image taken"); // изображение захвачено break; case FINGERPRINT_NOFINGER: Serial.print("."); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); break; default: Serial.println("Unknown error"); return; } } // OK success! p = finger.image2Tz(2); switch (p) { case FINGERPRINT_OK: Serial.println("Image converted"); break; case FINGERPRINT_IMAGEMESS: Serial.println("Image too messy"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Could not find fingerprint features"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Could not find fingerprint features"); return p; default: Serial.println("Unknown error"); return p; } // OK converted! Serial.print("Creating model for #"); Serial.println(id); p = finger.createModel(); if (p == FINGERPRINT_OK) { Serial.println("Prints matched!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_ENROLLMISMATCH) { Serial.println("Fingerprints did not match"); return p; } else { Serial.println("Unknown error"); return p; } Serial.print("ID "); Serial.println(id); p = finger.storeModel(id); if (p == FINGERPRINT_OK) { Serial.println("Stored!"); lcd.clear(); lcd.print("Stored!"); delay(2000); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_BADLOCATION) { Serial.println("Could not store in that location"); return p; } else if (p == FINGERPRINT_FLASHERR) { Serial.println("Error writing to flash"); return p; } else { Serial.println("Unknown error"); return p; } } int getFingerprintIDez() { uint8_t p = finger.getImage(); if (p != FINGERPRINT_OK) return -1; p = finger.image2Tz(); if (p != FINGERPRINT_OK) return -1; p = finger.fingerFastSearch(); if (p != FINGERPRINT_OK) { lcd.clear(); lcd.print("Finger Not Found"); lcd.setCursor(0,1); lcd.print("Try Later"); delay(2000); return -1; } // found a match! Serial.print("Found ID #"); Serial.print(finger.fingerID); return finger.fingerID; } uint8_t deleteFingerprint(uint8_t id) { uint8_t p = -1; lcd.clear(); lcd.print("Please wait"); // пожалуйста подождите p = finger.deleteModel(id); if (p == FINGERPRINT_OK) { Serial.println("Deleted!"); lcd.clear(); lcd.print("Figer Deleted"); // палец удален lcd.setCursor(0,1); lcd.print("Successfully"); // успешно delay(1000); } else { Serial.print("Something Wrong"); // что то пошло не так lcd.clear(); lcd.print("Something Wrong"); lcd.setCursor(0,1); lcd.print("Try Again Later"); // попробуйте снова немного позже delay(2000); return p; } } |
2 ответа к “Биометрическая система безопасности c использованием Arduino и датчика отпечатков пальцев”
Есть ли у вас библиотека с компонентом самого сканера отпечатков пальцев для proteus?
К сожалению нет.