Sebuahhobi98

fingerprint_match_esp32

Apr 1st, 2024
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 10.22 KB | None | 0 0
  1. #include <HardwareSerial.h>
  2. #include <fpm.h>
  3.  
  4. FPM finger(&Serial2);
  5. FPMSystemParams params;
  6.  
  7. /* for convenience */
  8. #define PRINTF_BUF_SZ 60
  9. char printfBuf[PRINTF_BUF_SZ];
  10.  
  11. /* This should be equal to the template size for your sensor,
  12.    which can be anywhere from 512 to 1536 bytes.
  13.  
  14.    So check the printed result of readTemplate() to determine
  15.    the correct template size for your sensor and adjust the buffer
  16.    size below accordingly. If this example doesn't work at first, try increasing
  17.    this value, provided you have sufficient RAM.
  18. */
  19. #define TEMPLATE_SZ 1536
  20. uint8_t template_buffer[TEMPLATE_SZ];
  21. #define RXD2 16
  22. #define TXD2 17
  23. void setup()
  24. {
  25.   Serial.begin(57600);
  26.   Serial2.begin(57600, SERIAL_8N1, RXD2, TXD2);
  27.  
  28.   Serial.println("TEMPLATES example");
  29.  
  30.   if (finger.begin()) {
  31.     finger.readParams(&params);
  32.     Serial.println("Found fingerprint sensor!");
  33.     Serial.print("Capacity: "); Serial.println(params.capacity);
  34.     Serial.print("Packet length: "); Serial.println(FPM::packetLengths[static_cast<uint8_t>(params.packetLen)]);
  35.   }
  36.   else {
  37.     Serial.println("Did not find fingerprint sensor :(");
  38.     while (1) yield();
  39.   }
  40. }
  41.  
  42. void loop() {
  43.   Serial.println("\r\nSend any character to enroll a finger...");
  44.   while (Serial.available() == 0) yield();
  45.  
  46.   Serial.println("Searching for a free slot to store the template...");
  47.  
  48.   int16_t fid;
  49.   if (getFreeId(&fid))
  50.   {
  51.     enrollFinger(fid);
  52.   }
  53.   else
  54.   {
  55.     Serial.println("No free slot/ID in database!");
  56.   }
  57.  
  58.   while (Serial.read() != -1);  // clear buffer
  59. }
  60.  
  61. bool getFreeId(int16_t * fid)
  62. {
  63.   for (int page = 0; page < (params.capacity / FPM_TEMPLATES_PER_PAGE) + 1; page++)
  64.   {
  65.     FPMStatus status = finger.getFreeIndex(page, fid);
  66.  
  67.     switch (status)
  68.     {
  69.       case FPMStatus::OK:
  70.         if (*fid != -1) {
  71.           Serial.print("Free slot at ID ");
  72.           Serial.println(*fid);
  73.           return true;
  74.         }
  75.         break;
  76.  
  77.       default:
  78.         snprintf(printfBuf, PRINTF_BUF_SZ, "getFreeIndex(%d): error 0x%X", page, static_cast<uint16_t>(status));
  79.         Serial.println(printfBuf);
  80.         return false;
  81.     }
  82.  
  83.     yield();
  84.   }
  85.  
  86.   Serial.println("No free slots!");
  87.   return false;
  88. }
  89.  
  90. bool enrollFinger(int16_t fid)
  91. {
  92.   FPMStatus status;
  93.   const int NUM_SNAPSHOTS = 2;
  94.  
  95. #if defined(FPM_LED_CONTROL_ENABLED)
  96.   finger.ledOn();
  97. #endif
  98.  
  99.   /* Take snapshots of the finger,
  100.      and extract the fingerprint features from each image */
  101.   for (int i = 0; i < NUM_SNAPSHOTS; i++)
  102.   {
  103.     Serial.println(i == 0 ? "Place a finger" : "Place same finger again");
  104.  
  105.     do {
  106. #if defined(FPM_LED_CONTROL_ENABLED)
  107.       status = finger.getImageOnly();
  108. #else
  109.       status = finger.getImage();
  110. #endif
  111.  
  112.       switch (status)
  113.       {
  114.         case FPMStatus::OK:
  115.           Serial.println("Image taken");
  116.           break;
  117.  
  118.         case FPMStatus::NOFINGER:
  119.           //Serial.println(".");
  120.           break;
  121.  
  122.         default:
  123.           /* allow retries even when an error happens */
  124.           snprintf(printfBuf, PRINTF_BUF_SZ, "getImage(): error 0x%X", static_cast<uint16_t>(status));
  125.           Serial.println(printfBuf);
  126.           break;
  127.       }
  128.  
  129.       yield();
  130.     }
  131.     while (status != FPMStatus::OK);
  132.  
  133.     status = finger.image2Tz(i + 1);
  134.  
  135.     switch (status)
  136.     {
  137.       case FPMStatus::OK:
  138.         Serial.println("Image converted");
  139.         break;
  140.  
  141.       default:
  142.         snprintf(printfBuf, PRINTF_BUF_SZ, "image2Tz(%d): error 0x%X", i + 1, static_cast<uint16_t>(status));
  143.         Serial.println(printfBuf);
  144.         return false;
  145.     }
  146.  
  147.     finger.ledOff();
  148.     Serial.println("Remove finger");
  149.     delay(2000);
  150.     finger.ledOn();
  151.     do {
  152. #if defined(FPM_LED_CONTROL_ENABLED)
  153.       status = finger.getImageOnly();
  154. #else
  155.       status = finger.getImage();
  156. #endif
  157.       delay(200);
  158.     }
  159.     while (status != FPMStatus::NOFINGER);
  160.  
  161.   }
  162.  
  163. #if defined(FPM_LED_CONTROL_ENABLED)
  164.   finger.ledOff();
  165. #endif
  166.  
  167.   /* Images have been taken and converted into features a.k.a character files.
  168.      Now, need to create a model/template from these features and store it. */
  169.  
  170.   status = finger.generateTemplate();
  171.   switch (status)
  172.   {
  173.     case FPMStatus::OK:
  174.       Serial.println("Template created from matching prints!");
  175.       break;
  176.  
  177.     case FPMStatus::ENROLLMISMATCH:
  178.       Serial.println("The prints do not match!");
  179.       return false;
  180.  
  181.     default:
  182.       snprintf(printfBuf, PRINTF_BUF_SZ, "createModel(): error 0x%X", static_cast<uint16_t>(status));
  183.       Serial.println(printfBuf);
  184.       return false;
  185.   }
  186.  
  187.   status = finger.storeTemplate(fid);
  188.   switch (status)
  189.   {
  190.     case FPMStatus::OK:
  191.       snprintf(printfBuf, PRINTF_BUF_SZ, "Template stored at ID %d!", fid);
  192.       Serial.println(printfBuf);
  193.       break;
  194.  
  195.     case FPMStatus::BADLOCATION:
  196.       snprintf(printfBuf, PRINTF_BUF_SZ, "Could not store in that location %d!", fid);
  197.       Serial.println(printfBuf);
  198.       return false;
  199.  
  200.     default:
  201.       snprintf(printfBuf, PRINTF_BUF_SZ, "storeModel(): error 0x%X", static_cast<uint16_t>(status));
  202.       Serial.println(printfBuf);
  203.       return false;
  204.   }
  205.   uint16_t totalRead = readTemplate(fid, template_buffer, TEMPLATE_SZ);
  206.   Serial.print("Total Read: ");
  207.   Serial.println(totalRead);
  208.   Serial.println();
  209.   return true;
  210. }
  211.  
  212. uint16_t readTemplate(uint16_t fid, uint8_t * buffer, uint16_t bufLen)
  213. {
  214.   /* Load the template from the sensor's storage into one of its Buffers
  215.      (Buffer 1 by default) */
  216.   FPMStatus status = finger.loadTemplate(fid);
  217.  
  218.   switch (status)
  219.   {
  220.     case FPMStatus::OK:
  221.       Serial.print("Template "); Serial.print(fid); Serial.println(" loaded");
  222.       break;
  223.  
  224.     case FPMStatus::DBREADFAIL:
  225.       Serial.println(F("Invalid template or location"));
  226.       return false;
  227.  
  228.     default:
  229.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("loadTemplate(%d): error 0x%X"), fid, static_cast<uint16_t>(status));
  230.       Serial.println(printfBuf);
  231.       return false;
  232.   }
  233.  
  234.   /* Inform the sensor that we're about to download a template from that Buffer */
  235.   status = finger.downloadTemplate();
  236.   switch (status)
  237.   {
  238.     case FPMStatus::OK:
  239.       break;
  240.  
  241.     default:
  242.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("downloadTemplate(%d): error 0x%X"), fid, static_cast<uint16_t>(status));
  243.       Serial.println(printfBuf);
  244.       return false;
  245.   }
  246.  
  247.   /* Now, the sensor will send us the template from that Buffer, one packet at a time */
  248.   bool readComplete = false;
  249.  
  250.   /* As an argument, this holds the max number of bytes to read from the sensor.
  251.      Whenever the function returns successfully, it then holds the number of bytes actually read. */
  252.   uint16_t readLen = bufLen;
  253.  
  254.   uint16_t bufPos = 0;
  255.  
  256.   while (!readComplete)
  257.   {
  258.     bool ret = finger.readDataPacket(buffer + bufPos, NULL, &readLen, &readComplete);
  259.  
  260.     if (!ret)
  261.     {
  262.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("readDataPacket(): failed after reading %u bytes"), bufPos);
  263.       Serial.println(printfBuf);
  264.       return 0;
  265.     }
  266.  
  267.     bufPos += readLen;
  268.     readLen = bufLen - bufPos;
  269.  
  270.     yield();
  271.   }
  272.  
  273.   uint16_t totalBytes = bufPos;
  274.  
  275.   /* just for pretty-printing */
  276.   uint16_t numRows = totalBytes / 16;
  277.  
  278.   Serial.println(F("Printing template:"));
  279.   const char * dashes = "---------------------------------------------";
  280.   Serial.println(dashes);
  281.  
  282.   for (int row = 0; row < numRows; row++) {
  283.     for (int col = 0; col < 16; col++) {
  284.       Serial.print("0x");
  285.       Serial.print(buffer[row * 16 + col], HEX);
  286.       Serial.print(", ");
  287.     }
  288.  
  289.     Serial.println();
  290.     yield();
  291.   }
  292.  
  293.   Serial.println(dashes);
  294.  
  295.   Serial.print(totalBytes); Serial.println(" bytes read.");
  296.   return totalBytes;
  297. }
  298.  
  299. bool deleteTemplate(int fid)
  300. {
  301.   FPMStatus status = finger.deleteTemplate(fid);
  302.  
  303.   switch (status)
  304.   {
  305.     case FPMStatus::OK:
  306.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("Deleted ID #%u."), fid);
  307.       Serial.println(printfBuf);
  308.       break;
  309.  
  310.     case FPMStatus::DELETEFAIL:
  311.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("Failed to delete ID #%u."), fid);
  312.       Serial.println(printfBuf);
  313.       return false;
  314.  
  315.     default:
  316.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("deleteTemplate(): error 0x%X"), static_cast<uint16_t>(status));
  317.       Serial.println(printfBuf);
  318.       return false;
  319.   }
  320.  
  321.   return true;
  322. }
  323.  
  324. bool writeTemplate(uint16_t fid, uint8_t * buffer, uint16_t templateSz)
  325. {
  326.   /* Inform the sensor that we're about to upload a template to one of its Buffers
  327.      (Buffer 1 by default) */
  328.   FPMStatus status = finger.uploadTemplate();
  329.  
  330.   switch (status)
  331.   {
  332.     case FPMStatus::OK:
  333.       Serial.println("Starting template upload...");
  334.       break;
  335.  
  336.     default:
  337.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("uploadTemplate(%u): error 0x%X"), fid, static_cast<uint16_t>(status));
  338.       Serial.println(printfBuf);
  339.       return false;
  340.   }
  341.  
  342.   /* One packet at a time, upload the template to that Buffer */
  343.   uint16_t writeLen = templateSz;
  344.   uint16_t written = 0;
  345.   const uint16_t PACKET_LENGTH = FPM::packetLengths[static_cast<uint8_t>(params.packetLen)];
  346.  
  347.   while (writeLen)
  348.   {
  349.     /* the write is completed when we have no more than PACKET_LENGTH left to write */
  350.     bool ret = finger.writeDataPacket(buffer + written, NULL, &writeLen, writeLen <= PACKET_LENGTH);
  351.  
  352.     if (!ret)
  353.     {
  354.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("writeDataPacket(): failed after writing %u bytes"), written);
  355.       Serial.println(printfBuf);
  356.       return false;
  357.     }
  358.  
  359.     written += writeLen;
  360.     writeLen = templateSz - written;
  361.  
  362.     yield();
  363.   }
  364.  
  365.   /* Finally, store the template at the specified location */
  366.   status = finger.storeTemplate(fid);
  367.  
  368.   switch (status)
  369.   {
  370.     case FPMStatus::OK:
  371.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("Template stored at ID %d!"), fid);
  372.       Serial.println(printfBuf);
  373.       break;
  374.  
  375.     case FPMStatus::BADLOCATION:
  376.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("Could not store in that location %d!"), fid);
  377.       Serial.println(printfBuf);
  378.       return false;
  379.  
  380.     default:
  381.       snprintf_P(printfBuf, PRINTF_BUF_SZ, PSTR("storeModel(%u): error 0x%X"), fid, static_cast<uint16_t>(status));
  382.       Serial.println(printfBuf);
  383.       return false;
  384.   }
  385.  
  386.   return true;
  387. }
Tags: Arduino ESP32
Add Comment
Please, Sign In to add comment