Esta semana os queremos enseñar a usar un sensor lector de huellas con Arduino, de una forma muy rápida y sencilla, podréis registrar más de 100 huellas diferentes y usarlas en vuestros proyectos con Arduino. Las posibilidades son infinitas, desde implementaciones en cerraduras inteligentes, desbloqueo de dispositivos electrónicos, registrar usuarios y mucho más.
En el mercado existen multitud de tiendas que venden sensores lector de huellas por muy poco precio, totalmente compatibles con Arduino. Pudiendo encontrarlos por menos de 10€.
Cómo funciona
En primer lugar, vamos a utilizar un código que se encargará de registrar las diferentes huellas dactilares que queramos usar en nuestro proyecto, y a continuación usaremos un segundo código para Arduino, el cuál se encargará de comprobar si la huella es válida o no, y hacer algo en consecuencia.
Para enseñaros a usar este tipo de lectores, vamos a montar un pequeño circuito de pruebas que ilumine un LED de color verde cuando la huella leída sea correcta (es decir, esté previamente registrada en el sistema), y por contra, ilumine un LED rojo cuando la huella leída no sea conocida.
Materiales
Para replicar el circuito de nuestro ejemplo, necesitaréis los siguientes componentes:
- Lector de huellas compatible con Arduino.
- Arduino (cualquier modelo es suficiente para este ejemplo).
- Un LED de color rojo y otro de color verde.
- Un par de resistencias de 220Ohm o un valor similar.
- Placa protoboard (opcional), para conectar los componentes cómodamente.
- Algunos cables para las conexiones.
Circuito
El circuito es muy sencillo, simplemente conectaremos el cable de RX del lector en el pin digital 3 de Arduino, el cable de TX del lector en el pin digital 2 de Arduino, y los cables de alimentación y tierra en los pines de 5V y GND de Arduino respectivamente.
Además colocaremos un par de LED junto a una resistencia para evitar dañar los LED, los cuales irán conectados a los pines 8 (LED verde) y 9 (LED rojo).
Código
Para el código vamos a usar los ejemplos dados por el fabricante Adafruit en el siguiente repositorio de Github: https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library
En primer lugar usaremos el código para registrar las huellas que queramos en nuestro Arduino, usando el ejemplo llamado enroll.ino:
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 | /*************************************************** This is an example sketch for our optical Fingerprint sensor Designed specifically to work with the Adafruit BMP085 Breakout ----> http://www.adafruit.com/products/751 These displays use TTL Serial to communicate, 2 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ #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; } |
Una vez cargado el código, necesitaremos seguir los pasos que se nos indican al abrir el Monitor Serie, poniendo el número del ID que queramos y colocando la huella dos veces, tal como nos pedirán los mensajes que vayamos viendo en el Monitor Serie. Si tenéis dudas en este paso, os animamos a ver el vídeo que hemos subido a Youtube, donde podéis ver cómo lo hacemos nosotros.
Lo siguiente que haremos tras registrar las huellas dactilares, será usar el código de ejemplo llamado fingerprint.ino. El cuál se mantendrá a la espera de recibir información del sensor de huellas, y determinará si la huella es válida o no. En este caso, le hemos hecho una pequeña modificación al código del repositorio, para que ilumine los LED rojo y verde para indicarnos si la huella es correcta. A continuación os mostramos el código con esta variación por si queréis usarla vosotros mismos:
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 | /*************************************************** This is an example sketch for our optical Fingerprint sensor Designed specifically to work with the Adafruit BMP085 Breakout ----> http://www.adafruit.com/products/751 These displays use TTL Serial to communicate, 2 pins are required to interface Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. BSD license, all text above must be included in any redistribution ****************************************************/ #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 const int ledVerde = 8; const int ledRojo = 9; Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); void setup() { Serial.begin(9600); while (!Serial); // For Yun/Leo/Micro/Zero/... delay(100); Serial.println("\n\nAdafruit finger detect test"); pinMode(ledVerde, OUTPUT); pinMode(ledRojo, OUTPUT); // 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"); 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!"); digitalWrite(ledVerde, HIGH); delay(2000); digitalWrite(ledVerde, LOW); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_NOTFOUND) { Serial.println("Did not find a match"); digitalWrite(ledRojo, HIGH); delay(2000); digitalWrite(ledRojo, LOW); 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; } |
¡Y eso sería todo! Con el circuito montado y estos códigos, ya tendréis listo vuestro lector de huellas digital con Arduino. Como podéis ver, es muy fácil y rápido de usar y no requiere de casi conocimientos en electrónica para usarlo, además de ser muy económico.
Esperemos os haya gustado. Si tenéis cualquier duda, nos podéis dejar un comentario en nuestro canal de Youtube o en la caja de comentarios de aquí abajo. ¡Gracias por leernos!