Leitor Biométrico com SPIFFS

,

Olá, como estão? A princípio iremos falar sobre SPIFFS, utilizando nosso último post como exemplo, onde iremos fazer um projeto com leitor biométrico com SPIFFS. O SPIFFS possuem diversas aplicações, por exemplo você pode fazer um datalogger, banco de dados, entre muitas outras aplicações… Desse modo podemos estar realizando aplicações complexas e mais econômicas, tomando proveito da memória FLASH no modulo ESP32 para armazenamento de arquivos.

Leitor Biométrico FPM10A - WJ Componentes
ESP32

Componentes Utilizados


O Que é SPIFFS?


O SPPIFS permite que você acesse a memoria FLASH do seu ESP como se fosse um sistema de arquivos. Assim permitindo criar, editar e armazenar arquivos assim deixando o seu projeto mais dinâmico e econômico. Pois o EPS32 tem 520 Kb de memória RAM, mas já de memória flash ele possui 4 Mb.

Algumas Funções Importantes

  • SPIFFS.begin(true) – Inicializa o serviço SPIFFS.
  • File variável – File é um tipo de variável que utilizamos para apontar para o arquivo.
  • SPIFFS.open(“caminho”,”modo”) – Abre o arquivo, o caminho refere-se ao arquivo que será aberto, já o modo refere-se de qual forma o arquivo será aberto. Entretanto existem 6 formas de abrir um arquivo entre elas estão:
    • “R” – Modo de Leitura.
    • “W” – Modo de Escrita e caso não exista o arquivo irá ser criado.
    • “A” – Modo de Anexo, ou seja, ele não irá sobrescrever e caso não exista o arquivo irá criar.
  • file.read() – Lê o arquivo.
  • file.close() – Fecha um arquivo que esteja aberto.
  • SPIFFS.remove(“caminho”) – Apaga um arquivo, o caminho refere-se ao arquivo que irá ser apagado.

Funcionamento do Projeto Leitor Biométrico com SPIFFS


A princípio o circuito baseia-se no ESP32 juntamente com o leitor biométrico FPM10A. Entretanto caso não lembre como realizar as ligações do circuito ou até mesmo de como funciona, índico que entre lá e leia clicando aqui.

Contudo é Importante ressaltar que o FPM10A não funciona com a tenção de 3,3V a tensão mínima é de 3,6V. Logo após realizarmos todas as ligações do circuito iremos utilizar o SPIFFS para gerar dois bancos de dados. Sendo um deles com a ID e nome para sabermos de quem é cada ID, e outra com nome e data para conseguíamos ter um controle de quem está utilizando o sensor, como se fosse um cartão de ponto biométrico.

Código-fonte do Projeto Leitor Biométrico com SPIFFS


Em seguida segue abaixo o código-fonte completo do projeto.

//Biblioteca -----------------------------------------------------------------------------------------
#include <Adafruit_Fingerprint.h>                           // Responsável pelo Leitor Biométrico
#include <SPIFFS.h>                                         // Responsável pela memoria SPIFFS
#include <WiFi.h>                                           // Responsável pelo WiFi
#include <time.h>                                           // Responsável pelo tempo

//Declarações de Variáveis----------------------------------------------------------------------------
const uint32_t password = 0x0;                              // Senha padrão do sensor biométrico

//Objetos --------------------------------------------------------------------------------------------
Adafruit_Fingerprint fingerSensor = Adafruit_Fingerprint(&Serial2, password);

//Funções Auxiliares ---------------------------------------------------------------------------------
void printMenu();                                           // Responsável pelo Menu
String pegaComando();                                       // Responsável por Pegar Comando
void printLocalTime();                                      // Responsável por Imprimir a Hora
void cadastraDigital();                                     // Responsável por Cadastrar Digital
void verificaDigital();                                     // Responsável por Verificar Digital
void contDigital();                                         // Responsável por Contar Digitais
void pontDigital();                                         // Responsável por Mostras os Registros
void deleteDigital();                                       // Responsável por Deletar Digital
void limpaDatabase();                                       // Responsável por Limpar Banco de Dados

//SPIFFS ---------------------------------------------------------------------------------------------
File fileDados;
File fileRegistro;

//WiFi -----------------------------------------------------------------------------------------------
const char* ssid  = "<NOME-DA-REDE>";                       // Nome da rede WiFi
const char* senha = "<SENHA-DA-REDE>";                      // Senha da rede WiFi

//Data e Hora ----------------------------------------------------------------------------------------
const char* ntpServer = "pool.ntp.org";                     // Consulta Horário
const long  gmtOffset_sec = -4*3600;                        // Fuso fuso horário
const int   daylightOffset_sec = 3600;                      // Tempo em horas

//Setup ----------------------------------------------------------------------------------------------
void setup(){
    Serial.begin(115200);                                   // Inicializa o Serial

    //Leitor de Biometria
    fingerSensor.begin(57600);                              // Inicializa o Sensor
    if(!fingerSensor.verifyPassword()){                     // Verifica se não é a senha do sensor
        Serial.println("Não foi possível conectar ao sensor. Verifique a senha ou a conexão");
        while(true){};                                      // Loop Infinito
    }

    //SPIFFS
    if(!SPIFFS.begin(true)){                                // Inicializa o SPIFFS
        Serial.println("Erro ao Inicializar o SPIFFS");     // Imprime na Serial
    }

    //WiFi
    WiFi.begin(ssid, senha);                                // Tenta se conectar a rede WiFi
    Serial.print("Conectando no WiFi ");                    // Imprime na Serial
    Serial.println(ssid);                                   // Imprime na Serial
    while (WiFi.status() != WL_CONNECTED) {                 // Verifica se a conexão foi realizada
        Serial.print(".");                                  // Imprime na Serial
        delay(500);                                         // Espera 0,5s
    }
    Serial.println(" CONNECTED");                           // Imprime na Serial

    //Inicia Configuração da Data e Hora
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

//Loop -----------------------------------------------------------------------------------------------
void loop(){
    printMenu();                                            // Chama função printMenu()
    String command = pegaComando();                         // Faz a leitura do comando digitado
    int i = command.toInt();                                // Transforma em inteiro
    switch (i){                                             // Verifica qual o número digitado
   case 1:                                                  // Se i = 1
        cadastraDigital();                                  // Chama Função cadastraDigital()
        break;
    case 2:                                                 // Se i = 2
        verificaDigital();                                  // Chama Função verificaDigital()
        break;
    case 3:                                                 // Se i = 3
        contDigital();                                      // Chama Função contDigital()
        break;
    case 4:                                                 // Se i = 4
        pontDigital();                                      // Chama Função pontDigital()
        break;
    case 5:                                                 // Se i = 5
        deleteDigital();                                    // Chama Função deletaDigital()
        break;
    case 6:                                                 // Se i = 6
        limpaDatabase();                                    // Chama Função limpaDatabase()
        break;
    default:
        Serial.println("Opção inválida");                   // Imprime na Serial
        break;
    }
    delay(1000);                                            // Espera 1s
}

//Imprime Menu ---------------------------------------------------------------------------------------
void printMenu(){
    Serial.println();
    Serial.println("Digite um dos números do menu abaixo");
    Serial.println("1 - Cadastrar digital");
    Serial.println("2 - Verificar digital");
    Serial.println("3 - Mostrar quantidade de digitais cadastradas");
    Serial.println("4 - Mostrar Pontos Registrados");
    Serial.println("5 - Apagar digital em uma posição");
    Serial.println("6 - Apagar banco de digitais");
}

//Pega Comando ---------------------------------------------------------------------------------------
String pegaComando(){
    while(!Serial.available()) delay(100);
    return Serial.readStringUntil('\n');                    // Retorna o que foi digitado na Serial
}

//Imprime Data e Hota --------------------------------------------------------------------------------
void printLocalTime(){
    struct tm timeinfo;                                     // Criar uma estrutura
    if(!getLocalTime(&timeinfo)){                           // Verifica se consegue obter a hora
        Serial.println("Erro ao obeter Horario");           // Imprime na Serial caso não consiga
        return;
    }
    fileRegistro = SPIFFS.open("/registro.txt","a");        // Abre arquivo registro em modo anexo
    if(!fileRegistro.print(&timeinfo, "%d %B %Y - %H:%M:%S")){ // Se foi possível gravar
        Serial.println("Erro ao Gravar Horario");           // Imprime na Serial caso não consiga
        return;
    }
    fileRegistro.close();                                   // Fecha o arquivo registro
    Serial.print(&timeinfo, "%d %B %Y - %H:%M:%S");         // Imprime data no serial
}

//Cadastra Digital -----------------------------------------------------------------------------------
void cadastraDigital(){
    Serial.println("Qual a posição para guardar a digital? (1 a 9)"); // Imprime na Serial
    String strLocation = pegaComando();                     // Faz a leitura do comando digitado
    int location = strLocation.toInt();                     // Transforma em inteiro
    fileDados = SPIFFS.open("/dados.txt","a");              // Abre arquivo dados em modo anexo
    
    if(location < 1 || location > 9){                       // Verifica se a posição é invalida
        Serial.println("Posição inválida");                 // Imprime na Serial
        return;
    }
    
    Serial.println("Digite seu nome: ");                    // Imprime na Serial
    nome = pegaComando();                                   // Lê o que foi digitado na Serial  
    Serial.println("Encoste o dedo no sensor");             // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK){};    // Espera até pegar uma imagem válida
    
    if (fingerSensor.image2Tz(1) != FINGERPRINT_OK){        // Converte a imagem para primeiro padrão
        Serial.println("Erro image2Tz 1");                  // Erro de Imagem
        return;
    }
    Serial.println("Tire o dedo do sensor");                // Imprime na Serial
    delay(2000);                                            // Espera 2s
    while (fingerSensor.getImage() != FINGERPRINT_NOFINGER){}; //Espera até tirar o dedo
    Serial.println("Encoste o mesmo dedo no sensor");       // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK);      // Espera até pegar uma imagem válida
    
    if(fingerSensor.image2Tz(2) != FINGERPRINT_OK){         // Converte a imagem para o segundo padrão
        Serial.println("Erro image2Tz 2");                  // Erro de Imagem
        return;
    }
    
    if(fingerSensor.createModel() != FINGERPRINT_OK){       // Cria um modelo com os dois padrões
        Serial.println("Erro createModel");                 // Erro para criar o Modelo
        return;
    }
    
    if(fingerSensor.storeModel(location) != FINGERPRINT_OK){// Guarda o modelo da digital no sensor
        Serial.println("Erro já existe uma biometrica cadastrada"); // Já existe
        return;
    }
    
    fileDados = SPIFFS.open("/dados.txt","a");              // Abre arquivo dados em modo anexo
    fileDados.print(location);                              // Escreve location no arquivo dados
    fileDados.print(" ");                                   // Escreve " " no arquivo dados
    fileDados.println(nome);                                // Escreve o nome no arquivo dados
    Serial.println("Sucesso!!!");                           // Imprime na Serial
    fileDados.close();                                      // Fecha arquivo dados
    Serial.print(location);                                 // Imprime a localização na Serial
    Serial.print(" ");                                      // Imprime " " na Serial
    Serial.println(nome);                                   // Imprime nome na Serial
}

//Verifica Digital -----------------------------------------------------------------------------------
void verificaDigital(){
    String text;
    int id,tam,i;
    char pos;
    Serial.println("Encoste o dedo no sensor");             // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK){};    // Espera até pegar uma imagem válida
    
    if (fingerSensor.image2Tz() != FINGERPRINT_OK){         // Converte a imagem para utilizar
        Serial.println("Erro image2Tz");                    // Imprime na Serial
        return;
    }

    if (fingerSensor.fingerFastSearch() != FINGERPRINT_OK){ // Procura pela digital no banco de dados
        Serial.println("Digital não encontrada");           // Imprime na Serial
        return;
    }

    fileDados = SPIFFS.open("/dados.txt","r");              // Abre arquivo dados em modo de leitura
    id = fingerSensor.fingerID;                             // Pega a ID no sensor e atribui a ID
    text = fileDados.readString();                          // Atribui texto do arquivo dados a text
    tam = text.length();                                    // Atribui o tamanho de text a tam
    pos = id+'0';                                           // Converte int para char
    for(i=0;i<tam;i++){                                     // Faz loop para verificar onde está a ID
        if(text.charAt(i) == pos){                          // Verifica se o caracteres é igual a ID
            text.remove(0,i+2);                             // Remove tudo que esta no começo até a ID
            for(i=0;i<tam-i;i++){                           // Faz loop para verificar onde esta
                if(text.charAt(i) == '\n'){                 // Verifica se onde o nome acaba 
                    text.remove(i);                         // Apaga tudo que esta depois de nome
                    break;                                  // Força uma saída do loop
                }
            }
            break;                                          // Força uma saída do loop
        }
    }
    fileDados.close();                                      // Fecha o arquivo dados
    delay(500);                                             // Espera 0,5s
    Serial.println("----------Digital Encontrada----------");
    Serial.print("Na posição: ");                           // Imprime na Serial
    Serial.println(id);                                     // Imprime na Serial a ID
    Serial.print("Pessoa: ");                               // Imprime na Serial
    Serial.println(text);                                   // Imprime na Serial o text
    fileRegistro = SPIFFS.open("/registro.txt","a");        // Abre arquivo registro em modo anexo
    fileRegistro.println("");                               // Salva pula linha no arquivo
    fileRegistro.print(text);                               // Salva text no arquivo
    fileRegistro.print(" - ");                              // Salva " - " no arquivo
    fileRegistro.close();                                   // Fecha o arquivo registro
    Serial.print("Horario: ");                              // Imprime na Serial
    printLocalTime();                                       // Chama a função printLocalTime
}

//Conta Qtde de Digitais -----------------------------------------------------------------------------
void contDigital(){
    fileDados = SPIFFS.open("/dados.txt","r");              // Abre arquivo dados em modo leitura
    String text = fileDados.readString();                   // Atribui a text o arquivo aberto
    fingerSensor.getTemplateCount();                        // Atribui a "templateCount" a qtde

    //Exibe a quantidade salva
    Serial.print("Digitais cadastradas: ");                 // Imprime na Serial
    Serial.println(fingerSensor.templateCount);             // Imprime na Serial a quantidade salva
    Serial.println("LISTA DOS USUARIOS:");                  // Imprime na Serial
    Serial.println(text);                                   // Imprime na Serial a Lista de Digitais
    fileDados.close();                                      // Fecha arquivo dados
}

//Imprime Registros ----------------------------------------------------------------------------------
void pontDigital(){
    fileRegistro = SPIFFS.open("/registro.txt","r");        // Abre arquivo em modo de leitura
    Serial.println(fileRegistro.readString());              // Imprime as ID e nomes de cada pessoa
    fileRegistro.close();                                   // Fecha arquivo registro
}

//Deleta uma Digital ---------------------------------------------------------------------------------
void deleteDigital(){
    Serial.println("Qual a posição para apagar a digital? (1 a 9)");  // Imprime na Serial
    String strLocation = pegaComando();                     // Faz a leitura do comando digitado
    int location = strLocation.toInt();                     // Transforma em inteiro

    if(location < 1 || location > 9){                       // Verifica se a posição é invalida
        Serial.println("Posição inválida");                 // Imprime na Serial
        return;
    }

    if(fingerSensor.deleteModel(location) != FINGERPRINT_OK){ // Apaga a digital na posição location
        Serial.println("Erro ao apagar digital");           // Imprime na Serial
    }
    else{
        Serial.println("Digital apagada com sucesso!!!");   // Imprime na Serial
    }
}

//Limpa Banco de Dados -------------------------------------------------------------------------------
void limpaDatabase(){
    Serial.println("Tem certeza? (S/N)");                   // Imprime na Serial
    String command = pegaComando();                         // Faz a leitura do comando digitado
    command.toUpperCase();                                  // Coloca tudo em maiúsculo

    if(command == "S" || command == "SIM"){                 // Verifica se foi digitado "S" ou "SIM"
        Serial.println("Apagando banco de digitais...");    // Imprime na Serial

        if(fingerSensor.emptyDatabase() != FINGERPRINT_OK){ // Apaga todas as digitais
            Serial.println("Erro ao apagar banco de digitais"); // Imprime na Serial
        }

        else{
            SPIFFS.remove("/dados.txt");                    // Apaga arquivo dados
            SPIFFS.remove("/registro.txt");                 // Apaga arquivo registro
            Serial.println("Banco de digitais apagado com sucesso!!!"); // Imprime na Serial
        }
    }
    else{
        Serial.println("Cancelado");                        // Imprime na Serial
    }
}

Vamos dar uma olhada mais de perto no código:

Incluindo Bibliotecas

Primeiramente temos que incluir as bibliotecas que usamos em nosso projeto.

//Biblioteca -----------------------------------------------------------------------------------------
#include <Adafruit_Fingerprint.h>                           // Responsável pelo Leitor Biométrico
#include <SPIFFS.h>                                         // Responsável pela memoria SPIFFS
#include <WiFi.h>                                           // Responsável pelo WiFi
#include <time.h>                                           // Responsável pelo tempo

Variáveis Globais

Logo após declaramos 1 variável global chamada password.

//Declarações de Variáveis----------------------------------------------------------------------------
const uint32_t password = 0x0;                              // Senha padrão do sensor biométrico

Declaração de Objeto

Logo após declaramos 1 objeto o qual chamamos de fingerSensor.

//Objetos --------------------------------------------------------------------------------------------
Adafruit_Fingerprint fingerSensor = Adafruit_Fingerprint(&Serial2, password);

Declarações de Funções Auxiliares

Em seguida declaramos 9 funções auxiliares, para que dessa forma possamos dividir nosso código.

//Funções Auxiliares ---------------------------------------------------------------------------------
void printMenu();                                           // Responsável pelo Menu
String pegaComando();                                       // Responsável por Pegar Comando
void printLocalTime();                                      // Responsável por Imprimir a Hora
void cadastraDigital();                                     // Responsável por Cadastrar Digital
void verificaDigital();                                     // Responsável por Verificar Digital
void contDigital();                                         // Responsável por Contar Digitais
void pontDigital();                                         // Responsável por Mostras os Registros
void deleteDigital();                                       // Responsável por Deletar Digital
void limpaDatabase();                                       // Responsável por Limpar Banco de Dados

Declarações de Arquivos

Logo após declaramos 2 variáveis do tipo File para apontarem para os arquivos.

//SPIFFS ---------------------------------------------------------------------------------------------
File fileDados;
File fileRegistro;

Declarações do WiFi

Então declaramos duas constantes para o WiFi sendo elas ssid(nome da rede WiFi) e senha da rede.

//WiFi -----------------------------------------------------------------------------------------------
const char* ssid  = "<NOME-DA-REDE>";                       // Nome da rede WiFi
const char* senha = "<SENHA-DA-REDE>";                      // Senha da rede WiFi

Declarações do NTP

Em seguida declaramos três constantes para que seja possível obter o horário atual.

//Data e Hora ----------------------------------------------------------------------------------------
const char* ntpServer = "pool.ntp.org";                     // Consulta Horário
const long  gmtOffset_sec = -4*3600;                        // Fuso fuso horario
const int   daylightOffset_sec = 3600;                      // Tempo em horas

Funções Setup

Então agora na função setup, será onde iremos inicializar a Serial, leitor biométrico, SPIFFS, WiFi e NTP para obter a data e hora atual.

//Setup ----------------------------------------------------------------------------------------------
void setup(){
    Serial.begin(115200);                                   // Inicializa o Serial

    //Leitor de Biometria
    fingerSensor.begin(57600);                              // Inicializa o Sensor
    if(!fingerSensor.verifyPassword()){                     // Verifica se não é a senha do sensor
        Serial.println("Não foi possível conectar ao sensor. Verifique a senha ou a conexão");
        while(true){};                                      // Loop Infinito
    }

    //SPIFFS
    if(!SPIFFS.begin(true)){                                // Inicializa o SPIFFS
        Serial.println("Erro ao Inicializar o SPIFFS");     // Imprime na Serial
    }

    //WiFi
    WiFi.begin(ssid, senha);                                // Tenta se conectar a rede WiFi
    Serial.print("Conectando no WiFi ");                    // Imprime na Serial
    Serial.println(ssid);                                   // Imprime na Serial
    while (WiFi.status() != WL_CONNECTED) {                 // Verifica se a conecção foi realizada
        Serial.print(".");                                  // Imprime na Serial
        delay(500);                                         // Espera 0,5s
    }
    Serial.println(" CONNECTED");                           // Imprime na Serial

    //Inicia Configuração da Data e Hora
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}

Funções Loop

Em seguida na função loop, iremos imprimir o menu chamando a função printMenu, então esperamos o usuário digitar o comando e atribuímos a command. Em seguida transformamos em inteiro e atribuímos a i, após verificamos se i é igual a 1, 2, 3, 4, 5 ou 6. Entretanto caso seja chamamos sua respectiva função.

//Loop -----------------------------------------------------------------------------------------------
void loop(){
    printMenu();                                            // Chama função printMenu()
    String command = pegaComando();                         // Faz a leitura do comando digitado
    int i = command.toInt();                                // Transforma em inteiro
    switch (i){                                             // Verifica qual o número digitado
   case 1:                                                  // Se i = 1
        cadastraDigital();                                  // Chama Função cadastraDigital()
        break;
    case 2:                                                 // Se i = 2
        verificaDigital();                                  // Chama Função verificaDigital()
        break;
    case 3:                                                 // Se i = 3
        contDigital();                                      // Chama Função contDigital()
        break;
    case 4:                                                 // Se i = 4
        pontDigital();                                      // Chama Função pontDigital()
        break;
    case 5:                                                 // Se i = 5
        deleteDigital();                                    // Chama Função deletaDigital()
        break;
    case 6:                                                 // Se i = 6
        limpaDatabase();                                    // Chama Função limpaDatabase()
        break;
    default:
        Serial.println("Opção inválida");                   // Imprime na Serial
        break;
    }
    delay(1000);                                            // Espera 1s
}

Funções Imprime Menu

Contudo na função printMenu, será onde iremos imprimir o menu na Serial.

//Imprime Menu ---------------------------------------------------------------------------------------
void printMenu(){
    Serial.println();
    Serial.println("Digite um dos números do menu abaixo");
    Serial.println("1 - Cadastrar digital");
    Serial.println("2 - Verificar digital");
    Serial.println("3 - Mostrar quantidade de digitais cadastradas");
    Serial.println("4 - Mostrar Pontos Registrados");
    Serial.println("5 - Apagar digital em uma posição");
    Serial.println("6 - Apagar banco de digitais");
}

Funções Pega Comando

Logo após na função pegaComando, será onde iremos obter o comando digitado pelo usuário. Então para isso iremos criar um loop enquanto não tiver dados na serial, quando tiver iremos retornar a string da serial.

//Pega Comando ---------------------------------------------------------------------------------------
String pegaComando(){
    while(!Serial.available()) delay(100);
    return Serial.readStringUntil('n');                    // Retorna o que foi digitado na Serial
}

Funções Data e Hora

Então na função printLocalTime, será onde iremos obter a data e hora atual. Em seguida salvamos a data e hora no arquivo registro.

//Pega Comando ---------------------------------------------------------------------------------------
String pegaComando(){
    while(!Serial.available()) delay(100);
    return Serial.readStringUntil('n');                    // Retorna o que foi digitado na Serial
}

Funções Cadastra Digital

Em seguida a função cadastraDigital, é responsável por cadastrar uma nova digital no banco de dados juntamente no arquivo dados.

//Cadastra Digital -----------------------------------------------------------------------------------
void cadastraDigital(){
    Serial.println("Qual a posição para guardar a digital? (1 a 9)"); // Imprime na Serial
    String strLocation = pegaComando();                     // Faz a leitura do comando digitado
    int location = strLocation.toInt();                     // Transforma em inteiro
    fileDados = SPIFFS.open("/dados.txt","a");              // Abre arquivo dados em modo anexo
    
    if(location < 1 || location > 9){                       // Verifica se a posição é invalida
        Serial.println("Posição inválida");                 // Imprime na Serial
        return;
    }
    
    Serial.println("Digite seu nome: ");                    // Imprime na Serial
    nome = pegaComando();                                   // Lê o que foi digitado na Serial  
    Serial.println("Encoste o dedo no sensor");             // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK){};    // Espera até pegar uma imagem válida
    
    if (fingerSensor.image2Tz(1) != FINGERPRINT_OK){        // Converte a imagem para primeiro padrão
        Serial.println("Erro image2Tz 1");                  // Erro de Imagem
        return;
    }
    Serial.println("Tire o dedo do sensor");                // Imprime na Serial
    delay(2000);                                            // Espera 2s
    while (fingerSensor.getImage() != FINGERPRINT_NOFINGER){}; //Espera até tirar o dedo
    Serial.println("Encoste o mesmo dedo no sensor");       // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK);      // Espera até pegar uma imagem válida
    
    if(fingerSensor.image2Tz(2) != FINGERPRINT_OK){         // Converte a imagem para o segundo padrão
        Serial.println("Erro image2Tz 2");                  // Erro de Imagem
        return;
    }
    
    if(fingerSensor.createModel() != FINGERPRINT_OK){       // Cria um modelo com os dois padrões
        Serial.println("Erro createModel");                 // Erro para criar o Modelo
        return;
    }
    
    if(fingerSensor.storeModel(location) != FINGERPRINT_OK){// Guarda o modelo da digital no sensor
        Serial.println("Erro já existe uma biometrica cadastrada"); // Já existe
        return;
    }
    
    fileDados = SPIFFS.open("/dados.txt","a");              // Abre arquivo dados em modo anexo
    fileDados.print(location);                              // Escreve location no arquivo dados
    fileDados.print(" ");                                   // Escreve " " no arquivo dados
    fileDados.println(nome);                                // Escreve o nome no arquivo dados
    Serial.println("Sucesso!!!");                           // Imprime na Serial
    fileDados.close();                                      // Fecha arquivo dados
    Serial.print(location);                                 // Imprime a localização na Serial
    Serial.print(" ");                                      // Imprime " " na Serial
    Serial.println(nome);                                   // Imprime nome na Serial
}

Funções Verifica Digital

Então agora na função verificaDigital, é responsável por verificar se a digital é igual alguma digital cadastrada anteriormente no banco de dados e registra no arquivo registros a data e hora que o usuário verificou aa digital.

//Verifica Digital -----------------------------------------------------------------------------------
void verificaDigital(){
    String text;
    int id,tam,i;
    char pos;
    Serial.println("Encoste o dedo no sensor");             // Imprime na Serial
    while (fingerSensor.getImage() != FINGERPRINT_OK){};    // Espera até pegar uma imagem válida
    
    if (fingerSensor.image2Tz() != FINGERPRINT_OK){         // Converte a imagem para utilizar
        Serial.println("Erro image2Tz");                    // Imprime na Serial
        return;
    }

    if (fingerSensor.fingerFastSearch() != FINGERPRINT_OK){ // Procura pela digital no banco de dados
        Serial.println("Digital não encontrada");           // Imprime na Serial
        return;
    }

    fileDados = SPIFFS.open("/dados.txt","r");              // Abre arquivo dados em modo de leitura
    id = fingerSensor.fingerID;                             // Pega a ID no sensor e atribui a ID
    text = fileDados.readString();                          // Atribui texto do arquivo dados a text
    tam = text.length();                                    // Atribui o tamanho de text a tam
    pos = id+'0';                                           // Convete int para char
    for(i=0;i<tam;i++){                                     // Faz loop para verificar onde está a ID
        if(text.charAt(i) == pos){                          // Verifica se o caracteres é igual a ID
            text.remove(0,i+2);                             // Remove tudo que esta no começo até a ID
            for(i=0;i<tam-i;i++){                           // Faz loop para verificar onde esta
                if(text.charAt(i) == '\n'){                 // Verifica se onde o nome acaba 
                    text.remove(i);                         // Apaga tudo que esta depois de nome
                    break;                                  // Força uma saida do loop
                }
            }
            break;                                          // Força uma saida do loop
        }
    }
    fileDados.close();                                      // Fecha o arquivo dados
    delay(500);                                             // Espera 0,5s
    Serial.println("----------Digital Encontrada----------");
    Serial.print("Na posição: ");                           // Imprime na Serial
    Serial.println(id);                                     // Imprime na Serial a ID
    Serial.print("Pessoa: ");                               // Imprime na Serial
    Serial.println(text);                                   // Imprime na Serial o text
    fileRegistro = SPIFFS.open("/registro.txt","a");        // Abre arquvio registro em modo anexo
    fileRegistro.println("");                               // Salva pula linha no arquivo
    fileRegistro.print(text);                               // Salva text no arquivo
    fileRegistro.print(" - ");                              // Salva " - " no arquivo
    fileRegistro.close();                                   // Fecha o arquivo registro
    Serial.print("Horario: ");                              // Imprime na Serial
    printLocalTime();                                       // Chama a função printLocalTime
}

Funções Quantidade de Digitas

Logo após vamos para a função contDigital, onde ela é responsável por imprimir na Serial a quantidade de digitais salva no banco de dados.

//Conta Qtde de Digitais -----------------------------------------------------------------------------
void contDigital(){
    fileDados = SPIFFS.open("/dados.txt","r");              // Abre arquivo dados em modo leitura
    String text = fileDados.readString();                   // Atribui a text o arquivo aberto
    fingerSensor.getTemplateCount();                        // Atribui a "templateCount" a qtde

    //Exibe a quantidade salva
    Serial.print("Digitais cadastradas: ");                 // Imprime na Serial
    Serial.println(fingerSensor.templateCount);             // Imprime na Serial a quantidade salva
    Serial.println("LISTA DOS USUARIOS:");                  // Imprime na Serial
    Serial.println(text);                                   // Imprime na Serial a Lista de Digitais
    fileDados.close();                                      // Fecha arquivo dados
}

Funções Imprime Registros

Então agora vamos para a função pontDigital, onde é responsável por imprimir na Serial todos os registros.

//Imprime Registros ----------------------------------------------------------------------------------
void pontDigital(){
    fileRegistro = SPIFFS.open("/registro.txt","r");        // Abre arquivo em modo de leitura
    Serial.println(fileRegistro.readString());              // Imprime as ID e nomes de cada pessoa
    fileRegistro.close();                                   // Fecha arquvio registro
}

Funções Deleta Digital

Em seguida na função deletaDigital, ela é responsável por deletar uma digital especifica no banco de dados

//Deleta uma Digital ---------------------------------------------------------------------------------
void deleteDigital(){
    Serial.println("Qual a posição para apagar a digital? (1 a 9)");  // Imprime na Serial
    String strLocation = pegaComando();                     // Faz a leitura do comando digitado
    int location = strLocation.toInt();                     // Transforma em inteiro

    if(location < 1 || location > 9){                       // Verifica se a posição é invalida
        Serial.println("Posição inválida");                 // Imprime na Serial
        return;
    }

    if(fingerSensor.deleteModel(location) != FINGERPRINT_OK){ // Apaga a digital na posição location
        Serial.println("Erro ao apagar digital");           // Imprime na Serial
    }
    else{
        Serial.println("Digital apagada com sucesso!!!");   // Imprime na Serial
    }
}

Funções Limpa Banco de dados

Logo após vamos para a função limpaDatabase, onde ela é responsável por apagar todas as informações salva no banco de dados e todos os arquivos.

//Limpa Banco de Dados -------------------------------------------------------------------------------
void limpaDatabase(){
    Serial.println("Tem certeza? (S/N)");                   // Imprime na Serial
    String command = pegaComando();                         // Faz a leitura do comando digitado
    command.toUpperCase();                                  // Coloca tudo em maiúsculo

    if(command == "S" || command == "SIM"){                 // Verifica se foi digitado "S" ou "SIM"
        Serial.println("Apagando banco de digitais...");    // Imprime na Serial

        if(fingerSensor.emptyDatabase() != FINGERPRINT_OK){ // Apaga todas as digitais
            Serial.println("Erro ao apagar banco de digitais"); // Imprime na Serial
        }
        else{
            Serial.println("Banco de digitais apagado com sucesso!!!"); // Imprime na Serial
        }
    }
    else{
        Serial.println("Cancelado");                        // Imprime na Serial
    }
}

E assim finalizamos todo código e explicação referentes ao projeto Leitor Biométrico com SPIFFS.

Resultado do Projeto Leitor Biométrico com SPIFFS


Por fim esse foi o resultado obtido com nosso projeto.

Serial - Leitor Biométrico com SPIFFS

Agradecemos sua Presença


Por fim, espero que tenham gostado e aprendido. Compartilhe com seus colegas e deixe um comentário de qual projeto deveria ser o próximo aqui no Blog da WJ Componentes!!
Enfim estarei deixando os arquivos do código-fonte e Fritzing, software e sites utilizados e deixarei também o GitHub da biblioteca utilizada.
Fique à vontade para tirar suas dúvidas nos comentários.

Software e Sites Utilizados

GitHub das Bibliotecas Utilizadas

Post Relacionados

    Posts mais Recentes

    Julio Cesar Bonow Manoel

    Julio Cesar Bonow Manoel

    Cursando Engenharia da Computação pelo Centro Universitário Facens e atua no desenvolvimento de projetos na WJ Componentes. Participante da equipe de robótica Omegabotz.

    Deixe um comentário

    O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *