Skip to content

Instantly share code, notes, and snippets.

@IdrisCytron
Last active August 25, 2020 08:34
Show Gist options
  • Save IdrisCytron/cc64da0830f1c4fd483d5fc7b574b4c2 to your computer and use it in GitHub Desktop.
Save IdrisCytron/cc64da0830f1c4fd483d5fc7b574b4c2 to your computer and use it in GitHub Desktop.
Interface Fingerprint Sensor Using M5Stack Core ESP32 Development Kit
#include <M5Stack.h>
#include "Fingerprint.h"
Fingerprint::Fingerprint(void)
{
Serial1.begin(19200, SERIAL_8N1, FINGER_TX, FINGER_RX);
}
uint8_t Fingerprint::TxAndRxCmd(uint8_t Scnt, uint8_t Rcnt, uint16_t Delay_ms)
{
uint8_t i, j, CheckSum;
uint32_t before_tick;
uint32_t after_tick;
uint8_t overflow_Flag = 0;
//Serial.print("TX: ");
Serial1.write(CMD_HEAD); //Serial.print(CMD_HEAD, HEX); Serial.print(" ");
CheckSum = 0;
for (i = 0; i < Scnt; i++) {
Serial1.write(finger_TxBuf[i]); //Serial.print(finger_TxBuf[i], HEX); Serial.print(" ");
CheckSum ^= finger_TxBuf[i];
}
Serial1.write(CheckSum); //Serial.print(CheckSum, HEX); Serial.print(" ");
Serial1.write(CMD_TAIL); //Serial.println(CMD_TAIL, HEX);
fingerPrevMillis = millis();
while (millis() - fingerPrevMillis < Delay_ms) {
if (Serial1.available()) break;
}
//Serial.print("RX: ");
i = 0;
while (Serial1.available()) {
finger_RxBuf[i] = Serial1.read();
//Serial.print(finger_RxBuf[i], HEX); Serial.print(" ");
i++;
}
//Serial.println();
if (i != Rcnt) {
return ACK_TIMEOUT;
}
else if (finger_RxBuf[0] != CMD_HEAD) {
return ACK_FAIL;
}
else if (finger_RxBuf[Rcnt - 1] != CMD_TAIL) {
return ACK_FAIL;
}
else if (finger_RxBuf[1] != finger_TxBuf[0]) {
return ACK_FAIL;
}
CheckSum = 0;
for (j = 1; j < Rcnt - 1; j++) {
CheckSum ^= finger_RxBuf[j];
}
if (CheckSum != 0) {
return ACK_FAIL;
}
return ACK_SUCCESS;
}
uint8_t Fingerprint::GetUserCount(void)
{
uint8_t m;
finger_TxBuf[0] = CMD_USER_CNT;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = 0;
finger_TxBuf[3] = 0;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 100);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return finger_RxBuf[3];
}
else {
return 0xFF;
}
}
uint8_t Fingerprint::GetcompareLevel(void)
{
uint8_t m;
finger_TxBuf[0] = CMD_COM_LEV;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = 0;
finger_TxBuf[3] = 1;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 100);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return finger_RxBuf[3];
}
else {
return 0xFF;
}
}
uint8_t Fingerprint::SetcompareLevel(uint8_t temp)
{
uint8_t m;
finger_TxBuf[0] = CMD_COM_LEV;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = temp;
finger_TxBuf[3] = 0;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 100);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return finger_RxBuf[3];
}
else {
return 0xFF;
}
}
uint8_t Fingerprint::GetTimeOut(void)
{
uint8_t m;
finger_TxBuf[0] = CMD_TIMEOUT;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = 0;
finger_TxBuf[3] = 1;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 100);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return finger_RxBuf[3];
}
else {
return 0xFF;
}
}
uint8_t Fingerprint::AddUser(void)
{
uint8_t m;
m = GetUserCount();
if (m >= USER_MAX_CNT) {
return ACK_FULL;
}
finger_TxBuf[0] = CMD_ADD_1;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = m + 1;
finger_TxBuf[3] = 3;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 5000);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
finger_TxBuf[0] = CMD_ADD_3;
m = TxAndRxCmd(5, 8, 5000);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return ACK_SUCCESS;
}
else {
return ACK_FAIL;
}
}
else {
return ACK_GO_OUT;
}
}
uint8_t Fingerprint::ClearAllUser(void)
{
uint8_t m;
finger_TxBuf[0] = CMD_DEL_ALL;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = 0;
finger_TxBuf[3] = 0;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 500);
if (m == ACK_SUCCESS && finger_RxBuf[4] == ACK_SUCCESS) {
return ACK_SUCCESS;
}
else {
return ACK_FAIL;
}
}
uint8_t Fingerprint::IsMasterUser(uint8_t UserID)
{
if ((UserID == 1) || (UserID == 2) || (UserID == 3)) {
return true;
}
else {
return false;
}
}
uint8_t Fingerprint::VerifyUser(void)
{
uint8_t m;
finger_TxBuf[0] = CMD_MATCH;
finger_TxBuf[1] = 0;
finger_TxBuf[2] = 0;
finger_TxBuf[3] = 0;
finger_TxBuf[4] = 0;
m = TxAndRxCmd(5, 8, 1000);
if ((m == ACK_SUCCESS) && (IsMasterUser(finger_RxBuf[4]) == true)) {
return ACK_SUCCESS;
}
else if(finger_RxBuf[4] == ACK_NO_USER) {
return ACK_NO_USER;
}
else if(finger_RxBuf[4] == ACK_TIMEOUT) {
return ACK_TIMEOUT;
}
else {
return ACK_FAIL;
}
}
#ifndef _FINGERPRINT_H
#define _FINGERPRINT_H
// Basic response message definition
#define ACK_SUCCESS 0x00
#define ACK_FAIL 0x01
#define ACK_FULL 0x04
#define ACK_NO_USER 0x05
#define ACK_TIMEOUT 0x08
#define ACK_GO_OUT 0x0F // The center of the fingerprint is out of alignment with sensor
// User information definition
#define ACK_ALL_USER 0x00
#define ACK_GUEST_USER 0x01
#define ACK_NORMAL_USER 0x02
#define ACK_MASTER_USER 0x03
#define USER_MAX_CNT 1000 // Maximum fingerprint number
// Command definition
#define CMD_HEAD 0xF5
#define CMD_TAIL 0xF5
#define CMD_ADD_1 0x01
#define CMD_ADD_2 0x02
#define CMD_ADD_3 0x03
#define CMD_MATCH 0x0C
#define CMD_DEL 0x04
#define CMD_DEL_ALL 0x05
#define CMD_USER_CNT 0x09
#define CMD_COM_LEV 0x28
#define CMD_LP_MODE 0x2C
#define CMD_TIMEOUT 0x2E
#define CMD_FINGER_DETECTED 0x14
#define FINGER_WAKE 26
#define FINGER_RST 5
#define FINGER_RX 17
#define FINGER_TX 16
class Fingerprint
{
public:
Fingerprint(void);
uint8_t TxAndRxCmd(uint8_t Scnt, uint8_t Rcnt, uint16_t Delay_ms);
uint8_t GetUserCount(void);
uint8_t GetcompareLevel(void);
uint8_t SetcompareLevel(uint8_t temp);
uint8_t GetTimeOut(void);
uint8_t AddUser(void);
uint8_t ClearAllUser(void);
uint8_t IsMasterUser(uint8_t UserID);
uint8_t VerifyUser(void);
public:
uint8_t finger_TxBuf[9];
uint8_t finger_RxBuf[9];
long fingerPrevMillis = 0;
private:
private:
};
#endif
/*
Project: Interface Fingerprint Sensor Using M5Stack
Board: M5Stack-Core-ESP32
Connections:
M5Stack | Fingerprint
3.3V - VIN
GND - GND
IO17 - RX
IO16 - TX
IO5 - RST
IO26 - WAKE
External libraries:
- M5Stack by M5Stack V0.3.0 (Manager)
*/
#include <M5Stack.h>
#include "Fingerprint.h"
Fingerprint fp;
char inChar;
int count = 0;
uint8_t fingerResponse;
long prevMillis = 0;
void setup()
{
pinMode(FINGER_WAKE, INPUT);
pinMode(FINGER_RST, OUTPUT);
digitalWrite(FINGER_RST, HIGH);
M5.begin();
M5.Power.begin();
Serial.begin(115200);
Serial.println();
Serial.println();
if (fp.SetcompareLevel(5) != 5) {
Serial.println("***ERROR***");
Serial.println("Please ensure that the module power supply is 3.3V or 5V,");
Serial.println("the serial line connection is correct.");
Serial.println();
}
Serial.println("********** WaveShare Capacitive Fingerprint Reader Test **********");
Serial.println("Compare Level: 5 (can be set to 0-9, the bigger, the stricter)");
Serial.print("Number of fingerprints already available: ");
Serial.println(fp.GetUserCount());
Serial.println("Send commands to operate the module: ");
Serial.println(" 1 : Query the number of existing fingerprints");
Serial.println(" 2 : Registered fingerprint (Put your finger on the sensor until successfully/failed information returned)");
Serial.println(" 3 : Clear fingerprints");
M5.Lcd.clear(BLACK);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(RED);
M5.Lcd.setCursor(0, 10);
M5.Lcd.println("**** Fingerprint Demo ****");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 40);
M5.Lcd.println("SW1: No of fingerprint");
M5.Lcd.setTextColor(YELLOW);
M5.Lcd.println("No of existing fingerprint");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 85);
M5.Lcd.println("SW2: Register fingerprint");
M5.Lcd.setTextColor(YELLOW);
M5.Lcd.println("Put your finger on sensor");
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 130);
M5.Lcd.println("SW3: Clear fingerprints");
M5.Lcd.setTextColor(GREEN);
M5.Lcd.setCursor(0, 160);
M5.Lcd.println("Status:");
digitalWrite(FINGER_RST, LOW);
M5.Speaker.beep();
}
void loop()
{
if (M5.BtnA.wasReleased()) {
inChar = '1';
}
else if (M5.BtnB.wasReleased()) {
inChar = '2';
}
else if (M5.BtnC.wasReleased()) {
inChar = '3';
}
if (digitalRead(FINGER_WAKE) == HIGH) {
while (digitalRead(FINGER_WAKE) != LOW) {
digitalWrite(FINGER_RST, HIGH);
delay(300);
Serial.println("Waiting Finger... Please try to place the center of the fingerprint flat to sensor!");
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
M5.Lcd.println("Fingerprint is detected");
M5.Lcd.print("scanning...");
for (count = 0; count < 3; count++) {
fingerResponse = fp.VerifyUser();
if (fingerResponse == ACK_SUCCESS) break;
}
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
switch (fingerResponse) {
case ACK_SUCCESS:
Serial.println("Matching successful!");
M5.Lcd.print("Matching successful!");
M5.Speaker.beep();
break;
case ACK_NO_USER:
Serial.println("Failed: This fingerprint was not found in the library!");
M5.Lcd.println("This fingerprint was not");
M5.Lcd.print("found in the library!");
break;
case ACK_TIMEOUT:
Serial.println("Failed: Time out!");
M5.Lcd.print("Time out!");
break;
case ACK_GO_OUT:
Serial.println("Failed: Please try to place the center of the fingerprint flat to sensor!");
M5.Lcd.print("Please try again!");
break;
}
}
digitalWrite(FINGER_RST, LOW);
prevMillis = millis();
}
if (Serial.available()) {
while (Serial.available()) {
inChar = (char)Serial.read();
}
}
if (inChar) {
switch (inChar) {
case '1':
digitalWrite(FINGER_RST, HIGH);
delay(300);
for (count = 0; count < 3; count++) {
fingerResponse = fp.GetUserCount();
if (fingerResponse != 0xFF) break;
}
Serial.print("Number of fingerprints already available: ");
Serial.println(fingerResponse);
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
M5.Lcd.print("No of fingerprint = ");
M5.Lcd.print(fingerResponse);
digitalWrite(FINGER_RST, LOW);
break;
case '2':
digitalWrite(FINGER_RST, HIGH);
delay(300);
Serial.println("Add fingerprint (Put your finger on sensor until successfully/failed information returned.");
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
M5.Lcd.println("Add new fingerprint");
M5.Lcd.print("Put your finger on sensor");
for (count = 0; count < 3; count++) {
fingerResponse = fp.AddUser();
if (fingerResponse == ACK_SUCCESS) break;
}
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
switch (fingerResponse) {
case ACK_SUCCESS:
Serial.println("Fingerprint added successfully!");
M5.Lcd.println("Fingerprint added");
M5.Lcd.print("successfully!");
break;
case ACK_GO_OUT:
Serial.println("Failed: Please try to place the center of the fingerprint flat to sensor, or this fingerprint already exists!");
M5.Lcd.println("Please try again /");
M5.Lcd.print("fingerprint already exist!");
break;
case ACK_FAIL:
Serial.println("Failed: The fingerprint library is full!");
M5.Lcd.println("The fingerprint library");
M5.Lcd.print("is full!");
break;
default:
Serial.println("Error!");
M5.Lcd.print("Error!");
break;
}
digitalWrite(FINGER_RST, LOW);
delay(100);
while (digitalRead(FINGER_WAKE) == HIGH);
break;
case '3':
digitalWrite(FINGER_RST, HIGH);
delay(300);
for (count = 0; count < 3; count++) {
fingerResponse = fp.ClearAllUser();
if (fingerResponse == ACK_SUCCESS) break;
}
Serial.println("All fingerprints have been cleared!");
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setCursor(0, 180);
M5.Lcd.println("All fingerprints have");
M5.Lcd.print("been cleared!");
digitalWrite(FINGER_RST, LOW);
break;
default:
break;
}
prevMillis = millis();
inChar = 0;
}
if (millis() - prevMillis > 5000) {
M5.Lcd.fillRect(0, 180, 320, 60, BLACK);
prevMillis = millis();
}
M5.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment