Write template on Fingerprint sensor R305/R307

Post the full true output of the example - not just an extract of what you think is meaningful

Are you running this on a UNO or MEGA ?

The stray FFFFFFFFFFF you see are just there because buffer is initialized with plenty of FF in the library

They seem to use data packets of 256 bytes but seems what you get back is actually the 128 bytes version

having multiple data packet is not impossible as you might not be able to fit all the data in one frame, so you should expect when you send a command to get many answer and at some point the last frame will include a

End of Data packet

command so that you know it’s the last one

there is plenty of garbage so would need to see exactly the output on the Serial console...

The 3 frames you see are

FFFFFFFFFFFFFFFFFF0165159200FFFEFFFEFFFEFFFEF80EC00680008000800080000000000000000000000000008000000000000000000000000000000020AB78324242982B0D


[b]EF01[/b]
[u]FFFFFFFF[/u]
02		Data packet
0082		length of package = command packets + data packets + CKSUM[color=green] --> 128 bytes + 2 for checksum[/color]
5E1F56592A3ED8D9674201F90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
056C		CKSUM ([color=green]this one is OK[/color])

[b]EF01[/b]
[u]FFFFFFFF[/u]
02		Data packet
0082		length of package = command packets + data packets + CKSUM[color=green] --> 128 bytes + 2 for checksum[/color]
03015E169700FFFEFFFEFFFEFF1EC006C002C0008000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFF98415E1BA41ADE49A4431E6BA481FE2E26047E60AB033E0AAD845E59B2DC5E45B39ADE0AB604BE09BADC5E1F3D9ABE553F04FE48C29ADE3898031F26AD843F53AF44FF71B81F9F
[color=red]2AF9[/color]		CKSUM ([color=red]this one seems wrong[/color])

[b]EF01[/b]
[u]FFFFFFFF[/u]
08		End of Data packet
0082		length of package = command packets + data packets + CKSUM[color=green] --> 128 bytes + 2 for checksum[/color]
39C306376297D71C659B2C7C2E39441600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0618		CKSUM ([color=green]this one is OK[/color])


FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

The attachment shows template read for 2 different fingerprints.

However when I am trying to write the same template on other location...the serial trace does not show garbage values but cool term shows. And after sending the 4 chunks of template...finally when store command is used...reply is 01 ...error when receiving data.

Extract.txt (2.4 KB)

Rewrite.txt (391 Bytes)

Issue resolved...I am now able to write template from external source. You can ignore the above post.

Would be fair to explain what you did and how you solved it for everyone having the same question in the future

1 Like
  1. First step to extract fingerprint from sensor is to load the desired template number to either buffer 1 or 2.
  2. Once the template is loaded into buffer, read the template from buffer.
  3. Template size might vary, hence, the whole template might be broken down into multiple bits and part.
  4. This template can now be stored onto other device and can be reused to write the same template into similar sensor.
  5. Commands for all the above functions are standard and can be viewed in the document shared in this blog post above.
  6. Example of template extracted can also be viewed in the text files shared in the previous post.

Thx - makes sense :slight_smile:

Hi,

Trying to send data over serial. The data is getting transmitted as ASCII equivalent when read over the other arduino with code shared by you in earlier post(one which displays the HEX values of the data received over serial). However, correct HEX value get displayed on the serial monitor of the arduino on which this code is runing.

/*
  SD card read/write

 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

 created   Nov 2010
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe

 This example code is in the public domain.

 */
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#include <SPI.h>
#include <SD.h>
int i;
String s;
char a[1]={16};
int b=20;
File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  mySerial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("ABCDEF.txt", FILE_WRITE);

  // re-open the file for reading:
  myFile = SD.open("ABCDEF.txt");
  if (myFile) {
    Serial.println("ABCDEF.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      i=myFile.read();
      
      if (isDigit(i)) {
      // convert the incoming byte to a char and add it to the string:
      s += (char)i;
    }

    if (i == '\n') {
      int p = s.toInt();
      Serial.print(p,HEX);
      mySerial.print(p,HEX);
      p=atoi(p);
      mySerial.print(p,HEX);
      s = "";
      p = "";
      //mySerial.print(32,HEX);
    }
    
      //Serial.write(r);
      //mySerial.write(r);
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening ABCDEF.txt");
  }
}

void loop() {
  // nothing happens after setup
  //mySerial.write("1");
}

ABCDEF.TXT (1.02 KB)

Understood my mistake...should had used Serial.write instead of Serial.print

:slight_smile: :slight_smile:

@nimit393, Can you show us, the code for write template on sensor, please?

nimit393:

  1. First step to extract fingerprint from sensor is to load the desired template number to either buffer 1 or 2.
  2. Once the template is loaded into buffer, read the template from buffer.
  3. Template size might vary, hence, the whole template might be broken down into multiple bits and part.
  4. This template can now be stored onto other device and can be reused to write the same template into similar sensor.
  5. Commands for all the above functions are standard and can be viewed in the document shared in this blog post above.
  6. Example of template extracted can also be viewed in the text files shared in the previous post.

J-M-L:
Post the full true output of the example - not just an extract of what you think is meaningful

Are you running this on a UNO or MEGA ?

The stray FFFFFFFFFFF you see are just there because buffer is initialized with plenty of FF in the library

They seem to use data packets of 256 bytes but seems what you get back is actually the 128 bytes version

having multiple data packet is not impossible as you might not be able to fit all the data in one frame, so you should expect when you send a command to get many answer and at some point the last frame will include a

End of Data packet

command so that you know it’s the last one

there is plenty of garbage so would need to see exactly the output on the Serial console...

The 3 frames you see are

FFFFFFFFFFFFFFFFFF0165159200FFFEFFFEFFFEFFFEF80EC00680008000800080000000000000000000000000008000000000000000000000000000000020AB78324242982B0D

EF01
FFFFFFFF
02 Data packet
0082 length of package = command packets + data packets + CKSUM --> 128 bytes + 2 for checksum
5E1F56592A3ED8D9674201F90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
056C CKSUM (this one is OK)

EF01
FFFFFFFF
02 Data packet
0082 length of package = command packets + data packets + CKSUM --> 128 bytes + 2 for checksum
03015E169700FFFEFFFEFFFEFF1EC006C002C0008000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFF98415E1BA41ADE49A4431E6BA481FE2E26047E60AB033E0AAD845E59B2DC5E45B39ADE0AB604BE09BADC5E1F3D9ABE553F04FE48C29ADE3898031F26AD843F53AF44FF71B81F9F
2AF9 CKSUM (this one seems wrong)

EF01
FFFFFFFF
08 End of Data packet
0082 length of package = command packets + data packets + CKSUM --> 128 bytes + 2 for checksum
39C306376297D71C659B2C7C2E39441600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0618 CKSUM (this one is OK)

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

This is my first comment so please forgive if I do some mistake.
I'm using Adafruit Fingerprint sensor library with Arduino Uno and I'm getting the same output of show_fingerprint_templates example code i.e. the 3 frames you've pointed to.

Now I want to know that

Firstly : how did you came to conclusion about which one is ( OK) and which one is (WRONG). Like in the manual/datasheet it is stated that CKSUM is equal to 'the arithmetic sum of package identifier, package length and
all package contents. Overflowing bits are omitted. high byte is
transferred first'.

Secondly : What will be the final correct template if we consider the above example?

Please help me I'm struggling with this problem of identifying the correct template (from past few weeks) so that I can store it and later upload back the correct template to the sensor.

Thank You

this was what the OP posted

FFFFFFFFFFFFFFFFFF0165159200FFFEFFFEFFFEFFFEF80EC00680008000800080000000000000000000000000
008000000000000000000000000000000020AB78324242982B0DEF01FFFFFFFF0200825E1F56592A3ED8D9674201F900000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000056CEF01FFFFFFFF0200820
3015E169700FFFEFFFEFFFEFF1EC006C002C0008000000000000000000000000000000000000000000000000
000FFFFFFFFFFFFFFFFFFFFFF98415E1BA41ADE49A4431E6BA481FE2E26047E60AB033E0AAD845E59B2DC5E4
5B39ADE0AB604BE09BADC5E1F3D9ABE553F04FE48C29ADE3898031F26AD843F53AF44FF71B81F9F2AF9EF0
1FFFFFFFF08008239C306376297D71C659B2C7C2E3944160000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000618FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

as the output of his request. in that blurb or data we can recognize 3 frames starting with EF01

I color coded the format of a frame as:
data to be ignored
EF01
ADDER --> Default value is 0xFFFFFFFF
package identifier --> describe what type of information is in the package
length --> length of package
The actual data
check sum

FFFFFFFFFFFFFFFFFF0165159200FFFEFFFEFFFEFFFEF80EC006800080008000800000000000000
00000000000008000000000000000000000000000000020AB78324242982B0D
EF01FFFFFFFF020082
5E1F56592A3ED8D9674201F9000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000
056C
EF01FFFFFFFF020082
03015E169700FFFEFFFEFFFEFF1EC006C002C000800000000000000000000000000000000000000
0000000000000FFFFFFFFFFFFFFFFFFFFFF98415E1BA41ADE49A4431E6BA481FE2E26047E60AB033E0AAD845
E59B2DC5E45B39ADE0AB604BE09BADC5E1F3D9ABE553F04FE48C29ADE3898031F26AD843F53AF44FF71B81F9F
2AF9
EF01FFFFFFFF080082
39C306376297D71C659B2C7C2E394416000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000
0618
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

so we see we have 3 frames, the first two are of type 02, meaning 'Data packet' and the last one is of type 08 which means 'End of Data packet'. (01 would be a "Command packet", 07 would be an "Acknowledge packet")

we then see that the length of package is 0x0082(hex) which is 130 in decimal
The length of the packet is composed of the length of the data + the 2 bytes for the checksum --> 128 bytes + 2 for checksum = 130 --> so we have 128 bytes of data, which will be represented as 256 ASCII symbols for the data and 2 bytes for the checksum represented by 4 ASCII symbols (theoretical Max length is 256 bytes so the library creates large buffers just in case but here we get the 128 byte frames).

we then have the data followed by the checksum on 16 bits

To calculate the checksum the documentation states it's the arithmetic sum of package identifier, package length and all package content with Overflowing bits being omitted

package ID = 1 byte
package length = 2 bytes
package content = we have seen above it's 128 bytes

so to run the checksum we need 128+2+1 = 131 bytes, or 262 characters starting at the package ID

So you need to take the package ID, length and content and sum all the numeric value represented by each byte, so you need to read 2 ASCII symbols, high side first, build a byte value and add to the sum in a 16 bit unsigned variable ignoring overflow.

In the first example above this would be the stream of data

0200825E1F56592A3ED8D9674201F90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

if you dump that into this test code

void getHexBufferCKSum()
{
  uint16_t cksum = 0;
  uint16_t lsb = 0, hsb = 0;
  boolean waitingForHigh = true;
  Serial.println(F("Enter HexBuffer (0..9 or A..F all caps):"));
  unsigned int nbBytes = 0;
  unsigned int nbCars = 0;
  while (1) {
    if (Serial.available()) {
      int r = Serial.read();
      if ((r != -1) && (r != '\n')) { // ignore and terminates on '\n'
        if ((r != '\r') && (((r >= '0') && (r <= '9')) || ((r >= 'A') && (r <= 'F')))) { // ignore '\r', handle only 0 to 9 and A to F
          uint8_t v;
          if ((r >= '0') && (r <= '9')) v = r - '0';
          else v = r - 'A' + 10;
          if (waitingForHigh) {
            hsb =  v;
          } else {
            lsb = v;
            cksum += 16 * hsb + lsb;
            nbBytes++; // got a full byte
          }
          waitingForHigh = !waitingForHigh;
          nbCars++;
        }
      } else break;
    }
  }

  Serial.print(F("received "));  Serial.print(nbCars);
  Serial.print(F(" characters ("));  Serial.print(nbBytes);
  Serial.print(F(" bytes), cksum is ")); Serial.println(cksum, HEX);
  if (nbCars != 2 * nbBytes)   Serial.println(F("*** received weird number of characters, check input ***"));
  Serial.println(F("-------------------"));

}

void setup() {
  Serial.begin(115200);
}

void loop() {
  getHexBufferCKSum();
}

you will see in your Serial console (set at 115200 bauds / sending NL to terminate)

[color=purple]Enter HexBuffer (0..9 or A..F all caps):
received 262 characters (131 bytes), cksum is 56C[/color]

So you can see that there is ineed 262 characters received and 56C(hex) is indeed the check sum 056C we had received for the first package

if you run the data for the third package you will see in your Serial console

[color=purple]Enter HexBuffer (0..9 or A..F all caps):
received 262 characters (131 bytes), cksum is 618
[/color]

So you can see that there is ineed 262 characters received and 618(hex) is indeed the check sum 0618 we had received for the third package

but if you run that for the second package, you will see in your Serial console

[color=purple]Enter HexBuffer (0..9 or A..F all caps):
received 262 characters (131 bytes), cksum is 359D[/color]

So you can see that there is ineed 262 characters received BUT 359D(hex) is NOT the check sum 2AF9 we had received for the third package.. So something weird there...

Thank You so much. You've helped me a lot
in understanding the dynamics and now I can work with peace as now I know that I'm headed in the right direction.

Thank You

One final thing I want to ask that if I'm writing template back to the sensor, I will be following the steps below. Can you point out if any mistake you think these points have:-

  • Since total size of template is 512 bytes, create two data frames containing 128 bytes of data each.
  • Send DownChar command first to the sensor and receive ready to send from sensor.
  • Start sending first data frame with 128 higher bytes and send data in Big Endian form i.e. higher byte first.
  • Now send the second data frame with package identifier as 'End of Data' in similar fashion
  • The above steps successfully downloads the template to the desired buffer which was mentioned while sending DownChar command in step 2.
  • Now store buffer to desired pageID.

These are the steps I will be following.

dhananjayaggarwal:
Since total size of template is 512 bytes, create two data frames containing 128 bytes of data each.

hum... 2 x 128 is not 512....

you can see above that extracting one profile actually required 3 frames

so you probably need to build the right number of frames based on what was actually received from the command to upload to the computer, and play that back the other way.

I'm on the go and don't have the device available so can't test anything - but that's how I would explore that

J-M-L:
you can see above that extracting one profile actually required 3 frames

This point is where all I got confused. The Adafruit library of show_fingerprint_templates extracts the total of final 512 bytes out of which one frame is received as faulty always.

Also these 512 bytes of data contains other parts of frame like header, package identifier, package length, content, cksm.

Whereas the specification of sensor states that size of each template is 512 bytes. So should I keep the lower bytes as 0x00 to complete the 512 bytes of template size? Or I should just upload the 256 bytes which are OK out of three frames received.

I am really feeling stupid to ask these questions and really sorry for it. But I've went through manual multiple times and unable to find details about this.
Thank you for giving time.

I haven't done it as I did not have the need, just looking at the spec like you.

@nimit393 seems to say it has done it, but seems missing in action and refused to post his code... so up to you to reinvent the wheel

would need to explore

Still you've helped me a lot. I would definitely share if I got a success in it.
Thank you :slight_smile:

dhananjayaggarwal:
I would definitely share if I got a success in it.

would be good for the community! thx +1 karma as encouragement

Hello.
Need help with this issue.
Is the topic still active?