Sparkfun Fingerprint Scanner "FIM5360N-LV"

Hey Guys, so i've build a little magnetic card reader for my house door, witch works fine, but now i've decited to Update it to a fingerprint reader, so i bought a fingerprint reader (FIM5360N-LV) at Sparkfun, my problem now is that i don't really know too much about Serial Comunication, and it seams to be pretty complicated... So a wanted to ask you guys if one of you maybe has an Example Code or could write one for me? It basically only needs to be able to destinguish between differint Users and well i guess it would also need to be able to Enroll and Delete Fingerprint somehow, maybe with a comand over the Serial Port or something?! From there on i guess i can Modify the Code to do the same the Card Reader used to do...

Here are the Links to the Product Page, Datasheet, etc.

Fingerprint Scanner - SEN-08839 - SparkFun Electronics <----- Product Page
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Biometric/FIM5360_DataSheet_v1.04.pdf <----- Datasheet
http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Biometric/EN%20FIM%20ComProtocol%20V2.01.pdf <----- Serial Interface

Well hopefully someone can help me out,
Thank you in advance!

Regards, Delphiño

Looks like, by default, it has 2 outputs and 3 inputs:

GPIO0: Output high when authentication, registration and deletion are succeeded.
GPIO1: Output high when authentication, registration and deletion are failed.
GPIO2: Do registration when the port level goes from high to low.
GPIO3: Do deletion when the port level goes from high to low.
GPIO4: Do identification when the port level goes from high to low.

On the 9-pin connector the signals are:
1: +5V
2: Serial Receive (DO NOT USE WITHOUT A LEVEL SHIFTER)
3: Serial Transmit (DO NOT USE WITHOUT A LEVEL SHIFTER)
4: GPIO0
5: GPIO1
6: GPIO2
7: GPIO3
8: GPIO4
9: Ground

Hook the +5V, Four I/O pins, and Ground to the Arduino.
Pull one of the output pins LOW to Register, Delete, or Identify a fingerprint.
Look for a high pulse on GPIO0 for success or GPIO1 for failure.

Well, yeah i actually already tried that, and it workt with the I/O Pins, the only problem though is that the Arduino also has to be able to distinguish between different Users, who at certain Times are allowed or not allowed to come in, and i obviously dont want to have do Delete and Enroll everybody again every time i want to allow/forbid someone to com in... Also i need to be able to Delete only one particular User by his ID, not having to Delete every single one, and then having to Enroll everybody else again...

And about the RX and TX lines, i've already asked the Sparkfun support Team about that, and they already told me about it comunicating with RS-323 signals and that i would need a Shifter (witch i also already bought by now), and i've read something about the Arduino and the Fingerprint Reader not being the same Endian, that their Backwords, although i don't quite know what that means yet... :~ Ah... It's all stil pretty complicated for me, i've read a few Wikipedia texts about Binary stuff and Serial Comunication but i'm stil a little confused about all the most significant bit, least significant bit, and all that stuff, and i kind of stil don't have a clue about what to write in the Arduino Programming Invironment so the Fingerprint Reader does what a want it to...
I was hoping maybe if i have some Example Code i could try reading it over and over again and try to understand it a little to be able modify it...

God :~ :~ :~ 000110101101011010 :~ :~ :~

Well thanks for your answer anyhow, maybe you could try explaining it to me, but i am kind of worried me Head will explode :smiley:

I can help with the Endian stuff.

If I told you,
00111001
what number is that (in decimal)? Is it 57 or 156? That's the difference between the Endians - One has the "least significant bit" (the one's place) first, and the other has the "most significant bit" (the 128/132768/2147483648's place, depending on the size of the number).

Big Endian is where
LOW then LOW then HIGH then HIGH, HIGH, LOW, LOW, HIGH
means 57, Little Endian is where it means 156.

So, ASSUMING (I'm not sure if it is...) the scanner is Big Endian and the Arduino is Little Endian, when you say

Serial.write(0x8B);

the scanner receives 0xD1!

Do you understand the packet structure described on page 8 of the serial interface PDF?

Sorry for the late response...
Thanks for the explanation!
First i didn't get it, but after seaching in Google for a while i think i got it.
Basically if the Arduino is Little Endian and the Scanner is Big Endian, the Arduino hast to send every thing backwords so the Scanner understands it, for example if i want to send 0x33, i have to send 0xCC so the Scanner gets it, is that right?!
Well, anyhow i tried writting i little code that was supposed to send an Enroll or Identefy comand to the Scanner, because that way i can see if the Scanner got it, when the light on the Scanner goes on...
I tried this:

void setup() {
  delay(5000);
  Serial.begin(9600);
  Serial.print(0x7E);
  Serial.print(0x000000CC);
  Serial.print(0x00000000);
  Serial.print(0x00000000);
  Serial.print(0x00000058);
  Serial.print(0x00000000);
  Serial.print(0x00000058);
}

void loop() {
}

But the Scanner didn't react at all...
I just don't know what i am supposed to write so the Arduino does what i want it to...
And it won't get better when i start trying to recieve data from the Scanner, with all the

if (Serial.available() > 0) {}

and that stuff witch to me seams alot more complicated...
But well, i guess i'll have to all that step by step...

Well could anybody try correcting the code or explaining why it does not work to me?

Thanks again... :slight_smile:

P.S. No i don't really understand the packet structure explained on page 8 of the Serial Interface PDF (at least not completely), i basically just tried guessing a little... Witch obviously didn't work to well :smiley:

Hello,

I have the same problem with you. I don't understand nothing about serial communication. i am trying to find an example code. I am new in all this and i have a project to finish. plz help :frowning:

You should probably start with the CMD_REQUEST_CONNECTION command. Once you have that working and you get a valid response back you can go on to the more complex commands.

Command: 0x01
Param1 : 0
Param2: 0
Data Size: 0
Error Code: 0

I think that when you put it into a packet it will look like this:

byte RequestConnection[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x01,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x00,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x01   // Header Checksum = 1
};

Then you send it to the device with a loop:

NewSoftSerial FingerprintReader(2,3);  // Use pins 2 and 3 for serial I/O to reader
FingerprintReader.begin(9600);
for (int i=0; i<(sizeof RequestConnection / sizeof RequestConnection[0]); i++)
    {
    FingerprintReader.print(requestConnection[i], BYTE);
    }

After you send that you should take any characters the fingerprint reader has to send and display then on the Serial Monitor as Hex:

void loop()
    {
    if (FingerprintReader.available())
        {
        Serial.print(FingerprintReader.read(), HEX);
        Serial.print(" ");
        }
    }

Then you can see if the result is correct:
7e 0 0 0 1 0 0 0 1 0 0 0 A 0 0 0 0 0 0 0 0 0 0 0 C

The first 0 0 0 1 is an echo of the CMD_REQUEST_CONNECTION command.
The second 0 0 0 1 is the RESULT_SUCCEEDED result
The 0 0 0 A is the count of registered fingerprints (assuming you has 10)
The eight 0's after that are the Data Size and Error Code
The 0 0 0 C at the end is the header checksum. If you don't have 10 users the checksum will be different.

Thank you so much for the help. i try that, but nothing found on serial monitor :~

Can i ask you something else?

I wrote the other code:

byte VerifyFp[] = {
0x7e, // Start Character
0x00, 0x00, 0x00, 0x11, // Command = 1
0x00, 0x00, 0x00, 0x00, // Param1 = 0
0x00, 0x00, 0x00, 0x00, // Param2 = 0
0x00, 0x00, 0x00, 0x0B, // Data Size = 0
0x00, 0x00, 0x00, 0x00, // Error Code = 0
0x00, 0x00, 0x00, 0x1C // Header Checksum = 1
};

byte IdentifyFp[] = {
0x7e, // Start Character
0x00, 0x00, 0x00, 0x12, // Command = 1
0x00, 0x00, 0x00, 0x00, // Param1 = 0
0x00, 0x00, 0x00, 0x00, // Param2 = 0
0x00, 0x00, 0x00, 0x00, // Data Size = 0
0x00, 0x00, 0x00, 0x00, // Error Code = 0
0x00, 0x00, 0x00, 0x12 // Header Checksum = 1
};

byte DeleteFp[] = {
0x7e, // Start Character
0x00, 0x00, 0x00, 0x22, // Command = 1
0x00, 0x00, 0x00, 0x00, // Param1 = 0
0x00, 0x00, 0x00, 0x00, // Param2 = 0
0x00, 0x00, 0x00, 0x0B, // Data Size = 0
0x00, 0x00, 0x00, 0x00, // Error Code = 0
0x00, 0x00, 0x00, 0x2D // Header Checksum = 1
};

byte RegisterFp[] = {
0x7e, // Start Character
0x00, 0x00, 0x00, 0x33, // Command = 1
0x00, 0x00, 0x00, 0x00, // Param1 = 0
0x00, 0x00, 0x00, 0x00, // Param2 = 0
0x00, 0x00, 0x00, 0x1B, // Data Size = 0
0x00, 0x00, 0x00, 0x00, // Error Code = 0
0x00, 0x00, 0x00, 0x4E // Header Checksum = 1
};

now i will write for all commands in void loop or i have to write other void ? sorry for this question :frowning:

troublebuble:
Thank you so much for the help. i try that, but nothing found on serial monitor :~

Until you get a proper response for the RequestConnection command you will not be able to use any other command. Let me know when you get it working.

ok i wrote the code and upload on arduino programma. My leds blinks but nothing shows on serial monitor.

in my circuit i have :

pin1 3.3v
pin2 tx
pin3 rx
pin4 ground
pin5 ground
pin6 3.3v
pin7 3.3v
pin8 3.3v
pin9 ground.

But nothing. I am sooooooo confused.

Note that the datasheet says the serial I/O is done at RS232 levels +/-3 to +/-12V and not TTL levels 0-5V. You will need a level shifter such as the MAX232 to convert the data levels.

Maybe this is the problem. I will add Max232 and i will tell you.

Thank you sooooooo much for your time.

Thanks you two, for breaking the disturbing silence here in this thread :smiley:

Ok, then i guess i was writing complete nonsense in my test before hmm?!
Anyhow, i tried putting your (johnwasser) code together and testing it, but couldn't compile it though...
First i got this: 'requestConnection' was not declared in this scope, i assumed that was because of the "r" instead of "R" in your code, so i tried compiling it with a "R" but then he gave me this: 'FingerprintReader' was not declared in this scope and markt the line "if (FingerprintReader.available()) {" in yellow.
Well and that's where i stopped understanding what the compiler wants me to change... :frowning:

Here is what i tried uploading:

#include <NewSoftSerial.h>

byte RequestConnection[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x01,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x00,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x01   // Header Checksum = 1
};

void setup() {
  Serial.begin(9600);

  NewSoftSerial FingerprintReader(2, 3);  // Use pins 2 and 3 for serial I/O to reader

  FingerprintReader.begin(9600);
  for (int i=0; i<(sizeof RequestConnection / sizeof RequestConnection[0]); i++) {
      FingerprintReader.print(RequestConnection[i], BYTE);
  }

}

void loop() {
    if (FingerprintReader.available()) {
        Serial.print(FingerprintReader.read(), HEX);
        Serial.print(" ");
    }
}

And the Circuit is basically just a 3.3V Regulator and RS232 Shifter connected to the 5V and Ground from the Arduino and the Fingerprint Scanner connected to the Regulator with it's power leads (little green LED is on) and the Shifter connected to the RX/TX from the Fingerprint Scanner, and everything is sharing one Ground... But i guess that is not so important jet, since i couldn't even manage to upload the script jet... :slight_smile:
Well, i'll let you know if i find the error!
Damn... Who would have thought it would be so difficult to get that FingerprintScanner to run?! :slight_smile:

Thanks for all the Help so far... At least now i understand the whole thing a bit better :slight_smile:

Move this:

NewSoftSerial FingerprintReader(2, 3);  // Use pins 2 and 3 for serial I/O to reader

Out of setup (above it). As you have it, it is a local variable to setup, hence the complaints you get when you try to use it in loop.

delphino-999:
... and i've read something about the Arduino and the Fingerprint Reader not being the same Endian, that their Backwords, although i don't quite know what that means yet... :~

I would be surprised if the actual bits are backwards. Endianness on async serial is pretty standard, namely that the low-order bit comes first (in case you only have 7 bits of data the 8th is assumed to be zero).

On page 93 of the spec for the device they mention:

User_Number and ID_Size are big endian format.

Also on page 94:

Log_Number and Log_Size are big endian.

That is referring to the order of the bytes, not the bits. So for example the decimal number 1000 (in hex, 0x03E8) would be either two bytes of:

0x03 0xE8  (big endian: big byte first)
0xE8 0x03  (little endian: little byte first)

"Normal" English writing uses big endian. So we write 1000 as just that, not 0001.

So I would definitely not be fiddling with bit orders. Your problem is much more likely to be electrical (if you aren't using level shifters).

If you have a logic analyzer it might help to see what is being sent, and what, if anything, is being returned.

@wildbill
Uau, thank you so much... :slight_smile:
I didn't get any Response in the Serial monitor, but hey it compiled right, and i think this was the first time the Rx LED on the Shifter lit up, when i connect the Arduino or reset it (so it runs the Script from the beginning) first the Tx LED lights up, so the Arduino did transmit something, and then the Rx LED lights up, so the Fingerprint Scanner must be sending something back i guess, right? (of course the two LEDs light up after each other pretty quickly).
However i guess than now i just need to find out why the Serial Port is all empty :~ one problem after the next... But at least i feel like i'm getting pretty close :slight_smile:

@Nick Gammon
Well, i don't know, i read it in a other thread...
I found it kind of strange too (not that i really know what is normal and what is strange in this area) but i guess i'll just have to try both. :slight_smile: I mean, it can only be one of 2 Endians, or did i understand something wrong there too?! :roll_eyes:
Anyhow, i'll keep that in mind, and no, i don't have a Logic Anylizer, do have a shifter connected though, and at least i can see if things are being Send or Received on the Tx and Rx LEDs from the Shifter...

Well, i guess i'll go wonder about why the Arduino doesn't send anything back to the Serial Port now :slight_smile:
Let you guys know, if i "discover" anything new :slight_smile:

troublebuble,

Since you are reading from the fingerprint reader you need "FingerprintReader.available()", not "Serial.avaialble()" in loop().

I'd recommend downloading the NewSoftSerial library and using that instead of SoftwareSerial:
http://arduiniana.org/libraries/newsoftserial/

#include <SoftwareSerial.h>

SoftwareSerial FingerprintReader(2,3);  // Use pins 2 and 3 for serial I/O to reader

byte RequestConnection[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x01,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x00,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x01   // Header Checksum = 1
};


 void setup (){
 FingerprintReader.begin(9600);
 for (int i=0; i<(sizeof RequestConnection / sizeof RequestConnection[0]); i++)
    {
    FingerprintReader.print(RequestConnection[i], BYTE);
    }
 }


 void loop()
    {
    if (Serial.available())   //////  This is a mistake.
        {
        
        Serial.print(FingerprintReader.read(), HEX);
        Serial.print(" ");
        }
    }

Hmm, well, i wrote "if (FingerprintReader.available()) {" and with me it didn't work either, so i guess you might as well write "if (Serial.available()) {". XD (just kidding)

After this line:

 FingerprintReader.begin(9600);

I would pause a bit (eg. delay (100)). Give the serial link time to stabilize.

johnwasser is totally right about checking the right "available".

Also check the other pins. I read on the Sparkfun site about people having problems if the wrong pins were pulled high/low as that put the device into a different "mode".

Ok, i have some rather interesting news...

So, i still don't get any responses in the Serial Port yet, and tried this:

void loop() {
    if (FingerprintReader.available()) {
        Serial.print(FingerprintReader.read(), HEX);
        Serial.print(" ");
        digitalWrite(13, HIGH); // Just to see if "FingerprintReader.available()" ever becomes true
    }
  digitalWrite(13, LOW);
}

And apparently "FingerprintReader.available()" never becomes true (or if it does, is true for such a short time, that you can't even see the LED flashing :))
I think maybe the NewSoftSerial library doesn't work right with me, because the Examples seem not do really do what they are supposed to do either...
If i upload this Example:

#include <NewSoftSerial.h>

NewSoftSerial mySerial(2, 3);

void setup()  
{
  Serial.begin(57600);
  Serial.println("Goodnight moon!");

  // set the data rate for the NewSoftSerial port
  mySerial.begin(4800);
  mySerial.println("Hello, world?");
}

void loop()                     // run over and over again
{

  if (mySerial.available()) {
      Serial.print((char)mySerial.read());
  }
  if (Serial.available()) {
      mySerial.print((char)Serial.read());
  }
}

all i receive is "Goodnight moon!", and then nothing... Is that supposed to happen (when nothing is hooked up to the Arduino)?

Anyhow that is not the Interesting part yet!
Then i tried uploading this Script:

#include <NewSoftSerial.h>

byte RequestConnection[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x01,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x00,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x01   // Header Checksum = 1
};

byte VerifyFp[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x11,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x0B,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x1C   // Header Checksum = 1
};

byte IdentifyFp[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x12,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x00,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x12   // Header Checksum = 1
};

byte DeleteFp[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x22,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x0B,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x2D   // Header Checksum = 1
};

byte RegisterFp[] = {
0x7e,                          // Start Character
0x00, 0x00, 0x00, 0x33,  // Command = 1
0x00, 0x00, 0x00, 0x00,  // Param1 = 0
0x00, 0x00, 0x00, 0x00,  // Param2 = 0
0x00, 0x00, 0x00, 0x1B,  // Data Size = 0
0x00, 0x00, 0x00, 0x00,  // Error Code = 0
0x00, 0x00, 0x00, 0x4E   // Header Checksum = 1
};

NewSoftSerial FingerprintReader(2, 3);  // Use pins 2 and 3 for serial I/O to reader

void setup() {
  
  pinMode(13, OUTPUT);
  
  Serial.begin(9600);

  FingerprintReader.begin(9600);

  delay(100); //I added this because of Nick Gammons reply (but the same Script without it seems to do the same, so i don't know if it really does anything)

  for (int i=0; i<(sizeof RequestConnection / sizeof RequestConnection[0]); i++) {
      FingerprintReader.print(RequestConnection[i], BYTE);
  }

  delay(500);

  for (int i=0; i<(sizeof IdentifyFp / sizeof IdentifyFp[0]); i++) {
      FingerprintReader.print(IdentifyFp[i], BYTE);
  }

}

void loop() {
    if (FingerprintReader.available()) {
        Serial.print(FingerprintReader.read(), HEX);
        Serial.print(" ");
        digitalWrite(13, HIGH); // Just to see if "FingerprintReader.available()" ever becomes true
    }
  digitalWrite(13, LOW);
}

just to see if the Fingerprint Reader maybe reacts too the IdentifyFp, and amzingly first the Green and Yellow LEDs on the Shifter blinkt after each other, then (after the 500 milliseconds) only the Green LED blinkt and the Background lights on the Fingerprint Reader turned on, and after a while the Background lights turned off, and the Yellow LED on the Shifter blinkt.
So i guess the Fingerprint Reader reacted to the IdentifyFp and then after a while sended his results back... So i guess that is a big step?!
Anyhow, the Fingerprint didn't react to the VerifyFp, DeleteFp or RegisterFp. It didn't even send anything back... Since i just copied the VerifyFp, IdentifyFp, DeleteFp and RegisterFp from troublebuble's older reply, i tried too look in the Serial Interface PDF if the VerifyFp, DeleteFp and/or RegisterFp maybe had any kind of error, but i guess i'll stil have to learn how to read that, so i don't if there are any errors :slight_smile: (sorry)
Well i guess, now i only need to find out why the other commands don't work, why the Serial Port is allways empty, and i guess a also need to figure out how to read the Serial Interface PDF so i know what the responses from the Fingerprint Reader mean (that is when i finally get responses :)).

Well, i'll try to understand the PDF then... :slight_smile:
Thanks for all the Help you all gave me 'til now!
Hopefully some day i'll have a chance to help one, some, or all of you with something too...

P.S. @johnwasser, just for the Record, the Fingerprint Reader also reacts to the IdentifyFp command when i try it without first sending the Request Connection command. (no offense or anything, just a little friendly correction) :slight_smile:
@Nick Gammon i only have VCC, GND, TX and RX connected (on the Fingerprint Reader) so i guess that won't be a problem... :slight_smile: