Skip to content

Instantly share code, notes, and snippets.

@calaveraInfo
Last active December 27, 2015 15:04
Show Gist options
  • Save calaveraInfo/2b295ae4939b058f4e34 to your computer and use it in GitHub Desktop.
Save calaveraInfo/2b295ae4939b058f4e34 to your computer and use it in GitHub Desktop.
Adafruit fingerprint sensor with Arduino Micro

Adafruit fingerprint sensor library uses software serial which is almost unusable with Arduino Micro at the speed needed by the sensor. The library needs to be modified to use hardware serial for it to be usable with Arduino Micro.

With this modification the fingerprint serial pins should be connected directly with Arduino Micro pins labeled RX and TX.

/***************************************************
This is a library for our optical Fingerprint sensor
Designed specifically to work with the Adafruit BMP085 Breakout
----> http://www.adafruit.com/products/751
These displays use TTL Serial to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
//#include "Adafruit_Fingerprint.h"
#include "Calavera_Fingerprint.h"
#include <util/delay.h>
//#if (ARDUINO >= 100)
// #include <SoftwareSerial.h>
//#else
// #include <NewSoftSerial.h>
//#endif
//static SoftwareSerial mySerial = SoftwareSerial(2, 3);
//#if ARDUINO >= 100
//Adafruit_Fingerprint::Adafruit_Fingerprint(SoftwareSerial *ss) {
//#else
//Adafruit_Fingerprint::Adafruit_Fingerprint(NewSoftSerial *ss) {
//#endif
Adafruit_Fingerprint::Adafruit_Fingerprint(HardwareSerial *ss) {
thePassword = 0;
theAddress = 0xFFFFFFFF;
mySerial = ss;
}
void Adafruit_Fingerprint::begin(uint16_t baudrate) {
mySerial->begin(baudrate);
}
boolean Adafruit_Fingerprint::verifyPassword(void) {
uint8_t packet[] = {FINGERPRINT_VERIFYPASSWORD,
(thePassword >> 24), (thePassword >> 16),
(thePassword >> 8), thePassword};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, 7, packet);
uint8_t len = getReply(packet);
if ((len == 1) && (packet[0] == FINGERPRINT_ACKPACKET) && (packet[1] == FINGERPRINT_OK))
return true;
/*
Serial.print("\nGot packet type "); Serial.print(packet[0]);
for (uint8_t i=1; i<len+1;i++) {
Serial.print(" 0x");
Serial.print(packet[i], HEX);
}
*/
return false;
}
uint8_t Adafruit_Fingerprint::getImage(void) {
uint8_t packet[] = {FINGERPRINT_GETIMAGE};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, 3, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
return packet[1];
}
uint8_t Adafruit_Fingerprint::image2Tz(uint8_t slot) {
uint8_t packet[] = {FINGERPRINT_IMAGE2TZ, slot};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
return packet[1];
}
uint8_t Adafruit_Fingerprint::createModel(void) {
uint8_t packet[] = {FINGERPRINT_REGMODEL};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
return packet[1];
}
uint8_t Adafruit_Fingerprint::storeModel(uint16_t id) {
uint8_t packet[] = {FINGERPRINT_STORE, 0x01, id >> 8, id & 0xFF};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
return packet[1];
}
uint8_t Adafruit_Fingerprint::emptyDatabase(void) {
uint8_t packet[] = {FINGERPRINT_EMPTY};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
return packet[1];
}
uint8_t Adafruit_Fingerprint::fingerFastSearch(void) {
fingerID = 0xFFFF;
confidence = 0xFFFF;
// high speed search of slot #1 starting at page 0x0000 and page #0x00A3
uint8_t packet[] = {FINGERPRINT_HISPEEDSEARCH, 0x01, 0x00, 0x00, 0x00, 0xA3};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
fingerID = packet[2];
fingerID <<= 8;
fingerID |= packet[3];
confidence = packet[4];
confidence <<= 8;
confidence |= packet[5];
return packet[1];
}
uint8_t Adafruit_Fingerprint::getTemplateCount(void) {
templateCount = 0xFFFF;
// get number of templates in memory
uint8_t packet[] = {FINGERPRINT_TEMPLATECOUNT};
writePacket(theAddress, FINGERPRINT_COMMANDPACKET, sizeof(packet)+2, packet);
uint8_t len = getReply(packet);
if ((len != 1) && (packet[0] != FINGERPRINT_ACKPACKET))
return -1;
templateCount = packet[2];
templateCount <<= 8;
templateCount |= packet[3];
return packet[1];
}
void Adafruit_Fingerprint::writePacket(uint32_t addr, uint8_t packettype,
uint16_t len, uint8_t *packet) {
#ifdef FINGERPRINT_DEBUG
Serial.print("---> 0x");
Serial.print((uint8_t)(FINGERPRINT_STARTCODE >> 8), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)FINGERPRINT_STARTCODE, HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(addr >> 24), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(addr >> 16), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(addr >> 8), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(addr), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)packettype, HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(len >> 8), HEX);
Serial.print(" 0x");
Serial.print((uint8_t)(len), HEX);
#endif
#if ARDUINO >= 100
mySerial->write((uint8_t)(FINGERPRINT_STARTCODE >> 8));
mySerial->write((uint8_t)FINGERPRINT_STARTCODE);
mySerial->write((uint8_t)(addr >> 24));
mySerial->write((uint8_t)(addr >> 16));
mySerial->write((uint8_t)(addr >> 8));
mySerial->write((uint8_t)(addr));
mySerial->write((uint8_t)packettype);
mySerial->write((uint8_t)(len >> 8));
mySerial->write((uint8_t)(len));
#else
mySerial->print((uint8_t)(FINGERPRINT_STARTCODE >> 8), BYTE);
mySerial->print((uint8_t)FINGERPRINT_STARTCODE, BYTE);
mySerial->print((uint8_t)(addr >> 24), BYTE);
mySerial->print((uint8_t)(addr >> 16), BYTE);
mySerial->print((uint8_t)(addr >> 8), BYTE);
mySerial->print((uint8_t)(addr), BYTE);
mySerial->print((uint8_t)packettype, BYTE);
mySerial->print((uint8_t)(len >> 8), BYTE);
mySerial->print((uint8_t)(len), BYTE);
#endif
uint16_t sum = (len>>8) + (len&0xFF) + packettype;
for (uint8_t i=0; i< len-2; i++) {
#if ARDUINO >= 100
mySerial->write((uint8_t)(packet[i]));
#else
mySerial->print((uint8_t)(packet[i]), BYTE);
#endif
#ifdef FINGERPRINT_DEBUG
Serial.print(" 0x"); Serial.print(packet[i], HEX);
#endif
sum += packet[i];
}
#ifdef FINGERPRINT_DEBUG
//Serial.print("Checksum = 0x"); Serial.println(sum);
Serial.print(" 0x"); Serial.print((uint8_t)(sum>>8), HEX);
Serial.print(" 0x"); Serial.println((uint8_t)(sum), HEX);
#endif
#if ARDUINO >= 100
mySerial->write((uint8_t)(sum>>8));
mySerial->write((uint8_t)sum);
#else
mySerial->print((uint8_t)(sum>>8), BYTE);
mySerial->print((uint8_t)sum, BYTE);
#endif
}
uint8_t Adafruit_Fingerprint::getReply(uint8_t packet[], uint16_t timeout) {
uint8_t reply[20], idx;
uint16_t timer=0;
idx = 0;
#ifdef FINGERPRINT_DEBUG
Serial.print("<--- ");
#endif
while (true) {
while (!mySerial->available()) {
delay(1);
timer++;
if (timer >= timeout) return FINGERPRINT_TIMEOUT;
}
// something to read!
reply[idx] = mySerial->read();
#ifdef FINGERPRINT_DEBUG
Serial.print(" 0x"); Serial.print(reply[idx], HEX);
#endif
if ((idx == 0) && (reply[0] != (FINGERPRINT_STARTCODE >> 8)))
continue;
idx++;
// check packet!
if (idx >= 9) {
if ((reply[0] != (FINGERPRINT_STARTCODE >> 8)) ||
(reply[1] != (FINGERPRINT_STARTCODE & 0xFF)))
return FINGERPRINT_BADPACKET;
uint8_t packettype = reply[6];
//Serial.print("Packet type"); Serial.println(packettype);
uint16_t len = reply[7];
len <<= 8;
len |= reply[8];
len -= 2;
//Serial.print("Packet len"); Serial.println(len);
if (idx <= (len+10)) continue;
packet[0] = packettype;
for (uint8_t i=0; i<len; i++) {
packet[1+i] = reply[9+i];
}
#ifdef FINGERPRINT_DEBUG
Serial.println();
#endif
return len;
}
}
}
/***************************************************
This is a library for our optical Fingerprint sensor
Designed specifically to work with the Adafruit BMP085 Breakout
----> http://www.adafruit.com/products/751
These displays use TTL Serial to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
//#if (ARDUINO >= 100)
#include "Arduino.h"
// #include <SoftwareSerial.h>
//#else
// #include "WProgram.h"
// #include <NewSoftSerial.h>
//#endif
#define FINGERPRINT_OK 0x00
#define FINGERPRINT_PACKETRECIEVEERR 0x01
#define FINGERPRINT_NOFINGER 0x02
#define FINGERPRINT_IMAGEFAIL 0x03
#define FINGERPRINT_IMAGEMESS 0x06
#define FINGERPRINT_FEATUREFAIL 0x07
#define FINGERPRINT_NOMATCH 0x08
#define FINGERPRINT_NOTFOUND 0x09
#define FINGERPRINT_ENROLLMISMATCH 0x0A
#define FINGERPRINT_BADLOCATION 0x0B
#define FINGERPRINT_DBRANGEFAIL 0x0C
#define FINGERPRINT_UPLOADFEATUREFAIL 0x0D
#define FINGERPRINT_PACKETRESPONSEFAIL 0x0E
#define FINGERPRINT_UPLOADFAIL 0x0F
#define FINGERPRINT_DELETEFAIL 0x10
#define FINGERPRINT_DBCLEARFAIL 0x11
#define FINGERPRINT_PASSFAIL 0x13
#define FINGERPRINT_INVALIDIMAGE 0x15
#define FINGERPRINT_FLASHERR 0x18
#define FINGERPRINT_INVALIDREG 0x1A
#define FINGERPRINT_ADDRCODE 0x20
#define FINGERPRINT_PASSVERIFY 0x21
#define FINGERPRINT_STARTCODE 0xEF01
#define FINGERPRINT_COMMANDPACKET 0x1
#define FINGERPRINT_DATAPACKET 0x2
#define FINGERPRINT_ACKPACKET 0x7
#define FINGERPRINT_ENDDATAPACKET 0x8
#define FINGERPRINT_TIMEOUT 0xFF
#define FINGERPRINT_BADPACKET 0xFE
#define FINGERPRINT_GETIMAGE 0x01
#define FINGERPRINT_IMAGE2TZ 0x02
#define FINGERPRINT_REGMODEL 0x05
#define FINGERPRINT_STORE 0x06
#define FINGERPRINT_EMPTY 0x0D
#define FINGERPRINT_VERIFYPASSWORD 0x13
#define FINGERPRINT_HISPEEDSEARCH 0x1B
#define FINGERPRINT_TEMPLATECOUNT 0x1D
//#define FINGERPRINT_DEBUG
#define DEFAULTTIMEOUT 5000 // milliseconds
class Adafruit_Fingerprint {
public:
//#if ARDUINO >= 100
// Adafruit_Fingerprint(SoftwareSerial *);
//#else
// Adafruit_Fingerprint(NewSoftSerial *);
//#endif
Adafruit_Fingerprint(HardwareSerial *);
void begin(uint16_t baud);
boolean verifyPassword(void);
uint8_t getImage(void);
uint8_t image2Tz(uint8_t slot = 1);
uint8_t createModel(void);
uint8_t emptyDatabase(void);
uint8_t storeModel(uint16_t id);
uint8_t fingerFastSearch(void);
uint8_t getTemplateCount(void);
void writePacket(uint32_t addr, uint8_t packettype, uint16_t len, uint8_t *packet);
uint8_t getReply(uint8_t packet[], uint16_t timeout=DEFAULTTIMEOUT);
uint16_t fingerID, confidence, templateCount;
private:
uint32_t thePassword;
uint32_t theAddress;
HardwareSerial *mySerial;
//#if ARDUINO >= 100
// SoftwareSerial *mySerial;
//#else
// NewSoftSerial *mySerial;
//#endif
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment