Last active
August 25, 2020 08:34
-
-
Save IdrisCytron/cc64da0830f1c4fd483d5fc7b574b4c2 to your computer and use it in GitHub Desktop.
Interface Fingerprint Sensor Using M5Stack Core ESP32 Development Kit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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