Como usar o módulo leitor de impressão digital com Arduino
Se você busca um projeto simples e barato de controle de acesso usando biometria, dê uma olhada neste Módulo Leitor de Impressão Digital, que vamos usar com Arduino no post de hoje.
Este leitor possui alta performance e um excelente algoritmo de comparação, e com ele você pode montar por exemplo um controle de acesso para acionamento de relés ou solenóides, ou até mesmo registrar em um banco de dados a presença das pessoas em um determinado ambiente.
O módulo que vamos utilizar é esse da imagem acima, que se comunica com o microcontrolador através de interface serial (UART) e funciona com tensões entre 3.8 e 7 VDC. Ele tem capacidade de armazenar até 240 digitais e leva menos de meio segundo para identificar a digital e enviar os dados para o microcontrolador.
Conexão do módulo leitor de impressão digital no Arduino
A conexão do módulo é feita usando somente 4 fios: o vermelho é o Vcc (5V) e o preto o GND. Os outros dois fios utilizados são da interface de comunicação serial: verde (TX) e branco (RX), que serão conectados respectivamente nos pinos 2 (RX) e 3 (TX) do Arduino Uno.
Adicionamos ao circuito um led na porta 7 que acende quando uma impressão digital é reconhecida, e também um pequeno Servo Motor TowerPro SG90 na porta 8 para simular o acionamento de uma trava. Você pode usar o mesmo princípio para acionar por exemplo um relé ou uma solenóide.
ATENÇÃO: as cores dos fios podem variar de acordo com o modelo de módulo leitor de impressão digital utilizado. E repare que no módulo que usamos “sobram” dois fios: o amarelo e o azul.
Instalação da biblioteca do módulo leitor
Para usar o módulo com Arduino vamos instalar a biblioteca Adafruit Fingerprint Sensor Library na IDE do Arduino seguindo os passos abaixo.
Selecione o menu Sketch -> Incluir Biblioteca -> Gerenciar Bibliotecas. No Gerenciador de Bibliotecas, procure por fingerprint e selecione a biblioteca da Adafruit, conforme imagem abaixo clicando em seguida em Instalar:
Dúvidas na instalação da biblioteca? Confira o post Como instalar uma biblioteca na IDE Arduino.
Armazenando as digitais no módulo leitor
A primeira coisa que temos que fazer é cadastrar as digitais no módulo, usando o programa abaixo. Ele é baseado no exemplo Enroll da biblioteca da Adafruit, e fiz uma versão um pouco mais enxuta com as mensagens em Português.
O programa usa a biblioteca SoftwareSerial para criar uma interface serial nos pinos digitais 2 e 3 do Arduino, liberando assim a serial por hardware para que possamos ver o resultado do programa usando o monitor serial da IDE.
O que esse programa faz é solicitar uma “posição de memória” (ID) para armazenar a digital. Vamos carregar o programa e ver como isso funciona.
//Programa: Modulo Leitor de impressao digital - Registro //Alteracoes: Arduino e Cia //Baseado no exemplo original da biblioteca Adafruit Fingerprint #include <Adafruit_Fingerprint.h> //Parametros da serial por software (pinos 2 e 3) SoftwareSerial mySerial(2, 3); Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); uint8_t id; void setup() { Serial.begin(9600); Serial.println("\n\nModulo Leitor de Impressao Digital - Registro"); //Taxa de comunicação com o modulo finger.begin(57600); //Checagem do hardware if (finger.verifyPassword()) { Serial.println("Sensor de impressao digital detectado!"); } else { Serial.println("Sensor de impressao digital nao encontrado:("); while (1) { delay(1); } } Serial.println(F("Lendo parametros do sensor")); 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("Capacidade: ")); Serial.println(finger.capacity); Serial.print(F("Nivel de Seguranca: ")); Serial.println(finger.security_level); Serial.print(F("Endereco do dispositivo: ")); 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() { Serial.println("Pronto para registrar uma digital!"); Serial.println("Digite o numero do ID (de 1 a 240) onde voce deseja salvar a digital..."); id = readnumber(); if (id == 0) {// ID #0 not allowed, try again! return; } Serial.print("Registrando ID #"); Serial.println(id); while (! getFingerprintEnroll() ); } uint8_t getFingerprintEnroll() { int p = -1; Serial.print("Aguardando a digital para registrar no ID numero "); Serial.println(id); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Imagem capturada"); break; case FINGERPRINT_NOFINGER: Serial.println("."); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Erro de imagem"); break; default: Serial.println("Erro desconhecido"); break; } } // OK success! p = finger.image2Tz(1); switch (p) { case FINGERPRINT_OK: Serial.println("Imagem convertida"); break; case FINGERPRINT_IMAGEMESS: Serial.println("Imagem incorreta"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; default: Serial.println("Erro desconhecido"); return p; } Serial.println("Remova o dedo do sensor"); delay(2000); p = 0; while (p != FINGERPRINT_NOFINGER) { p = finger.getImage(); } Serial.print("ID "); Serial.println(id); p = -1; Serial.println("Coloque o mesmo dedo novamente"); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Imagem capturada"); break; case FINGERPRINT_NOFINGER: Serial.print("."); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imagem incorreta"); break; default: Serial.println("Erro desconhecido"); break; } } // OK success! p = finger.image2Tz(2); switch (p) { case FINGERPRINT_OK: Serial.println("Image converted"); break; case FINGERPRINT_IMAGEMESS: Serial.println("Imagem incorreta"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; default: Serial.println("Erro desconhecido"); return p; } // OK converted! Serial.print("Creating model for #"); Serial.println(id); p = finger.createModel(); if (p == FINGERPRINT_OK) { Serial.println("Digitais correspondem!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Erro de comunicacao"); return p; } else if (p == FINGERPRINT_ENROLLMISMATCH) { Serial.println("Digitais nao correspondem"); return p; } else { Serial.println("Erro desconhecido"); return p; } Serial.print("ID "); Serial.println(id); p = finger.storeModel(id); if (p == FINGERPRINT_OK) { Serial.println("Impressao Digital Armazenada!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Erro de comunicacao"); return p; } else if (p == FINGERPRINT_BADLOCATION) { Serial.println("Nao foi possivel armazenar nesta localizacao"); return p; } else if (p == FINGERPRINT_FLASHERR) { Serial.println("Erro gravando na memoria flash"); return p; } else { Serial.println("Erro desconhecido"); return p; } return true; }
Com o programa carregado, abra o serial monitor, selecione a velocidade de 9600 e aguarde a mensagem solicitando o ID no qual você deseja armazenar a digital. Digite um número entre 1 e 240, clique em Enviar e siga as instruções enviadas pelo programa.
Após a detecção da digital, o programa vai pedir para que você coloque novamente o mesmo dedo no sensor, para conferir se a digital foi lida corretamente. Se tudo estiver ok, uma mensagem de Impressão Digital Armazenada irá aparecer na tela, e você pode ou encerrar o programa ou cadastrar novas digitais.
Lendo as digitais no módulo leitor de impressão digital
Com as digitais armazenadas, vamos agora efetuar a leitura utilizando o programa abaixo. Ele também foi baseado no exemplo da biblioteca da Adafruit e eu acrescentei o led e o acionamento do servo motor que pode ser usado por exemplo em um sistema de abertura de portas.
//Programa: Modulo Leitor de impressao digital - Leitura //Alteracoes: Arduino e Cia //Baseado no exemplo original da biblioteca Adafruit Fingerprint #include <Adafruit_Fingerprint.h> #include <Servo.h> //Cria um objeto para controlar o servo motor Servo myservo; //Parametros da serial por software (pinos 2 e 3) SoftwareSerial mySerial(2, 3); #define pino_led 7 #define pino_servo 8 Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); void setup() { Serial.begin(9600); Serial.println("\n\nModulo Leitor de Impressao Digital - Leitura"); pinMode(pino_led, OUTPUT); digitalWrite(pino_led, LOW); // Define que o servo esta ligado a porta 7 myservo.attach(pino_servo); myservo.write(0); //Taxa de comunicação com o modulo finger.begin(57600); delay(5); if (finger.verifyPassword()) { Serial.println("Sensor de impressao digital detectado!"); } else { Serial.println("Sensor de impressao digital nao encontrado:("); while (1) { delay(1); } } Serial.println(F("Lendo parametros do sensor")); 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("Capacidade: ")); Serial.println(finger.capacity); Serial.print(F("Nivel de Seguranca: ")); Serial.println(finger.security_level); Serial.print(F("Endereco do dispositivo: ")); 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 nao contem nenhuma digital. Cadastre as digitais primeiro!"); } else { Serial.println("Aguardando digital..."); Serial.print("O sensor contem "); Serial.print(finger.templateCount); Serial.println(" digitais cadastradas"); } } void loop() { getFingerprintID(); delay(50); } uint8_t getFingerprintID() { uint8_t p = finger.getImage(); switch (p) { case FINGERPRINT_OK: Serial.println("Imagem registrada"); break; case FINGERPRINT_NOFINGER: Serial.println("Digital nao detectada"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); return p; case FINGERPRINT_IMAGEFAIL: Serial.println("Imagem incorreta"); return p; default: Serial.println("Erro desconhecido"); return p; } // OK success! p = finger.image2Tz(); switch (p) { case FINGERPRINT_OK: Serial.println("Imagem convertida"); break; case FINGERPRINT_IMAGEMESS: Serial.println("Imagem invalida"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Erro de comunicacao"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Nao foi possivel encontrar recursos de impressao digital"); return p; default: Serial.println("Erro desconhecido"); return p; } // OK converted! p = finger.fingerSearch(); if (p == FINGERPRINT_OK) { Serial.println("Encontrada digital correspondente!"); //Aciona o led e o servo motor digitalWrite(pino_led, HIGH); myservo.write(90); //Aguarda 1 segundo e desliga o led e o servo delay(1000); digitalWrite(pino_led, LOW); myservo.write(0); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_NOTFOUND) { Serial.println("Did not find a match"); return p; } else { Serial.println("Unknown error"); return p; } Serial.print("ID encontrado #"); Serial.print(finger.fingerID); Serial.print(" com confianca de "); Serial.println(finger.confidence); return finger.fingerID; } //Retorna -1 em caso de falha, senao retorna o numero do 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; Serial.print("ID encontrado #"); Serial.print(finger.fingerID); Serial.print(" com confianca de "); Serial.println(finger.confidence); return finger.fingerID; }
O programa reconhece a digital armazenada anteriormente e mostra em qual posição de memória ela está armazenada. Essas informações são mostradas também no serial monitor.
Lembrando que por ter comunicação Serial / TTL este módulo pode ser usado com outros microcontroladores como PIC ou placas como Raspberry Pi, que permitem esse tipo de comunicação.
Gostou? Confira outros posts usando Arduino aqui mesmo no Arduino e Cia!
não gostei, pois não tem informações de como ligar o monitor, por acaso é LCD ? como ligá-lo.
gostei do projecto estou montando com uma fechadura selenoide adicionei dois leds e um buzzer para sinalizacao
gostaaria de saber o autor do projecto para possivel menção no final do meu projecto bem a pinagem usa no modulo biometrico
Oi Ivam,
Desculpe pela demora. O autor é Adilson Thomsen
Abraço e obrigado!
Adilson
Muito bom! Parabéns pela didática. Ajudou muito a ver a biblioteca e suas classes. Obrigado.
Valeu Paulo!
Abraço.
Adilson
Olá, bom dia! Gostaria de uma ajudinha, comprei um Sim800l para fazer um projeto para uma empresa e estou tendo muitos problemas na hora de fazê-lo se comunicar com o Arduino, está aparecendo umas mensagens estranhas, como por exemplo: “��” mando mensagem e ela aparece assim tbm, não sei oq fazer…
Oi Vinicius,
Tudo bem? Isso “parece” ser velocidade de comunicação. Qual você está usando? Já experimentou alterar o valor para 4800, 9600, etc?
Abraço!
Adilson