Download a template from fingerprint sensor

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
lupine37
 
Posts: 1
Joined: Thu Nov 14, 2019 10:02 am

Download a template from fingerprint sensor

Post by lupine37 »

Hi, I have a project that uses jm101 fingerprint sensor and esp32 as the controller. In my project I am using adafruit fingerprint library in adruino ide. The library helped me allot to learn about the fingerprint sensor and how it works. The program was to download template from esp32, which I saved in the flash memory, to character buffer2 in the fingerprint sensor. The template was to be compared to the template created and stored in character buffer1. I could not find the code to download and match the template to the fingerprint so I tried to add some code in library.

Code: Select all

uint8_t Adafruit_Fingerprint::getModel(uint8_t bufferNo) {
  uint16_t i = 0;
  uint8_t k = 0;
  uint8_t j = 0;
  TemplateLength = 0;
  memset(fingerTemplate, 0xff, 960);
  uint16_t maxPacketSize = getMaxPacketSize();
  GET_CMD_PACKET(FINGERPRINT_UPLOAD, bufferNo);
  while (packet.type != FINGERPRINT_ENDDATAPACKET){
    packet.checksum = 0;
    uint8_t p = getStructuredPacket(&packet);
    // if (packet.length >= maxPacketSize) {
      TemplateLength += (packet.length - 2);
      for (i = i; i < TemplateLength; i++){
        if (k > 0){
          j = (i) % (k * packet.length);
        }
        else{
          j = i;
        }
        fingerTemplate[i] = packet.data[j];
        //Serial.print(fingerTemplate[i], HEX); Serial.print(" ");
      }
      Serial.println();
      k++;
    // }
  }
  return packet.data[0];
}

/**************************************************************************/
/*!
    @brief   Ask the sensor to delete a model in memory
    @param   location The model location #
    @returns <code>FINGERPRINT_OK</code> on success
    @returns <code>FINGERPRINT_BADLOCATION</code> if the location is invalid
    @returns <code>FINGERPRINT_FLASHERR</code> if the model couldn't be written to flash memory
    @returns <code>FINGERPRINT_PACKETRECIEVEERR</code> on communication error
*/

uint8_t Adafruit_Fingerprint::downloadModel(uint16_t tempLength) {
  uint8_t fingerDownloadTemplate[tempLength];
  memset (fingerDownloadTemplate, 0xff, tempLength);
  uint16_t maxPacketSize = getMaxPacketSize();
  GET_CMD_PACKET(FINGERPRINT_DOWNCHAR, 0x02);
  // if (packet.data[0] == FINGERPRINT_OK) {
  //   Serial.println("Ready to transfer");
  // }
  // else if (packet.data[0] == FINGERPRINT_PACKETRECIEVEERR) {
  //   Serial.println("Error when receiving package");
  //   return FINGERPRINT_PACKETRECIEVEERR;
  // }
  // else if (packet.data[0] == FINGERPRINT_PACKETRESPONSEFAIL) {
  //   Serial.println("Failed to receive the following data packeges");
  //   return FINGERPRINT_PACKETRESPONSEFAIL;
  // }
  // uint8_t packetNbr = tempLength / maxPacketSize;
  // Serial.println(fingerTemplate[0:128]);
  if (packetNbr <= 1) {
    Adafruit_Fingerprint_Packet packet(FINGERPRINT_ENDDATAPACKET, tempLength, fingerTemplate); \
    writeStructuredPacket(packet);
  }
  else {
    uint8_t m = 1;
    uint8_t y = 0;
    uint8_t z = 0;
    uint8_t data[maxPacketSize];
    while (m < packetNbr){
      uint16_t startl = (m-1) * maxPacketSize;
      uint16_t endl = startl + maxPacketSize;
      for (int n = startl; n < endl; n++) {
        if (z > 0){
        y = (n) % (z * maxPacketSize);
        }
        else{
          y = n;
        }
        data[y] = fingerTemplate[n];
        fingerDownloadTemplate[n] = fingerTemplate[n];
        // Serial.print(data[y]); Serial.print(" ");
      }
      Adafruit_Fingerprint_Packet packet(FINGERPRINT_DATAPACKET, sizeof(data), data); \
      writeStructuredPacket(packet);
      z++;
      m++;
    }
    uint16_t startl = (m-1) * maxPacketSize;
      uint16_t endl = startl + maxPacketSize;
      for (int n = startl; n < endl; n++) {
        y = (n) % (z * maxPacketSize);
        data[y] = fingerTemplate[n];
        fingerDownloadTemplate[n] = fingerTemplate[n];
      }
      Adafruit_Fingerprint_Packet packet(FINGERPRINT_ENDDATAPACKET, sizeof(data), data); \
      writeStructuredPacket(packet);
  }
  getModel(0x02);
  Serial.println(TemplateLength);
  for (int m = 0; m < tempLength; m++) {
    Serial.print(fingerDownloadTemplate[m], HEX);
  }
  Serial.println();
  for (int m = 0; m <TemplateLength; m++) {
    Serial.print(fingerTemplate[m], HEX);
  }
  UploadDownloadState = areEqual(fingerTemplate, fingerDownloadTemplate, tempLength);

}

bool Adafruit_Fingerprint::areEqual(uint8_t arr1[], uint8_t arr2[], uint16_t n) {
  for (int i = 0; i < n; i++) {
    if (arr1[i] != arr2[i]) {
      Serial.println(i);
      return false;
    }
  }
  return true;
}
I also changed the code to getStructurePacket so I can remove the checksum from the data.

Code: Select all

uint8_t Adafruit_Fingerprint::getStructuredPacket(Adafruit_Fingerprint_Packet * packet, uint16_t timeout) {
  uint8_t byte;
  uint16_t idx=0, timer=0, sum = 0;
  uint8_t recvData[512];

  while(true) {
    while(!mySerial->available()) {
      delay(1);
      timer++; 
      if( timer >= timeout) {
#ifdef FINGERPRINT_DEBUG
	Serial.println("Timed out");
#endif
	return FINGERPRINT_TIMEOUT;
      }
    }
    byte = mySerial->read();
    // Serial.print(byte, HEX);
#ifdef FINGERPRINT_DEBUG
    Serial.print("<- 0x"); Serial.println(byte, HEX);
#endif
    switch (idx) {
      case 0:
        if (byte != (FINGERPRINT_STARTCODE >> 8)) 
	  continue;
        packet->start_code = (uint16_t)byte << 8;
        break;
      case 1:
        packet->start_code |= byte;
        if (packet->start_code != FINGERPRINT_STARTCODE) 
	  return FINGERPRINT_BADPACKET;
        break;
      case 2:
      case 3:
      case 4:
      case 5:
        packet->address[idx-2] = byte;
        break;
      case 6: 
	packet->type = byte; 
	break;
      case 7: 
	packet->length = (uint16_t)byte << 8; 
	break;
      case 8: 
	packet->length |= byte; 
	break;
      default:
        recvData[idx-9] = byte;
        if((idx-8) == packet->length){
          sum = sum + packet->type + packet->length;
          packet->checksum |= byte;
          // Serial.println();
          // Serial.println(sum, HEX);
          // Serial.println(packet->checksum, HEX);
          if (sum == packet->checksum) {
            for (int i = 0; i < (packet->length); i++) {
              packet->data[i] = recvData[i];
            }
            return FINGERPRINT_OK;
          }
        }
        else{
          if ((idx-8) <= (packet->length - 2)){
          sum = sum + byte;
        }
          else{
            packet->checksum = (uint16_t)byte << 8;
          }
        }
        break;
    }
    idx++;
  }
  // Shouldn't get here so...
  return FINGERPRINT_BADPACKET;
}
The arduino code:

Code: Select all

#include "EEPROM.h"
#include <Adafruit_Fingerprint.h>

HardwareSerial mySerial(2);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

uint8_t getFingerprintTemplate() {
  uint16_t i = 0;
  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.print("Unknown error "); Serial.println(p);
      return p;
  }
  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 by image2Tz");
      return p;
  }
 // int k = 1;
 // int j = 0;
 // while (k <= 6) {
  // for (j = j; j < (128 * k); j++){
  //   Serial.print(EEPROM.read(j), HEX); Serial.print(" ");
  //  }
  // Serial.println();
  // k++;
  // }
    
  for (i = 0; i < 768; i++) {
    finger.fingerTemplate[i] = EEPROM.read(i);
  }
  Serial.println();
  finger.downloadModel(i);
  Serial.println(finger.UploadDownloadState);
//  Serial.println(p);

//  p = finger.compareCharacteristics();
//  switch(p) {
//    case FINGEPRINT_OK:
//      Serial.println(
//  }
//  Serial.println(finger.accuracyScore);
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("\n\nAdafruit finger detect test");

  if (!EEPROM.begin(960)){
    Serial.println("failed to initialise EEPROM"); delay (1000000);
    }
  // 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) { vTaskDelay(pdMS_TO_TICKS(1)); }
  }

  finger.getTemplateCount();
  Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates");
//  finger.readSysPara();
//  Serial.print("The sys parameters are "); Serial println(finger.
  Serial.println("Waiting for valid finger...");
}

void loop() {
  // put your main code here, to run repeatedly:
  getFingerprintTemplate();
  vTaskDelay(pdMS_TO_TICKS(50)); 
}
I was able to download the fingerprint data to the fingerprint sensor and even be able to upload if again to the esp to see the data agaiThe issue is that the template changes after I upload it for the second time from the fingerprint. I need help understanding what is happening to template. Thank you.
The result.

Code: Select all

Image taken
Image converted
768
33561E0120178000000000000000000000000000000000000000A070730003F33333FCFCF3FFFFFEAAAAAAAAAAAAA99555555511514441504000000000000000000000000000000000000000000000033E7532437E40A7829E12AD289E67B29C5E21ACEA5F28B0801F42B6469F403ECC5F25404FFF1142FFF553B47BC48BDCAFC213A503D4E414AFD1B9B123A34AD81BA2D38C67A273A4FFA2EC0EBA322B543B33BDC5B5E3AC8B9239C6B56564287F6229AE9174031C4975BC19E745E3D9EB55F4187755D3EC8D200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084D80801E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008AD80801EFB3FE8EB0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
33561E0120178000000000000000000000000000000000000000A070730003F33333FCFCF3FFFFFEAAAAAAAAAAAAA99555555511514441504000000000000000000000000000000000000000000000035133E7532437E40A7829E12AD289E67B29C5E21ACEA5F28B0801F42B6469F403ECC5F25404FFF1142FFF553B47BC48BDCAFC213A503D4E414AFD1B9B123A34AD81BA2D38C67A273A4FFA2EC0EBA322B543B33BDC5B5E3AC8B9239C6B56564287F6229AE9174031C4975BC19E745E3D9EB55F4187755D3EC8D20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002338408843084D80801E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054C8408843840552608AD80801EFB3FE8EB000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000128
0


Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”