Датчики отпечатков пальцев (Finger Print Sensor) в настоящее время находят все более широкое применение в жизнедеятельности современного общества. В данной статье мы рассмотрим подключение датчика отпечатка пальцев к плате Raspberry Pi. С помощью датчика отпечатков пальцев мы сможем регистрировать в нашей системе новые отпечатки пальцев и удалять уже существующие отпечатки пальцев. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
Ранее на нашем сайте мы уже рассматривали подключение датчика отпечатка пальцев к плате Arduino и к микроконтроллеру AVR.
Необходимые компоненты
- Плата Raspberry Pi (купить на AliExpress).
- ЖК дисплей 16x2 (купить на AliExpress).
- Конвертер USB в UART-порт (купить на AliExpress).
- Датчик отпечатков пальцев (купить на AliExpress).
- Кнопки.
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная или печатная плата.
- Соединительные провода.
- Светодиод (опционально) (купить на AliExpress).
- Резистор 150 Ом - 1 кОм (опционально) (купить на AliExpress).
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Схема проекта
В схеме нашего проекта мы будем использовать 4 кнопки:
- 1-я будет вносить в базу новый отпечаток пальца;
- 2-я будет удалять из базы существующий отпечаток пальца;
- 3-я и 4-я будут инкрементировать/декрементировать позицию среди существующих отпечатков пальцев (внесенных в систему).
Светодиод будет использоваться для индикации того, что датчик отпечатков пальцев готов считать новый отпечаток пальца. В нашем проекте мы будем использовать датчик отпечатков пальцев, который работает через UART (последовательный порт). Для того, чтобы подключить данный датчик к плате Raspberry Pi, мы будем использовать конвертер USB в последовательный порт. Внешний вид подобного конвертера представлен на следующем рисунке.
Схема подключения датчика отпечатка пальцев к плате Raspberry Pi представлена на следующем рисунке.
ЖК дисплей в схеме используется для отображения всех необходимых сообщений. Потенциометр 10 кОм используется для регулировки его контрастности. Контакты ЖК дисплея RS, EN, d4, d5, d6 и d7 подключены к контактам GPIO 18, 23, 24, 25, 8 и 7 платы Raspberry Pi соответственно. Четыре кнопки подключены к контактам GPIO 5, 6, 13 и 19 платы Raspberry Pi. Светодиод подключен к контакту 26 платы.
Внешний вид собранной на макетной плате конструкции проекта показан на следующем рисунке.
Установка библиотеки для работы с датчиком отпечатков пальцев
После того, как все соединения в схеме сделаны, откройте окно терминала на Raspberry Pi. Для установки библиотеки, позволяющей работать с датчиком отпечатков пальцев, выполните следующую последовательность шагов.
Шаг 1. Для установки данной библиотеки особые привилегии (root privileges). Чтобы получить доступ к данным привилегиям (войти в "корень" системы) используйте следующую команду:
1 |
sudo bash |
Шаг 2. Скачайте необходимые пакеты с помощью следующих команд.
1 2 |
wget –O – http://apt.pm-codeworks.de/pm-codeworks.de.gpg | apt-key add – wget http://apt.pm-codeworks.de/pm-codeworks.list%20-P%20/etc/apt/sources.list.d/ |
Шаг 3. После этого необходимо скачать последние обновления для Raspberry Pi установить скачанную библиотеку для работы с датчиком отпечатков пальцев.
1 2 |
sudo apt-get update sudo apt-get install python-fingerprint –yes |
Шаг 4. После установки библиотеки необходимо проверить USB порт, к которому в нашем проекте подключен датчик отпечатков пальцев.
1 |
ls /dev/ttyUSB* |
После этого вы должны изменить номер USB порта в программе (приведена ниже) на тот номер порта, который вы видите на экране в результате выполнения данной команды.
Принципы работы проекта
Запустите код программы для данного проекта на выполнение, после этого вы увидите на экране ЖК дисплея приветственное сообщение, после чего система попросит вас приложить палец к датчику отпечатков пальцев. Приложив палец к датчику, мы можем убедиться в том сохранен ли уже наш отпечаток пальца в системе или нет. Если наш отпечаток пальца уже сохранен в системе, то на экране ЖК дисплея высветится сообщение с позицией отпечатка в системе, например, ‘Fount at Pos:2’. Если же отпечаток пальца не найден в системе, то высветится сообщение ‘No Match Found’ (соответствия не найдено).
Чтобы внести отпечаток пальца в систему пользователю необходимо нажать кнопку enroll и следовать инструкциям, которые он увидит на ЖК дисплее.
Если пользователю необходимо удалить какой-нибудь отпечаток пальца из системы, он должен нажать кнопку delete. После этого на ЖК дисплее высветится сообщение с запросом позиции отпечатка пальцев, который необходимо удалить. Используя две остальные кнопки проекта, пользователь может выбрать позицию отпечатка пальцев, который необходимо удалить, после этого он должен нажать кнопку enroll (то есть в данном случае кнопка enroll работает как кнопка Ok). Более подробно работу проекта вы можете посмотреть на видео, представленном в конце статьи.
Структурная схема работы проекта показана на следующем рисунке.
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Если вы будете использовать готовые функции библиотеки, то работа с датчиком отпечатков пальцев станет достаточно простой. Но если вы будете подключать его в программе самостоятельно, то это может быть немного затруднительно в первый раз – вся информация, необходимая для этого, содержится в даташите на датчик отпечатков пальцев. Также вы можете использовать этот код с репозитория GitHub, чтобы протестировать работу вашей платы Raspberry Pi с датчиком отпечатков пальцев.
В программе нам первым делом необходимо подключить (импортировать) используемые библиотеки (fingerprint, GPIO и time) и объявить используемые контакты.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import time from pyfingerprint.pyfingerprint import PyFingerprint import RPi.GPIO as gpio RS =18 EN =23 D4 =24 D5 =25 D6 =8 D7 =7 enrol=5 delet=6 inc=13 dec=19 led=26 HIGH=1 LOW=0 |
После этого необходимо задать направление работы для используемых контактов – на ввод или вывод данных.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
gpio.setwarnings(False) gpio.setmode(gpio.BCM) gpio.setup(RS, gpio.OUT) gpio.setup(EN, gpio.OUT) gpio.setup(D4, gpio.OUT) gpio.setup(D5, gpio.OUT) gpio.setup(D6, gpio.OUT) gpio.setup(D7, gpio.OUT) gpio.setup(enrol, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(delet, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(inc, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(dec, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(led, gpio.OUT) |
Затем мы инициализируем датчик отпечатков пальцев.
1 2 3 4 5 6 7 |
try: f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000) if ( f.verifyPassword() == False ): raise ValueError('The given fingerprint sensor password is wrong!') except Exception as e: print('Exception message: ' + str(e)) exit(1) |
Далее мы запрограммируем ряд функций для работы с ЖК дисплеем. Их коды приведены ниже, в полном тексте программы.
1 |
def begin(), def lcdcmd(ch), def lcdwrite(ch), def lcdprint(Str), def setCursor(x,y) |
После этого мы запрограммируем функции для добавления нового отпечатка пальца, поиска отпечатка и удаления отпечатка:
- def enrollFinger() – используется для добавления (сохранения) нового отпечатка пальца в систему;
- def searchFinger() – используется для поиска сохраненных ранее отпечатков пальцев;
- def deleteFinger() – используется для удаления выбранного отпечатка пальца.
Далее, в бесконечном цикле мы будем формировать запрос (приглашение) пользователю чтобы он приложил свой палец к датчику отпечатков пальцев. После этого мы будем проверять отпечаток пальца на корректность (то есть присутствует ли он уже в системе) и выводить на экран дисплея результат этой проверки.
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 |
begin() lcdcmd(0x01) lcdprint("FingerPrint ") lcdcmd(0xc0) lcdprint("Interfacing ") time.sleep(3) lcdcmd(0x01) lcdprint("Circuit Digest") lcdcmd(0xc0) lcdprint("Welcomes You ") time.sleep(3) flag=0 lcdclear() while 1: gpio.output(led, HIGH) lcdcmd(1) lcdprint("Place Finger") if gpio.input(enrol) == 0: gpio.output(led, LOW) enrollFinger() elif gpio.input(delet) == 0: gpio.output(led, LOW) while gpio.input(delet) == 0: time.sleep(0.1) deleteFinger() else: searchFinger() |
Исходный код программы на Python
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 |
import time from pyfingerprint.pyfingerprint import PyFingerprint import RPi.GPIO as gpio RS =18 EN =23 D4 =24 D5 =25 D6 =8 D7 =7 enrol=5 delet=6 inc=13 dec=19 led=26 HIGH=1 LOW=0 gpio.setwarnings(False) gpio.setmode(gpio.BCM) gpio.setup(RS, gpio.OUT) gpio.setup(EN, gpio.OUT) gpio.setup(D4, gpio.OUT) gpio.setup(D5, gpio.OUT) gpio.setup(D6, gpio.OUT) gpio.setup(D7, gpio.OUT) gpio.setup(enrol, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(delet, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(inc, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(dec, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.setup(led, gpio.OUT) try: f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000) if ( f.verifyPassword() == False ): raise ValueError('The given fingerprint sensor password is wrong!') except Exception as e: print('Exception message: ' + str(e)) exit(1) def begin(): lcdcmd(0x33) lcdcmd(0x32) lcdcmd(0x06) lcdcmd(0x0C) lcdcmd(0x28) lcdcmd(0x01) time.sleep(0.0005) def lcdcmd(ch): gpio.output(RS, 0) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) if ch&0x20==0x20: gpio.output(D5, 1) if ch&0x40==0x40: gpio.output(D6, 1) if ch&0x80==0x80: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) # Low bits gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x01==0x01: gpio.output(D4, 1) if ch&0x02==0x02: gpio.output(D5, 1) if ch&0x04==0x04: gpio.output(D6, 1) if ch&0x08==0x08: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) def lcdwrite(ch): gpio.output(RS, 1) gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x10==0x10: gpio.output(D4, 1) if ch&0x20==0x20: gpio.output(D5, 1) if ch&0x40==0x40: gpio.output(D6, 1) if ch&0x80==0x80: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) # Low bits gpio.output(D4, 0) gpio.output(D5, 0) gpio.output(D6, 0) gpio.output(D7, 0) if ch&0x01==0x01: gpio.output(D4, 1) if ch&0x02==0x02: gpio.output(D5, 1) if ch&0x04==0x04: gpio.output(D6, 1) if ch&0x08==0x08: gpio.output(D7, 1) gpio.output(EN, 1) time.sleep(0.005) gpio.output(EN, 0) def lcdclear(): lcdcmd(0x01) def lcdprint(Str): l=0; l=len(Str) for i in range(l): lcdwrite(ord(Str[i])) def setCursor(x,y): if y == 0: n=128+x elif y == 1: n=192+x lcdcmd(n) def enrollFinger(): lcdcmd(1) lcdprint("Enrolling Finger") time.sleep(2) print('Waiting for finger...') lcdcmd(1) lcdprint("Place Finger") while ( f.readImage() == False ): pass f.convertImage(0x01) result = f.searchTemplate() positionNumber = result[0] if ( positionNumber >= 0 ): print('Template already exists at position #' + str(positionNumber)) lcdcmd(1) lcdprint("Finger ALready") lcdcmd(192) lcdprint(" Exists ") time.sleep(2) return print('Remove finger...') lcdcmd(1) lcdprint("Remove Finger") time.sleep(2) print('Waiting for same finger again...') lcdcmd(1) lcdprint("Place Finger") lcdcmd(192) lcdprint(" Again ") while ( f.readImage() == False ): pass f.convertImage(0x02) if ( f.compareCharacteristics() == 0 ): print "Fingers do not match" lcdcmd(1) lcdprint("Finger Did not") lcdcmd(192) lcdprint(" Mactched ") time.sleep(2) return f.createTemplate() positionNumber = f.storeTemplate() print('Finger enrolled successfully!') lcdcmd(1) lcdprint("Stored at Pos:") lcdprint(str(positionNumber)) lcdcmd(192) lcdprint("successfully") print('New template position #' + str(positionNumber)) time.sleep(2) def searchFinger(): try: print('Waiting for finger...') while( f.readImage() == False ): #pass time.sleep(.5) return f.convertImage(0x01) result = f.searchTemplate() positionNumber = result[0] accuracyScore = result[1] if positionNumber == -1 : print('No match found!') lcdcmd(1) lcdprint("No Match Found") time.sleep(2) return else: print('Found template at position #' + str(positionNumber)) lcdcmd(1) lcdprint("Found at Pos:") lcdprint(str(positionNumber)) time.sleep(2) except Exception as e: print('Operation failed!') print('Exception message: ' + str(e)) exit(1) def deleteFinger(): positionNumber = 0 count=0 lcdcmd(1) lcdprint("Delete Finger") lcdcmd(192) lcdprint("Position: ") lcdcmd(0xca) lcdprint(str(count)) while gpio.input(enrol) == True: # здесь кнопка enrol работает как кнопка ok if gpio.input(inc) == False: count=count+1 if count>1000: count=1000 lcdcmd(0xca) lcdprint(str(count)) time.sleep(0.2) elif gpio.input(dec) == False: count=count-1 if count<0: count=0 lcdcmd(0xca) lcdprint(str(count)) time.sleep(0.2) positionNumber=count if f.deleteTemplate(positionNumber) == True : print('Template deleted!') lcdcmd(1) lcdprint("Finger Deleted"); time.sleep(2) begin() lcdcmd(0x01) lcdprint("FingerPrint ") lcdcmd(0xc0) lcdprint("Interfacing ") time.sleep(3) lcdcmd(0x01) lcdprint("Circuit Digest") lcdcmd(0xc0) lcdprint("Welcomes You ") time.sleep(3) flag=0 lcdclear() while 1: gpio.output(led, HIGH) lcdcmd(1) lcdprint("Place Finger") if gpio.input(enrol) == 0: gpio.output(led, LOW) enrollFinger() elif gpio.input(delet) == 0: gpio.output(led, LOW) while gpio.input(delet) == 0: time.sleep(0.1) deleteFinger() else: searchFinger() |
Добрый день. А каким образом можно будет реализовать функцию отправки данных в базу данных? чтобы дальше использовать отпечаток.
Здравствуйте, ну здесь многое зависит от того какую базу данных вы хотите использовать. На основе mySQL или какой то специализированный интернет сервис для хранения данных?
К примеру, на нашем сайте есть статья про веб-сервер на Raspberry Pi с хостингом сайта на WordPress, в ней рассматривается установка сервера MySQL. Вам что то подобное нужно или нет?