В этом уроке мы узнаем о подключении емкостного датчика отпечатков пальцев R502/R503 к плате Arduino. Модуль датчика отпечатков пальцев захватывает, сохраняет и сопоставляет отпечатки пальцев пользователя. Обычно он используется для предоставления пользователям контроля доступа или для определения их присутствия.
На рынке доступно множество датчиков отпечатков пальцев и мы использовали оптические датчики отпечатков пальцев R305/R307 в некоторых более ранних проектах, таких как система учета рабочего времени и биометрическая система безопасности. Мы также использовали усовершенствованный датчик отпечатков пальцев GT511C3, который имеет высокую точность и более быстрое время отклика. Вместо оптического метода он использует метод обработки изображения камеры для обнаружения отпечатков пальцев.
В этой статье мы рассмотрим детали и характеристики емкостного датчика отпечатков пальцев R502/R503 и узнаем, как работает емкостный датчик отпечатков пальцев. Кроме того, мы подключим емкостный датчик отпечатков пальцев R502/R503 к плате Arduino с помощью библиотеки Adafruit, а затем изучим метод регистрации и тестирования отпечатков пальцев.
Необходимые компоненты
- Плата Arduino Nano (купить на AliExpress).
- Датчик отпечатков пальцев R502/R503 (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Как работает емкостный сканер отпечатков пальцев?
Емкостный датчик отпечатков пальцев работает по другому алгоритму чем оптические датчики отпечатков пальцев. Вместо создания традиционного изображения отпечатка пальца емкостные сканеры отпечатков пальцев используют массивы крошечных конденсаторных схем для сбора данных.
Поскольку конденсаторы хранят электрический заряд, подключение их к проводящим пластинам на поверхности сканера позволяет использовать их для отслеживания деталей отпечатка пальца. Сохраненный заряд будет немного меняться, когда гребень пальца будет помещен на проводящие пластины. И наоборот, воздушный зазор оставит заряд на конденсаторе относительно неизменным. Для отслеживания этих изменений используется схема интегратора на операционном усилителе, которая затем может быть записана аналого-цифровым преобразователем.
После захвата эти цифровые данные анализируются для поиска отличительных и уникальных атрибутов отпечатков пальцев. Затем их можно сохранить для сравнения в более позднее время.
Емкостный сканер отпечатков пальцев R502/R503
R502/R503 — самый популярный и недорогой емкостный датчик отпечатков пальцев, доступный на рынке. Чип разработан путем интеграции сбора изображений и алгоритмических чипов. Самое лучшее в R502/R503 — это то, что он гибко адаптируется к состоянию пальцев, будь то сухие пальцы, влажные, легкие или старые пальцы с высокой скоростью распознавания. Разница между R502 и R503 заключается в том, что R502 тоньше и меньше по сравнению с R503.
Датчик отпечатков пальцев работает при напряжении 3,3 В и потребляет ток 18 мА во время считывания отпечатков пальцев и средний ток в режиме ожидания 2 мкА. Он использует интерфейс RS232 UART и обменивается данными со скоростью передачи данных по умолчанию 57600 бит/с. Он может хранить максимум 200 отпечатков пальцев. Модуль отпечатков пальцев R502/R503 поддерживает Arduino, Android, Windows и Linux. Для получения дополнительной информации вы можете обратиться к техническому описанию R502/R503.
Характеристики датчика
- Интерфейс: RS232 (ТТЛ).
- Разрешение: 508 точек на дюйм.
- Напряжение: 3,3 В постоянного тока.
- Рабочий ток (считывание отпечатков пальцев): 18 мА.
- Ток в режиме ожидания (обнаружение отпечатков пальцев): Типичное напряжение в режиме ожидания касания: 3,3 В, Средний ток: 2 мкА.
- Емкость отпечатков пальцев: 200.
- Сенсорная матрица: 192*192 пикселей.
- Цвет светодиода: синий и красный.
- Скорость сканирования: < 0,2 секунды.
- Скорость проверки: < 0,3 секунды.
- Метод сопоставления: 1:1; 1:N.
- FRR (коэффициент ложного отклонения): ≤0,01%.
- FAR (коэффициент ложного принятия): ≤0,00001%.
- Скорость передачи данных (UART): (9600 × N) бит/с, где N = 1 ~ 12 (по умолчанию N = 6, т.е. 57600 бит/с).
Распиновка R502/R503
Всего имеется 6 проводов, основная распиновка датчика отпечатков пальцев R502/R503 выглядит следующим образом.
Взаимодействие емкостного датчика отпечатков пальцев R502/R503 с Arduino
Схема подключения емкостного датчика отпечатков пальцев R502/R503 к плате Arduino представлена на следующем рисунке.
Датчик отпечатков пальцев — это модуль UART. Подключите контакты VCC и GND R502/R503 к контактам Arduino 3.3V и GND. Аналогично подключите Tx (желтый провод) и Rx (зеленый провод) к D2 и D3 Arduino соответственно. Синий провод — это провод прерывания, который остается неподключенным. Белый провод подключите к 3.3V.
Модуль сканера отпечатков пальцев можно подключить напрямую к плате Arduino с помощью перемычек.
Исходный код программы
Для емкостного датчика отпечатков пальцев R502/R503 от Adafruit доступна библиотека Arduino. Вы можете загрузить библиотеку датчика отпечатков пальцев Adafruit из репозитория Github.
Существует два отдельных кода для регистрации и считывания данных отпечатков пальцев. Код регистрации сохранит данные отпечатков пальцев в памяти EEPROM. В то время как код считывания отпечатков пальцев считывает отпечаток пальца, сохраненный в памяти EEPROM, и сопоставляет его со сканированным.
Код регистрации
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 |
#include <Adafruit_Fingerprint.h> #if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__) // For UNO and others without hardware serial, we must use software serial... // pin #2 is IN from sensor (GREEN wire) // pin #3 is OUT from arduino (WHITE wire) // Set up the serial port to use softwareserial.. SoftwareSerial mySerial(2, 3); #else // On Leonardo/M0/etc, others with hardware serial, use hardware serial! // #0 is green wire, #1 is white #define mySerial Serial1 #endif Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); uint8_t id; void setup() { Serial.begin(9600); while (!Serial); // For Yun/Leo/Micro/Zero/... delay(100); Serial.println("\n\nAdafruit Fingerprint sensor enrollment"); // set the data rate for the sensor serial port finger.begin(57600); if (finger.verifyPassword()) { Serial.println("Found fingerprint sensor!"); } else { Serial.println("Did not find fingerprint sensor :("); while (1) { delay(1); } } Serial.println(F("Reading sensor parameters")); finger.getParameters(); Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX); Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX); Serial.print(F("Capacity: ")); Serial.println(finger.capacity); Serial.print(F("Security level: ")); Serial.println(finger.security_level); Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX); Serial.print(F("Packet len: ")); Serial.println(finger.packet_len); Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate); } uint8_t readnumber(void) { uint8_t num = 0; while (num == 0) { while (! Serial.available()); num = Serial.parseInt(); } return num; } void loop() // run over and over again { Serial.println("Ready to enroll a fingerprint!"); Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as..."); id = readnumber(); if (id == 0) {// ID #0 not allowed, try again! return; } Serial.print("Enrolling ID #"); Serial.println(id); while (! getFingerprintEnroll() ); } uint8_t getFingerprintEnroll() { int p = -1; Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Image taken"); break; case FINGERPRINT_NOFINGER: Serial.println("."); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); break; default: Serial.println("Unknown error"); break; } } // OK success! p = finger.image2Tz(1); 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; } Serial.println("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"); 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"); break; } } // 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!"); } 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; } return true; } |
После загрузки кода откройте Serial Monitor (окно монитора последовательной связи). Монитор попросит вас ввести идентификатор отпечатка пальца, который находится в диапазоне от 1 до 127.
Теперь введите номер 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 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 |
#include <Adafruit_Fingerprint.h> int u=0; int relay=5; #if (defined(__AVR__) || defined(ESP8266)) && !defined(__AVR_ATmega2560__) // For UNO and others without hardware serial, we must use software serial... // pin #2 is IN from sensor (GREEN wire) // pin #3 is OUT from arduino (WHITE wire) // Set up the serial port to use softwareserial.. SoftwareSerial mySerial(2, 3); #else // On Leonardo/M0/etc, others with hardware serial, use hardware serial! // #0 is green wire, #1 is white #define mySerial Serial1 #endif Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); void setup() { pinMode(relay,OUTPUT); Serial.begin(9600); while (!Serial); // For Yun/Leo/Micro/Zero/... delay(100); Serial.println("\n\nAdafruit finger detect test"); // set the data rate for the sensor serial port finger.begin(57600); delay(5); if (finger.verifyPassword()) { Serial.println("Found fingerprint sensor!"); } else { Serial.println("Did not find fingerprint sensor :("); while (1) { delay(1); } } Serial.println(F("Reading sensor parameters")); finger.getParameters(); Serial.print(F("Status: 0x")); Serial.println(finger.status_reg, HEX); Serial.print(F("Sys ID: 0x")); Serial.println(finger.system_id, HEX); Serial.print(F("Capacity: ")); Serial.println(finger.capacity); Serial.print(F("Security level: ")); Serial.println(finger.security_level); Serial.print(F("Device address: ")); Serial.println(finger.device_addr, HEX); Serial.print(F("Packet len: ")); Serial.println(finger.packet_len); Serial.print(F("Baud rate: ")); Serial.println(finger.baud_rate); finger.getTemplateCount(); if (finger.templateCount == 0) { Serial.print("Sensor doesn't contain any fingerprint data. Please run the 'enroll' example."); } else { Serial.println("Waiting for valid finger..."); Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates"); } } void loop() // run over and over again { getFingerprintID(); delay(50); //don't ned to run this at full speed. } uint8_t getFingerprintID() { uint8_t p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Image taken"); break; case FINGERPRINT_NOFINGER: Serial.println("No finger detected"); finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_BLUE); finger.LEDcontrol(FINGERPRINT_LED_OFF, 0, FINGERPRINT_LED_RED); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); return p; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); return p; default: Serial.println("Unknown error"); return p; } // OK success! p = finger.image2Tz(); 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! p = finger.fingerSearch(); if (p == FINGERPRINT_OK) { Serial.println("Found a print match!"); finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_PURPLE, 10); delay(1000); if(u==0) { digitalWrite(relay,HIGH); u=1; } else if(u==1) { digitalWrite(relay,LOW); u=0; } } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_NOTFOUND) { finger.LEDcontrol(FINGERPRINT_LED_FLASHING, 25, FINGERPRINT_LED_RED, 10); delay(1000); Serial.println("Did not find a match"); return p; } else { Serial.println("Unknown error"); return p; } // found a match! Serial.print("Found ID #"); Serial.print(finger.fingerID); Serial.print(" with confidence of "); Serial.println(finger.confidence); return finger.fingerID; } // returns -1 if failed, otherwise returns ID # 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) return -1; // found a match! Serial.print("Found ID #"); Serial.print(finger.fingerID); Serial.print(" with confidence of "); Serial.println(finger.confidence); return finger.fingerID; } |
После регистрации отпечатков пальцев вы можете загрузить указанный выше код для считывания отпечатка пальца, хранящегося в базе данных отпечатков пальцев.
Вы можете приложить палец к сканеру отпечатков пальцев и считать сохраненные данные.