Table of Contents:
Overview:
In this project, I will tell you how to build a Portable IoT based Fingerprint Biometric Attendance System using NodeMCU ESP8266 12E, 0.96” OLED Display & SFG R303a Fingerprint Sensor. The ESP8266 Wi-Fi Module will collect the fingerprint data from the multiple users and sends it over the internet to a website. The Enrolment of fingerprints is done on the server using any fingerprint sensor like R303, R305 or R307 that is available on the market and verification of the fingerprint will be done on the webserver while fingerprint templates are transmitted over the WiFi.
The website used in this project is developed using PHP, it has a database and records of attendance. By logging into the website, you can collect all the attendance records of each user including personal details as well as incoming & outgoing timing. The data can also be downloaded and exported to an excel sheet.
Website: a snapshot of Portable IoT Based Fingerprint Biometric Attendance System
The main drawback of conventional authentication technologies like RFID tags and authentication cards are can be transferred, if we use such type of methodologies users can easily manipulate the data, biometric method of authentication is a prompt replacement for this. Biometrics such as fingerprints, Face Recognition, voice and ECG signals are unique human characters that cannot be tampered or replicated impossible to manipulate. This allow us to develop rugged real-time biometric system implementations.
Biometric Attendance systems are commonly used systems to mark the presence of students or employees in the schools and offices. This project has a wide scope in the modern era of schools, colleges, business organizations, offices where accurate attendance data is required. Biometric attendance system will make the process of taking very easy and reliable. Thus, by using the fingerprint sensor, the system will become more secure for both parties.
You can watch the following video tutorial for detailed information, or you can read the article written over here.
Required Components:
The following are the required components to proceed with IoT Based Biometric Fingerprint Attendance System. All the components can be purchased from Amazon. The purchase links are given below.
In this article, I am using SFG r303a module. Currently, this module is not in production. you can R305 or R307.
- NodeMCU Buy from Amazon.
- R303/R305/R307 fingerprint sensor Buy from Amazon (R303)/(R307)
- 0.96″ OLED display Buy from Amazon
- Li-Ion battery(18650) Buy from Amazon
- TP4056 Li-Ion Battery charger Buy from Amazon
- MT3608 Boost converter Buy from Amazon
- On/Off switch Buy from Amazon
- Breadboard Buy from Amazon
- Connecting wires Buy from Amazon
SFG R303 Fingerprint Identification Module
Introduction
This is a fingerprint sensor module with TTL UART interface for direct connections to microcontroller UART or to PC through MAX232 / USB-Serial adapter. The user can store the fingerprint data in the module and can configure it in 1:1 or 1: N mode for identifying the person.
The Fingerprint module can be directly interfaced with any microcontroller as well as Arduino Board. This optical biometric fingerprint reader with great features and can be embedded into a variety of end products like access control system, attendance system, safety deposit box, car door locking system.
Operation Principle:
Fingerprint processing includes two parts: fingerprint enrollment and fingerprint matching (the matching can be 1:1 or 1:N).
When enrolling, the user needs to enter the finger two times. The system will process the two-time finger images, generate a template of the finger based on processing results and store the template. When matching, the user enters the finger through the optical sensor and system will generate a template of the finger and compare it with templates of the finger library. For 1:1 matching, the system will compare the live finger with specific template designated in the Module; for 1:N matching, or searching, the system will search the whole finger library for the matching finger. In both circumstances, system will return the matching result, success or failure.
Features
- Integrated image collecting and algorithm chip together, ALL-in-One
- The fingerprint reader can conduct secondary development, can be embedded into a variety of end products
- Low power consumption, low cost, small size, excellent performance
- Professional optical technology, precise module manufacturing techniques
- Good image processing capabilities can successfully capture image up to resolution 500 dpi
Specifications:
For more information about SFG R303A Fingerprint sensor, check out this datasheet.
0.96″ I2C OLED Display:
This is a 0.96 inch blue OLED display module. The display module can be interfaced with any microcontroller using SPI/IIC protocols. It is having a resolution of 128×64. The package includes display board, display,4 pin male header pre-soldered to board.
OLED (Organic Light-Emitting Diode) is a self light-emitting technology composed of a thin, multi-layered organic film placed between an anode and cathode. In contrast to LCD technology, OLED does not require a backlight. OLED possesses high application potential for virtually all types of displays and is regarded as the ultimate technology for the next generation of flat-panel displays.
Specifications:
- OLED Driver IC: SSD1306
- Resolution: 128 x 64
- Visual Angle: >160°
- Input Voltage: 3.3V ~ 6V
- Compatible I/O Level: 3.3V, 5V
- Mini Size: 2.7 x 2.8cm
- Only Need 2 I/O Port to Control
- Fully Compatible with Arduino
- Working temperature: -30°C ~ 70°C
- Module volume ( generous ): 27.0 x 27.0 x 4.1mm
- Factory configured for SPI protocol (can be easily changed to IIC)
For more information about the SSD1306 OLED Display, check out this datasheet.
The Total process includes the following steps:
- Setting up the website
- Circuit Diagram and hardware connections
- Source code development
- Registration of the users.
Setting up the website:
The website used in this project can be configured as global/Local. You need to have a unique domain name and to set up a global website. if you have a website and a server you can simply download the biometricattendance.zip file and copy to the cPanel/website file manager and modify the connectDb.php and install.php files with your website credentials. but having website domain and hosting is will cost you more.
In case if you don’t wanna spend money on website management, then you can configure your website as local and use your own computer as a server to store the data locally in localhost.
For that, you can use any local server provider Xampp or Wamp. I have given both download links below you can choose either.
Download and install Xampp from the link here: Download XAMPP
Download and install Xampp from the link here: Download Wamp
I will use Xampp to demonstrate further process. Choose an appropriate file for your operating system. Xampp is available for Windows, Linux Mac.
Once the file downloaded succesfully install the Xampp, the installation process is very easy, it is like normal software installation only.
After successful installation, simply download the biometricattendance.zip file and copy to the folder C:\xampp\htdocs in your computer. This folder is the location where all your website data will store.
The website configuration process is a little bit longer, which is explained in the video. You can follow the video to completely set up the website.
Circuit Diagram: Portable IoT based Fingerprint Biometric Attendance System
The following circuit diagram shows how an OLED Display & Fingerprint Sensor is interfaced to NodeMCU ESP8266 12E Board.
The I2C pins of OLED Display, i.e SDA & SCL is connected to NodeMCU D1 & D2 pins respectively. Similarly, the fingerprint sensor is also connected to UART pins D5 & D6. The fingerprint sensor Tx and Rx wires color may vary. So connect it by finding appropriate color wires else the module won’t be detected by NodeMCU.
The R303a fingerprint sensor is supplied with 5V through Vin pins of NodeMCU. In my case, the sensor didn’t work at 3.3V. because sensor operating voltage is 3.6v to 6v Similarly, connect OLED Vcc pin to 3.3V of NodeMCU.
Source Code/Program
The source code for the Portable IoT Based Fingerprint Biometric Attendance System using NodeMCU here.
In this source code, you need to do two modifications according to your WiFi Network connection and PC IP.
You have to make sure that the WiFi username and password are provided which is available in the range.
/* Set these to your desired credentials. */ const char *ssid = "Electronics_Innovation"; //ENTER YOUR WIFI SETTINGS const char *password = "subscribe";
Also, change the IP Address if you are using Xampp or change the website domain name if you are using the global website as changed below.
String link = "http://192.168.43.205/biometricattendance/getdata.php"; //computer IP or the server domain
Add the following libraries via library manager or simply add the following zip files to Arduino libraries folder:
1. OLED GFX Library: Download
2. SSD1306 Library: Download
3. Adafruit Fingerprint Sensor Library: Download
/* Developed by Electronics Innovation Project: Portable IoT based Fingerprint Biometric Attendance System with NodeMCU. Electronics Innovation - www.electronicsinnovation.com GitHub - https://github.com/VeeruSubbuAmi YouTube - http://bit.ly/Electronics_Innovation Upload date: 18 September 2019 Libraries: Adafruit GFX:- https://github.com/adafruit/Adafruit-GFX-Library Adafruit SSD1306:- https://github.com/adafruit/Adafruit_SSD1306 Adafruit-Fingerprint-Sensor-Library:- https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library This sketch is developed to capture fingerprint data to compare the existing data and mark attendance on the server over the Internet. Note: 1)Connect the circuit as shown in the circuit diagram. 2) Download and install all the required libraries. All the Links are given above. */ //*******************************libraries******************************** #include <SPI.h> #include <Wire.h> #include <ESP8266WiFi.h> // If you face any problem with this library vist here: #include <SoftwareSerial.h> // https://youtu.be/oq3_xy2rCyk #include <ESP8266WebServer.h> #include <ESP8266HTTPClient.h> #include <Adafruit_GFX.h> //Library link:https://github.com/adafruit/Adafruit-GFX-Library #include <Adafruit_SSD1306.h> //Library link:https://github.com/adafruit/Adafruit_SSD1306 #include <Adafruit_Fingerprint.h> //Library link:https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library //************************************************************************ //Fingerprint scanner Pins #define Finger_Rx 14 //D5 #define Finger_Tx 12 //D6 // Declaration for SSD1306 display connected using software I2C #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET 0 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //************************************************************************ SoftwareSerial mySerial(Finger_Rx, Finger_Tx); Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial); //************************************************************************ /* Set these to your desired credentials. */ const char *ssid = "Electronics_Innovation"; //ENTER YOUR WIFI SETTINGS const char *password = "subscribe"; //************************************************************************ String postData ; // post array that will be send to the website String link = "http://192.168.43.205/biometricattendance/getdata.php"; //computer IP or the server domain int FingerID = 0; // The Fingerprint ID from the scanner uint8_t id; //*************************Biometric Icons********************************* #define Wifi_start_width 54 #define Wifi_start_height 49 const uint8_t PROGMEM Wifi_start_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00 ,0x00,0x03,0xff,0xff,0x80,0x00,0x00 ,0x00,0x1f,0xf0,0x1f,0xf0,0x00,0x00 ,0x00,0x7e,0x00,0x00,0xfc,0x00,0x00 ,0x01,0xf0,0x00,0x00,0x1f,0x00,0x00 ,0x03,0xc0,0x00,0x00,0x07,0xc0,0x00 ,0x0f,0x00,0x00,0x00,0x01,0xe0,0x00 ,0x1c,0x00,0x00,0x00,0x00,0x70,0x00 ,0x38,0x00,0x07,0xc0,0x00,0x38,0x00 ,0x70,0x00,0xff,0xfe,0x00,0x1e,0x00 ,0xe0,0x03,0xfc,0x7f,0xc0,0x0e,0x00 ,0x00,0x1f,0x80,0x03,0xf0,0x00,0x00 ,0x00,0x3c,0x00,0x00,0x78,0x00,0x00 ,0x00,0xf0,0x00,0x00,0x1c,0x00,0x00 ,0x01,0xe0,0x00,0x00,0x0c,0x00,0x00 ,0x03,0x80,0x00,0x00,0x00,0x00,0x00 ,0x03,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x3f,0xf8,0x07,0x1e,0x00 ,0x00,0x00,0xff,0xfe,0x1f,0xbf,0x80 ,0x00,0x03,0xe0,0x04,0x7f,0xff,0xc0 ,0x00,0x07,0x80,0x00,0xff,0xff,0xe0 ,0x00,0x0e,0x00,0x00,0xff,0xff,0xe0 ,0x00,0x0c,0x00,0x00,0x7f,0xff,0xc0 ,0x00,0x00,0x00,0x00,0xfe,0x07,0xe0 ,0x00,0x00,0x00,0x03,0xf8,0x03,0xf8 ,0x00,0x00,0x07,0xe7,0xf9,0xf1,0xfc ,0x00,0x00,0x1f,0xe7,0xf1,0xf9,0xfc ,0x00,0x00,0x1f,0xe7,0xf3,0xf9,0xfc ,0x00,0x00,0x3f,0xe7,0xf3,0xf9,0xfc ,0x00,0x00,0x3f,0xe7,0xf1,0xf1,0xfc ,0x00,0x00,0x3f,0xe3,0xf8,0xe3,0xfc ,0x00,0x00,0x3f,0xf3,0xfc,0x07,0xf8 ,0x00,0x00,0x1f,0xf0,0x7f,0x0f,0xc0 ,0x00,0x00,0x0f,0xe0,0x7f,0xff,0xe0 ,0x00,0x00,0x07,0xc0,0xff,0xff,0xe0 ,0x00,0x00,0x00,0x00,0x7f,0xff,0xe0 ,0x00,0x00,0x00,0x00,0x3f,0xff,0x80 ,0x00,0x00,0x00,0x00,0x1f,0xbf,0x00 ,0x00,0x00,0x00,0x00,0x03,0x18,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; #define Wifi_connected_width 63 #define Wifi_connected_height 49 const uint8_t PROGMEM Wifi_connected_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x03,0xff,0xff,0x80,0x00,0x00 ,0x00,0x00,0x3f,0xff,0xff,0xf8,0x00,0x00 ,0x00,0x01,0xff,0xff,0xff,0xff,0x00,0x00 ,0x00,0x0f,0xff,0xff,0xff,0xff,0xe0,0x00 ,0x00,0x3f,0xff,0xc0,0x07,0xff,0xf8,0x00 ,0x00,0xff,0xf8,0x00,0x00,0x3f,0xfe,0x00 ,0x03,0xff,0x80,0x00,0x00,0x03,0xff,0x80 ,0x07,0xfe,0x00,0x00,0x00,0x00,0xff,0xc0 ,0x1f,0xf8,0x00,0x00,0x00,0x00,0x3f,0xf0 ,0x3f,0xe0,0x01,0xff,0xff,0x00,0x0f,0xf8 ,0x7f,0x80,0x0f,0xff,0xff,0xe0,0x03,0xfc ,0xff,0x00,0x7f,0xff,0xff,0xfc,0x01,0xfe ,0xfc,0x01,0xff,0xff,0xff,0xff,0x00,0x7e ,0x78,0x07,0xff,0xc0,0x07,0xff,0xc0,0x3c ,0x00,0x0f,0xfc,0x00,0x00,0x7f,0xe0,0x00 ,0x00,0x1f,0xf0,0x00,0x00,0x1f,0xf0,0x00 ,0x00,0x3f,0xc0,0x00,0x00,0x07,0xf8,0x00 ,0x00,0x7f,0x00,0x01,0x00,0x01,0xfc,0x00 ,0x00,0x7e,0x00,0x7f,0xfc,0x00,0xfc,0x00 ,0x00,0x3c,0x03,0xff,0xff,0x80,0x78,0x00 ,0x00,0x00,0x07,0xff,0xff,0xc0,0x00,0x00 ,0x00,0x00,0x1f,0xff,0xff,0xf0,0x00,0x00 ,0x00,0x00,0x3f,0xf0,0x1f,0xf8,0x00,0x00 ,0x00,0x00,0x3f,0x80,0x03,0xf8,0x00,0x00 ,0x00,0x00,0x3f,0x00,0x01,0xf8,0x00,0x00 ,0x00,0x00,0x1c,0x00,0x00,0x70,0x00,0x00 ,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00 ,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x1f,0xf0,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; #define FinPr_start_width 64 #define FinPr_start_height 64 const uint8_t PROGMEM FinPr_start_bits[] = { 0x00,0x00,0x00,0x1f,0xe0,0x00,0x00,0x00 ,0x00,0x00,0x01,0xff,0xfe,0x00,0x00,0x00 ,0x00,0x00,0x03,0xff,0xff,0x80,0x00,0x00 ,0x00,0x00,0x0f,0xc0,0x0f,0xe0,0x00,0x00 ,0x00,0x00,0x1f,0x00,0x01,0xf8,0x00,0x00 ,0x00,0x00,0x3c,0x00,0x00,0x7c,0x00,0x00 ,0x00,0x00,0x78,0x00,0x00,0x3e,0x00,0x00 ,0x00,0x00,0xf0,0x3f,0xf8,0x0f,0x00,0x00 ,0x00,0x01,0xe0,0xff,0xfe,0x07,0x80,0x00 ,0x00,0x03,0xc3,0xff,0xff,0x03,0x80,0x00 ,0x00,0x03,0x87,0xc0,0x07,0xc3,0xc0,0x00 ,0x00,0x07,0x0f,0x00,0x03,0xe1,0xc0,0x00 ,0x00,0x0f,0x0e,0x00,0x00,0xe0,0xe0,0x00 ,0x00,0x0e,0x1c,0x00,0x00,0xf0,0xe0,0x00 ,0x00,0x0c,0x3c,0x1f,0xe0,0x70,0xe0,0x00 ,0x00,0x00,0x38,0x3f,0xf0,0x38,0x70,0x00 ,0x00,0x00,0x78,0x78,0xf8,0x38,0x70,0x00 ,0x00,0x00,0x70,0x70,0x3c,0x18,0x70,0x00 ,0x00,0x00,0xe0,0xe0,0x1e,0x1c,0x70,0x00 ,0x00,0x03,0xe1,0xe0,0x0e,0x1c,0x70,0x00 ,0x00,0x0f,0xc1,0xc3,0x0e,0x1c,0x70,0x00 ,0x00,0x3f,0x03,0xc3,0x8e,0x1c,0x70,0x00 ,0x00,0x3e,0x03,0x87,0x0e,0x1c,0x70,0x00 ,0x00,0x30,0x07,0x07,0x0e,0x18,0xe0,0x00 ,0x00,0x00,0x0e,0x0e,0x0e,0x38,0xe0,0x00 ,0x00,0x00,0x3e,0x1e,0x1e,0x38,0xe0,0x00 ,0x00,0x00,0xf8,0x1c,0x1c,0x38,0xe0,0x00 ,0x00,0x03,0xf0,0x38,0x3c,0x38,0xe0,0x00 ,0x00,0x3f,0xc0,0xf8,0x78,0x38,0xe0,0x00 ,0x00,0x7f,0x01,0xf0,0x70,0x38,0xf0,0x00 ,0x00,0x78,0x03,0xe0,0xe0,0x38,0x70,0x00 ,0x00,0x00,0x0f,0x81,0xe0,0x38,0x7c,0x00 ,0x00,0x00,0x3f,0x03,0xc0,0x38,0x3e,0x00 ,0x00,0x00,0xfc,0x0f,0x80,0x38,0x1e,0x00 ,0x00,0x07,0xf0,0x1f,0x1c,0x1c,0x04,0x00 ,0x00,0x3f,0xc0,0x3e,0x3f,0x1e,0x00,0x00 ,0x00,0x7f,0x00,0xf8,0x7f,0x0f,0x00,0x00 ,0x00,0x38,0x01,0xf0,0xf7,0x07,0xc0,0x00 ,0x00,0x00,0x07,0xe1,0xe3,0x83,0xf8,0x00 ,0x00,0x00,0x3f,0x87,0xc3,0xc0,0xfc,0x00 ,0x00,0x01,0xfe,0x0f,0x81,0xe0,0x3c,0x00 ,0x00,0x0f,0xf8,0x1f,0x00,0xf0,0x00,0x00 ,0x00,0x1f,0xc0,0x7c,0x00,0x7c,0x00,0x00 ,0x00,0x1e,0x01,0xf8,0x00,0x3f,0x00,0x00 ,0x00,0x00,0x07,0xe0,0x78,0x0f,0xc0,0x00 ,0x00,0x00,0x3f,0x81,0xfe,0x07,0xf0,0x00 ,0x00,0x01,0xfe,0x07,0xff,0x01,0xf0,0x00 ,0x00,0x07,0xf8,0x0f,0x87,0x80,0x30,0x00 ,0x00,0x07,0xc0,0x3f,0x03,0xe0,0x00,0x00 ,0x00,0x06,0x00,0xfc,0x01,0xf8,0x00,0x00 ,0x00,0x00,0x03,0xf0,0x00,0x7e,0x00,0x00 ,0x00,0x00,0x0f,0xc0,0x00,0x3f,0x80,0x00 ,0x00,0x00,0x7f,0x00,0xf8,0x0f,0x80,0x00 ,0x00,0x00,0xfc,0x03,0xfe,0x01,0x80,0x00 ,0x00,0x00,0xf0,0x1f,0xff,0x80,0x00,0x00 ,0x00,0x00,0x00,0x7f,0x07,0xe0,0x00,0x00 ,0x00,0x00,0x00,0xfc,0x03,0xf8,0x00,0x00 ,0x00,0x00,0x03,0xf0,0x00,0x78,0x00,0x00 ,0x00,0x00,0x0f,0xc0,0x00,0x18,0x00,0x00 ,0x00,0x00,0x0f,0x01,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x07,0xfe,0x00,0x00,0x00 ,0x00,0x00,0x00,0x1f,0xfe,0x00,0x00,0x00 ,0x00,0x00,0x00,0x1e,0x0e,0x00,0x00,0x00 ,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00 }; //--------------------------------------------------------------- #define FinPr_valid_width 64 #define FinPr_valid_height 64 const uint8_t PROGMEM FinPr_valid_bits[] = { 0x00,0x00,0x03,0xfe,0x00,0x00,0x00,0x00 ,0x00,0x00,0x1f,0xff,0xe0,0x00,0x00,0x00 ,0x00,0x00,0x7f,0xff,0xf8,0x00,0x00,0x00 ,0x00,0x00,0xfc,0x00,0xfe,0x00,0x00,0x00 ,0x00,0x03,0xe0,0x00,0x1f,0x00,0x00,0x00 ,0x00,0x07,0xc0,0x00,0x07,0x80,0x00,0x00 ,0x00,0x0f,0x80,0x00,0x03,0xe0,0x00,0x00 ,0x00,0x0e,0x03,0xff,0x01,0xe0,0x00,0x00 ,0x00,0x1c,0x1f,0xff,0xe0,0xf0,0x00,0x00 ,0x00,0x3c,0x3f,0xff,0xf0,0x78,0x00,0x00 ,0x00,0x78,0x7c,0x00,0xf8,0x3c,0x00,0x00 ,0x00,0x70,0xf0,0x00,0x3c,0x1c,0x00,0x00 ,0x00,0xe1,0xe0,0x00,0x1e,0x1c,0x00,0x00 ,0x00,0xe1,0xc0,0x00,0x0f,0x0e,0x00,0x00 ,0x00,0xc3,0x81,0xfc,0x07,0x0e,0x00,0x00 ,0x00,0x03,0x83,0xff,0x07,0x8e,0x00,0x00 ,0x00,0x07,0x07,0x8f,0x83,0x87,0x00,0x00 ,0x00,0x0f,0x0f,0x03,0xc3,0x87,0x00,0x00 ,0x00,0x1e,0x0e,0x01,0xc3,0x87,0x00,0x00 ,0x00,0x3c,0x1c,0x00,0xe1,0x87,0x00,0x00 ,0x00,0xf8,0x1c,0x30,0xe1,0x87,0x00,0x00 ,0x07,0xf0,0x38,0x70,0xe1,0x86,0x00,0x00 ,0x07,0xc0,0x78,0x70,0xe3,0x8e,0x00,0x00 ,0x02,0x00,0xf0,0xf0,0xe3,0x8e,0x00,0x00 ,0x00,0x01,0xe0,0xe0,0xe3,0x8e,0x00,0x00 ,0x00,0x03,0xc1,0xe1,0xc3,0x8e,0x00,0x00 ,0x00,0x0f,0x83,0xc3,0xc3,0x8e,0x00,0x00 ,0x00,0x7f,0x07,0x83,0x83,0x0e,0x00,0x00 ,0x07,0xfc,0x0f,0x07,0x83,0x0e,0x00,0x00 ,0x07,0xf0,0x1e,0x0f,0x03,0x0e,0x00,0x00 ,0x07,0x80,0x7c,0x1e,0x03,0x07,0x00,0x00 ,0x00,0x00,0xf8,0x3c,0x03,0x87,0x80,0x00 ,0x00,0x03,0xf0,0x78,0x03,0x83,0xc0,0x00 ,0x00,0x1f,0xc0,0xf0,0x02,0x00,0x00,0x00 ,0x00,0xff,0x01,0xe1,0xc0,0x0c,0x00,0x00 ,0x07,0xfc,0x03,0xc3,0xe1,0xff,0xc0,0x00 ,0x07,0xe0,0x0f,0x87,0xc7,0xff,0xf0,0x00 ,0x07,0x00,0x3f,0x0f,0x0f,0xff,0xfc,0x00 ,0x00,0x00,0x7c,0x3e,0x3f,0xff,0xfe,0x00 ,0x00,0x03,0xf8,0x7c,0x3f,0xff,0xff,0x00 ,0x00,0x1f,0xe0,0xf0,0x7f,0xff,0xff,0x80 ,0x00,0xff,0x83,0xe0,0xff,0xff,0xff,0x80 ,0x01,0xfc,0x07,0xc1,0xff,0xff,0xe3,0xc0 ,0x01,0xe0,0x1f,0x01,0xff,0xff,0xc3,0xc0 ,0x00,0x00,0xfe,0x01,0xff,0xff,0x87,0xe0 ,0x00,0x03,0xf8,0x13,0xff,0xff,0x0f,0xe0 ,0x00,0x1f,0xe0,0x73,0xff,0xfe,0x1f,0xe0 ,0x00,0x7f,0x81,0xf3,0xff,0xfc,0x1f,0xe0 ,0x00,0xfc,0x03,0xe3,0xef,0xf8,0x3f,0xe0 ,0x00,0x60,0x0f,0xc3,0xc7,0xf0,0x7f,0xe0 ,0x00,0x00,0x3f,0x03,0xc3,0xe0,0xff,0xe0 ,0x00,0x00,0xfc,0x03,0xc1,0xc1,0xff,0xe0 ,0x00,0x07,0xf0,0x13,0xe0,0x83,0xff,0xe0 ,0x00,0x0f,0xc0,0x7b,0xf8,0x07,0xff,0xe0 ,0x00,0x0f,0x01,0xf9,0xfc,0x0f,0xff,0xc0 ,0x00,0x00,0x07,0xf1,0xfe,0x1f,0xff,0xc0 ,0x00,0x00,0x1f,0xc0,0xff,0x3f,0xff,0x80 ,0x00,0x00,0x7e,0x00,0xff,0xff,0xff,0x80 ,0x00,0x00,0xfc,0x00,0x7f,0xff,0xff,0x00 ,0x00,0x00,0xf0,0x1f,0x3f,0xff,0xfe,0x00 ,0x00,0x00,0x00,0x7f,0x1f,0xff,0xfc,0x00 ,0x00,0x00,0x01,0xff,0x8f,0xff,0xf8,0x00 ,0x00,0x00,0x03,0xe0,0xe3,0xff,0xe0,0x00 ,0x00,0x00,0x01,0x80,0x00,0x7f,0x00,0x00 }; //--------------------------------------------------------------- #define FinPr_invalid_width 64 #define FinPr_invalid_height 64 const uint8_t PROGMEM FinPr_invalid_bits[] = { 0x00,0x00,0x03,0xfe,0x00,0x00,0x00,0x00 ,0x00,0x00,0x1f,0xff,0xe0,0x00,0x00,0x00 ,0x00,0x00,0x7f,0xff,0xf8,0x00,0x00,0x00 ,0x00,0x00,0xfc,0x00,0xfe,0x00,0x00,0x00 ,0x00,0x03,0xe0,0x00,0x1f,0x00,0x00,0x00 ,0x00,0x07,0xc0,0x00,0x07,0x80,0x00,0x00 ,0x00,0x0f,0x80,0x00,0x03,0xe0,0x00,0x00 ,0x00,0x0e,0x03,0xff,0x01,0xe0,0x00,0x00 ,0x00,0x1c,0x1f,0xff,0xe0,0xf0,0x00,0x00 ,0x00,0x3c,0x3f,0xff,0xf0,0x78,0x00,0x00 ,0x00,0x78,0x7c,0x00,0xf8,0x3c,0x00,0x00 ,0x00,0x70,0xf0,0x00,0x3c,0x1c,0x00,0x00 ,0x00,0xe1,0xe0,0x00,0x1e,0x1c,0x00,0x00 ,0x00,0xe1,0xc0,0x00,0x0f,0x0e,0x00,0x00 ,0x00,0xc3,0x81,0xfc,0x07,0x0e,0x00,0x00 ,0x00,0x03,0x83,0xff,0x07,0x8e,0x00,0x00 ,0x00,0x07,0x07,0x8f,0x83,0x87,0x00,0x00 ,0x00,0x0f,0x0f,0x03,0xc3,0x87,0x00,0x00 ,0x00,0x1e,0x0e,0x01,0xc3,0x87,0x00,0x00 ,0x00,0x3c,0x1c,0x00,0xe1,0x87,0x00,0x00 ,0x00,0xf8,0x1c,0x30,0xe1,0x87,0x00,0x00 ,0x07,0xf0,0x38,0x70,0xe1,0x86,0x00,0x00 ,0x07,0xc0,0x78,0x70,0xe3,0x8e,0x00,0x00 ,0x02,0x00,0xf0,0xf0,0xe3,0x8e,0x00,0x00 ,0x00,0x01,0xe0,0xe0,0xe3,0x8e,0x00,0x00 ,0x00,0x03,0xc1,0xe1,0xc3,0x8e,0x00,0x00 ,0x00,0x0f,0x83,0xc3,0xc3,0x8e,0x00,0x00 ,0x00,0x7f,0x07,0x83,0x83,0x0e,0x00,0x00 ,0x07,0xfc,0x0f,0x07,0x83,0x0e,0x00,0x00 ,0x07,0xf0,0x1e,0x0f,0x03,0x0e,0x00,0x00 ,0x07,0x80,0x7c,0x1e,0x03,0x07,0x00,0x00 ,0x00,0x00,0xf8,0x3c,0x03,0x87,0x80,0x00 ,0x00,0x03,0xf0,0x78,0x03,0x83,0xc0,0x00 ,0x00,0x1f,0xc0,0xf0,0x02,0x00,0x00,0x00 ,0x00,0xff,0x01,0xe1,0xc0,0x00,0x00,0x00 ,0x07,0xfc,0x03,0xc3,0xe1,0xff,0xc0,0x00 ,0x07,0xe0,0x0f,0x87,0xc7,0xff,0xf0,0x00 ,0x07,0x00,0x3f,0x0f,0x0f,0xff,0xf8,0x00 ,0x00,0x00,0x7c,0x3e,0x1f,0xff,0xfe,0x00 ,0x00,0x03,0xf8,0x7c,0x3f,0xff,0xff,0x00 ,0x00,0x1f,0xe0,0xf0,0x7f,0xff,0xff,0x00 ,0x00,0xff,0x83,0xe0,0xfe,0xff,0xbf,0x80 ,0x01,0xfc,0x07,0xc0,0xfc,0x7f,0x1f,0xc0 ,0x01,0xe0,0x1f,0x01,0xf8,0x3e,0x0f,0xc0 ,0x00,0x00,0xfe,0x01,0xf8,0x1c,0x07,0xe0 ,0x00,0x03,0xf8,0x13,0xf8,0x00,0x0f,0xe0 ,0x00,0x1f,0xe0,0x73,0xfc,0x00,0x1f,0xe0 ,0x00,0x7f,0x81,0xf3,0xfe,0x00,0x3f,0xe0 ,0x00,0xfc,0x03,0xe3,0xff,0x00,0x7f,0xe0 ,0x00,0x60,0x0f,0xc3,0xff,0x80,0xff,0xe0 ,0x00,0x00,0x3f,0x03,0xff,0x00,0x7f,0xe0 ,0x00,0x00,0xfc,0x03,0xfe,0x00,0x3f,0xe0 ,0x00,0x07,0xf0,0x13,0xfc,0x00,0x1f,0xe0 ,0x00,0x0f,0xc0,0x79,0xf8,0x08,0x0f,0xe0 ,0x00,0x0f,0x01,0xf9,0xf8,0x1c,0x0f,0xc0 ,0x00,0x00,0x07,0xf1,0xfc,0x3e,0x1f,0xc0 ,0x00,0x00,0x1f,0xc0,0xfe,0x7f,0x3f,0x80 ,0x00,0x00,0x7e,0x00,0xff,0xff,0xff,0x80 ,0x00,0x00,0xfc,0x00,0x7f,0xff,0xff,0x00 ,0x00,0x00,0xf0,0x1f,0x3f,0xff,0xfe,0x00 ,0x00,0x00,0x00,0x7f,0x1f,0xff,0xfc,0x00 ,0x00,0x00,0x01,0xff,0x8f,0xff,0xf8,0x00 ,0x00,0x00,0x03,0xe0,0xe3,0xff,0xe0,0x00 ,0x00,0x00,0x01,0x80,0x00,0x7f,0x00,0x00 }; //--------------------------------------------------------------- #define FinPr_failed_width 64 #define FinPr_failed_height 64 const uint8_t PROGMEM FinPr_failed_bits[] = { 0x00,0x00,0x3f,0xe0,0x00,0x00,0x00,0x00 ,0x00,0x01,0xff,0xfe,0x00,0x00,0x00,0x00 ,0x00,0x0f,0xc0,0x1f,0x80,0x00,0x00,0x00 ,0x00,0x1e,0x00,0x03,0xc0,0x00,0x00,0x00 ,0x00,0x78,0x00,0x00,0xf0,0x00,0x00,0x00 ,0x00,0xe0,0x00,0x00,0x38,0x00,0x00,0x00 ,0x01,0xc0,0x00,0x00,0x1c,0x00,0x00,0x00 ,0x03,0x80,0x00,0x00,0x0e,0x00,0x00,0x00 ,0x07,0x00,0x7f,0xe0,0x07,0x00,0x00,0x00 ,0x06,0x01,0xff,0xf8,0x03,0x00,0x00,0x00 ,0x0c,0x03,0xc0,0x3c,0x03,0x80,0x00,0x00 ,0x1c,0x0f,0x00,0x0e,0x01,0x80,0x00,0x00 ,0x18,0x0c,0x00,0x03,0x00,0xc0,0x00,0x00 ,0x18,0x18,0x00,0x01,0x80,0xc0,0x00,0x00 ,0x30,0x38,0x00,0x01,0xc0,0xe0,0x00,0x00 ,0x30,0x30,0x0f,0x00,0xc0,0x60,0x00,0x00 ,0x30,0x30,0x3f,0xc0,0xe0,0x60,0x00,0x00 ,0x70,0x60,0x78,0xe0,0x60,0x60,0x00,0x00 ,0x60,0x60,0x60,0x60,0x60,0x70,0x00,0x00 ,0x60,0x60,0x60,0x60,0x60,0x30,0x00,0x00 ,0x60,0x60,0x60,0x60,0x30,0x30,0x00,0x00 ,0x60,0x60,0x60,0x30,0x30,0x20,0x00,0x00 ,0x60,0x60,0x60,0x30,0x30,0x01,0xe0,0x00 ,0x60,0x60,0x60,0x30,0x30,0x0f,0xfc,0x00 ,0x60,0x60,0x60,0x30,0x30,0x3f,0xff,0x00 ,0x60,0x60,0x60,0x30,0x18,0x78,0x03,0x80 ,0x60,0x60,0x60,0x30,0x1c,0x60,0x01,0x80 ,0x60,0x60,0x30,0x38,0x0c,0xc0,0x00,0xc0 ,0x00,0x60,0x30,0x18,0x00,0xc0,0x00,0xc0 ,0x00,0x60,0x30,0x18,0x00,0xc0,0x00,0xc0 ,0x00,0xe0,0x30,0x0c,0x01,0xc0,0x00,0xe0 ,0x00,0xc0,0x18,0x0e,0x01,0xc0,0x00,0xe0 ,0x60,0xc0,0x18,0x07,0x01,0xc0,0x00,0xe0 ,0x01,0xc0,0x1c,0x03,0x81,0xc0,0x00,0xe0 ,0x01,0x80,0x0c,0x01,0xc1,0xc0,0x00,0xe0 ,0x03,0x80,0x0e,0x00,0xf1,0xc0,0x00,0xe0 ,0x0f,0x00,0x06,0x00,0x01,0xc0,0x00,0xe0 ,0x3e,0x01,0x03,0x00,0x01,0xc0,0x00,0xe0 ,0x30,0x03,0x83,0x80,0x1f,0xff,0xff,0xfe ,0x00,0x03,0x81,0xc0,0x3f,0xff,0xff,0xff ,0x00,0x07,0xc0,0xe0,0x30,0x00,0x00,0x03 ,0x00,0x0e,0xc0,0x78,0x30,0x00,0x00,0x03 ,0x00,0x3c,0x60,0x1e,0x30,0x00,0x00,0x03 ,0x00,0x78,0x70,0x0f,0x30,0x00,0x00,0x03 ,0x03,0xe0,0x38,0x03,0x30,0x00,0x00,0x03 ,0x07,0x80,0x1c,0x00,0x30,0x00,0x00,0x03 ,0xc0,0x00,0x0f,0x00,0x30,0x00,0x00,0x03 ,0xc0,0x00,0x03,0x80,0x30,0x01,0xe0,0x03 ,0x00,0x18,0x01,0xe0,0x30,0x03,0xf0,0x03 ,0x00,0x18,0x00,0x7c,0x30,0x07,0x38,0x03 ,0x00,0x0c,0x00,0x1f,0x30,0x06,0x18,0x03 ,0x18,0x0e,0x00,0x07,0x30,0x06,0x18,0x03 ,0x0c,0x07,0x80,0x00,0x30,0x07,0x38,0x03 ,0x0e,0x03,0xc0,0x00,0x30,0x03,0x30,0x03 ,0x07,0x00,0xf0,0x00,0x30,0x03,0x30,0x03 ,0x03,0x00,0x7e,0x00,0x30,0x03,0x30,0x03 ,0x01,0x80,0x1f,0xc0,0x30,0x03,0x30,0x03 ,0x01,0xc0,0x03,0xe1,0x30,0x07,0xf8,0x03 ,0x00,0xf0,0x00,0x01,0x30,0x03,0xf0,0x03 ,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x03 ,0x00,0x1e,0x00,0x00,0x30,0x00,0x00,0x03 ,0x00,0x07,0xc0,0x00,0x30,0x00,0x00,0x03 ,0x00,0x01,0xff,0x80,0x3f,0xff,0xff,0xff ,0x00,0x00,0x3f,0x80,0x1f,0xff,0xff,0xfe }; //--------------------------------------------------------------- #define FinPr_scan_width 64 #define FinPr_scan_height 64 const uint8_t PROGMEM FinPr_scan_bits[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x1f,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00 ,0x00,0x00,0x01,0xfc,0x7f,0xc0,0x00,0x00 ,0x00,0x00,0x03,0xc0,0x03,0xe0,0x00,0x00 ,0x00,0x00,0x07,0x80,0x00,0xf0,0x00,0x00 ,0x00,0x00,0x0e,0x00,0x00,0x3c,0x00,0x00 ,0x00,0x00,0x1c,0x1f,0xfc,0x1c,0x00,0x00 ,0x00,0x00,0x38,0x7f,0xfe,0x0e,0x00,0x00 ,0x00,0x00,0x78,0xf8,0x0f,0x87,0x00,0x00 ,0x00,0x00,0x71,0xe0,0x03,0xc7,0x00,0x00 ,0x00,0x00,0xe3,0x80,0x01,0xc3,0x80,0x00 ,0x00,0x00,0xc3,0x83,0xc0,0xe3,0x80,0x00 ,0x00,0x00,0xc7,0x0f,0xf0,0x71,0x80,0x00 ,0x00,0x00,0x06,0x1f,0xf8,0x71,0xc0,0x00 ,0x00,0x00,0x0e,0x1c,0x3c,0x31,0xc0,0x00 ,0x00,0x00,0x1c,0x38,0x1c,0x31,0xc0,0x00 ,0x00,0x00,0x38,0x70,0x0e,0x39,0xc0,0x00 ,0x00,0x01,0xf0,0x71,0x8e,0x39,0xc0,0x00 ,0x00,0x03,0xe0,0xe1,0x86,0x31,0xc0,0x00 ,0x00,0x03,0x81,0xe3,0x8e,0x31,0x80,0x00 ,0x00,0x00,0x03,0xc3,0x8e,0x33,0x80,0x00 ,0x00,0x00,0x07,0x87,0x0c,0x73,0x80,0x00 ,0x00,0x00,0x1f,0x0e,0x1c,0x73,0x80,0x00 ,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xfe ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff ,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xfe ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x03,0xf0,0x1e,0x3e,0x1c,0x00,0x00 ,0x00,0x03,0x80,0x7c,0x77,0x0f,0x00,0x00 ,0x00,0x00,0x01,0xf0,0xe3,0x07,0xc0,0x00 ,0x00,0x00,0x07,0xe3,0xc3,0x81,0xf0,0x00 ,0x00,0x00,0x3f,0x87,0x81,0xc0,0x60,0x00 ,0x00,0x01,0xfc,0x1f,0x00,0xf0,0x00,0x00 ,0x00,0x01,0xe0,0x3c,0x00,0x7c,0x00,0x00 ,0x00,0x00,0x00,0xf8,0x78,0x1f,0x00,0x00 ,0x00,0x00,0x07,0xe0,0xfc,0x0f,0xc0,0x00 ,0x00,0x00,0x3f,0x83,0xef,0x03,0xc0,0x00 ,0x00,0x00,0xfc,0x0f,0x87,0x80,0x00,0x00 ,0x00,0x00,0x70,0x1f,0x03,0xe0,0x00,0x00 ,0x00,0x00,0x00,0x7c,0x00,0xf8,0x00,0x00 ,0x00,0x00,0x01,0xf0,0x00,0x3e,0x00,0x00 ,0x00,0x00,0x0f,0xc0,0xf8,0x0f,0x00,0x00 ,0x00,0x00,0x1f,0x03,0xfe,0x02,0x00,0x00 ,0x00,0x00,0x0c,0x0f,0x8f,0x80,0x00,0x00 ,0x00,0x00,0x00,0x3f,0x03,0xe0,0x00,0x00 ,0x00,0x00,0x00,0xf8,0x00,0xf0,0x00,0x00 ,0x00,0x00,0x01,0xe0,0x00,0x30,0x00,0x00 ,0x00,0x00,0x01,0xc0,0xf8,0x00,0x00,0x00 ,0x00,0x00,0x00,0x07,0xfe,0x00,0x00,0x00 ,0x00,0x00,0x00,0x0f,0x8e,0x00,0x00,0x00 ,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; //************************************************************************ void setup() { Serial.begin(115200); //-----------initiate OLED display------------- // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. // you can delet these three lines if you don't want to get the Adfruit logo appear display.display(); delay(2000); // Pause for 2 seconds display.clearDisplay(); //--------------------------------------------- connectToWiFi(); //--------------------------------------------- // set the data rate for the sensor serial port finger.begin(57600); Serial.println("\n\nAdafruit finger detect test"); if (finger.verifyPassword()) { Serial.println("Found fingerprint sensor!"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); } else { Serial.println("Did not find fingerprint sensor :("); display.clearDisplay(); display.drawBitmap( 32, 0, FinPr_failed_bits, FinPr_failed_width, FinPr_failed_height, WHITE); display.display(); while (1) { delay(1); } } //--------------------------------------------- finger.getTemplateCount(); Serial.print("Sensor contains "); Serial.print(finger.templateCount); Serial.println(" templates"); Serial.println("Waiting for valid finger..."); //------------*test the connection*------------ //SendFingerprintID( FingerID ); } //************************************************************************ void loop() { //check if there's a connection to WiFi or not if(WiFi.status() != WL_CONNECTED){ connectToWiFi(); } //--------------------------------------------- //If there no fingerprint has been scanned return -1 or -2 if there an error or 0 if there nothing, The ID start form 1 to 127 FingerID = getFingerprintID(); // Get the Fingerprint ID from the Scanner delay(50); //don't need to run this at full speed. //--------------------------------------------- DisplayFingerprintID(); //--------------------------------------------- ChecktoAddID(); //--------------------------------------------- ChecktoDeleteID(); //--------------------------------------------- } //************Display the fingerprint ID state on the OLED************* void DisplayFingerprintID(){ //Fingerprint has been detected if (FingerID > 0){ display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); SendFingerprintID( FingerID ); // Send the Fingerprint ID to the website. } //--------------------------------------------- //No finger detected else if (FingerID == 0){ display.clearDisplay(); display.drawBitmap( 32, 0, FinPr_start_bits, FinPr_start_width, FinPr_start_height, WHITE); display.display(); } //--------------------------------------------- //Didn't find a match else if (FingerID == -1){ display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_invalid_bits, FinPr_invalid_width, FinPr_invalid_height, WHITE); display.display(); } //--------------------------------------------- //Didn't find the scanner or there an error else if (FingerID == -2){ display.clearDisplay(); display.drawBitmap( 32, 0, FinPr_failed_bits, FinPr_failed_width, FinPr_failed_height, WHITE); display.display(); } } //************send the fingerprint ID to the website************* void SendFingerprintID( int finger ){ HTTPClient http; //Declare object of class HTTPClient //Post Data postData = "FingerID=" + String(finger); // Add the Fingerprint ID to the Post array in order to send it // Post methode http.begin(link); //initiate HTTP request, put your Website URL or Your Computer IP http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header int httpCode = http.POST(postData); //Send the request String payload = http.getString(); //Get the response payload Serial.println(httpCode); //Print HTTP return code Serial.println(payload); //Print request response payload Serial.println(postData); //Post Data Serial.println(finger); //Print fingerprint ID if (payload.substring(0, 5) == "login") { String user_name = payload.substring(5); // Serial.println(user_name); display.clearDisplay(); display.setTextSize(2); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(15,0); // Start at top-left corner display.print(F("Welcome")); display.setCursor(0,20); display.print(user_name); display.display(); } else if (payload.substring(0, 6) == "logout") { String user_name = payload.substring(6); // Serial.println(user_name); display.clearDisplay(); display.setTextSize(2); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(10,0); // Start at top-left corner display.print(F("Good Bye")); display.setCursor(0,20); display.print(user_name); display.display(); } delay(1000); postData = ""; http.end(); //Close connection } //********************Get the Fingerprint ID****************** int getFingerprintID() { uint8_t p = finger.getImage(); switch (p) { case FINGERPRINT_OK: //Serial.println("Image taken"); break; case FINGERPRINT_NOFINGER: //Serial.println("No finger detected"); return 0; case FINGERPRINT_PACKETRECIEVEERR: //Serial.println("Communication error"); return -2; case FINGERPRINT_IMAGEFAIL: //Serial.println("Imaging error"); return -2; default: //Serial.println("Unknown error"); return -2; } // OK success! p = finger.image2Tz(); switch (p) { case FINGERPRINT_OK: //Serial.println("Image converted"); break; case FINGERPRINT_IMAGEMESS: //Serial.println("Image too messy"); return -1; case FINGERPRINT_PACKETRECIEVEERR: //Serial.println("Communication error"); return -2; case FINGERPRINT_FEATUREFAIL: //Serial.println("Could not find fingerprint features"); return -2; case FINGERPRINT_INVALIDIMAGE: //Serial.println("Could not find fingerprint features"); return -2; default: //Serial.println("Unknown error"); return -2; } // OK converted! p = finger.fingerFastSearch(); if (p == FINGERPRINT_OK) { //Serial.println("Found a print match!"); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { //Serial.println("Communication error"); return -2; } else if (p == FINGERPRINT_NOTFOUND) { //Serial.println("Did not find a match"); return -1; } else { //Serial.println("Unknown error"); return -2; } // found a match! //Serial.print("Found ID #"); Serial.print(finger.fingerID); //Serial.print(" with confidence of "); Serial.println(finger.confidence); return finger.fingerID; } //******************Check if there a Fingerprint ID to delete****************** void ChecktoDeleteID(){ HTTPClient http; //Declare object of class HTTPClient //Post Data postData = "DeleteID=check"; // Add the Fingerprint ID to the Post array in order to send it // Post methode http.begin(link); //initiate HTTP request, put your Website URL or Your Computer IP http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header int httpCode = http.POST(postData); //Send the request String payload = http.getString(); //Get the response payload if (payload.substring(0, 6) == "del-id") { String del_id = payload.substring(6); Serial.println(del_id); deleteFingerprint( del_id.toInt() ); } http.end(); //Close connection } //******************Delete Finpgerprint ID***************** uint8_t deleteFingerprint( int id) { uint8_t p = -1; p = finger.deleteModel(id); if (p == FINGERPRINT_OK) { //Serial.println("Deleted!"); display.clearDisplay(); display.setTextSize(2); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Deleted!\n")); display.display(); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { //Serial.println("Communication error"); display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Communication error!\n")); display.display(); return p; } else if (p == FINGERPRINT_BADLOCATION) { //Serial.println("Could not delete in that location"); display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Could not delete in that location!\n")); display.display(); return p; } else if (p == FINGERPRINT_FLASHERR) { //Serial.println("Error writing to flash"); display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Error writing to flash!\n")); display.display(); return p; } else { //Serial.print("Unknown error: 0x"); Serial.println(p, HEX); display.clearDisplay(); display.setTextSize(2); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Unknown error:\n")); display.display(); return p; } } //******************Check if there a Fingerprint ID to add****************** void ChecktoAddID(){ HTTPClient http; //Declare object of class HTTPClient //Post Data postData = "Get_Fingerid=get_id"; // Add the Fingerprint ID to the Post array in order to send it // Post methode http.begin(link); //initiate HTTP request, put your Website URL or Your Computer IP http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header int httpCode = http.POST(postData); //Send the request String payload = http.getString(); //Get the response payload if (payload.substring(0, 6) == "add-id") { String add_id = payload.substring(6); Serial.println(add_id); id = add_id.toInt(); getFingerprintEnroll(); } http.end(); //Close connection } //******************Enroll a Finpgerprint ID***************** uint8_t getFingerprintEnroll() { int p = -1; display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_scan_bits, FinPr_scan_width, FinPr_scan_height, WHITE); display.display(); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: //Serial.println("Image taken"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); break; case FINGERPRINT_NOFINGER: //Serial.println("."); display.setTextSize(1); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("scanning")); display.display(); break; case FINGERPRINT_PACKETRECIEVEERR: display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_invalid_bits, FinPr_invalid_width, FinPr_invalid_height, WHITE); display.display(); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); break; default: Serial.println("Unknown error"); break; } } // OK success! p = finger.image2Tz(1); switch (p) { case FINGERPRINT_OK: display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); break; case FINGERPRINT_IMAGEMESS: display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_invalid_bits, FinPr_invalid_width, FinPr_invalid_height, WHITE); display.display(); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Could not find fingerprint features"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Could not find fingerprint features"); return p; default: Serial.println("Unknown error"); return p; } display.clearDisplay(); display.setTextSize(2); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("Remove")); display.setCursor(0,20); display.print(F("finger")); display.display(); //Serial.println("Remove finger"); delay(2000); p = 0; while (p != FINGERPRINT_NOFINGER) { p = finger.getImage(); } Serial.print("ID "); Serial.println(id); p = -1; display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_scan_bits, FinPr_scan_width, FinPr_scan_height, WHITE); display.display(); while (p != FINGERPRINT_OK) { p = finger.getImage(); switch (p) { case FINGERPRINT_OK: //Serial.println("Image taken"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); break; case FINGERPRINT_NOFINGER: //Serial.println("."); display.setTextSize(1); // Normal 2:2 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(F("scanning")); display.display(); break; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); break; case FINGERPRINT_IMAGEFAIL: Serial.println("Imaging error"); break; default: Serial.println("Unknown error"); break; } } // OK success! p = finger.image2Tz(2); switch (p) { case FINGERPRINT_OK: //Serial.println("Image converted"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); break; case FINGERPRINT_IMAGEMESS: Serial.println("Image too messy"); return p; case FINGERPRINT_PACKETRECIEVEERR: Serial.println("Communication error"); return p; case FINGERPRINT_FEATUREFAIL: Serial.println("Could not find fingerprint features"); return p; case FINGERPRINT_INVALIDIMAGE: Serial.println("Could not find fingerprint features"); return p; default: Serial.println("Unknown error"); return p; } // OK converted! Serial.print("Creating model for #"); Serial.println(id); p = finger.createModel(); if (p == FINGERPRINT_OK) { //Serial.println("Prints matched!"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_ENROLLMISMATCH) { Serial.println("Fingerprints did not match"); return p; } else { Serial.println("Unknown error"); return p; } Serial.print("ID "); Serial.println(id); p = finger.storeModel(id); if (p == FINGERPRINT_OK) { //Serial.println("Stored!"); display.clearDisplay(); display.drawBitmap( 34, 0, FinPr_valid_bits, FinPr_valid_width, FinPr_valid_height, WHITE); display.display(); confirmAdding(); } else if (p == FINGERPRINT_PACKETRECIEVEERR) { Serial.println("Communication error"); return p; } else if (p == FINGERPRINT_BADLOCATION) { Serial.println("Could not store in that location"); return p; } else if (p == FINGERPRINT_FLASHERR) { Serial.println("Error writing to flash"); return p; } else { Serial.println("Unknown error"); return p; } } //******************Check if there a Fingerprint ID to add****************** void confirmAdding(){ HTTPClient http; //Declare object of class HTTPClient //Post Data postData = "confirm_id=" + String(id); // Add the Fingerprint ID to the Post array in order to send it // Post methode http.begin(link); //initiate HTTP request, put your Website URL or Your Computer IP http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header int httpCode = http.POST(postData); //Send the request String payload = http.getString(); //Get the response payload display.clearDisplay(); display.setTextSize(1.5); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0,0); // Start at top-left corner display.print(payload); display.display(); delay(1000); Serial.println(payload); http.end(); //Close connection } //********************connect to the WiFi****************** void connectToWiFi(){ WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect) delay(1000); WiFi.mode(WIFI_STA); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); display.clearDisplay(); display.setTextSize(1); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(0, 0); // Start at top-left corner display.print(F("Connecting to \n")); display.setCursor(0, 50); display.setTextSize(2); display.print(ssid); display.drawBitmap( 73, 10, Wifi_start_bits, Wifi_start_width, Wifi_start_height, WHITE); display.display(); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("Connected"); display.clearDisplay(); display.setTextSize(2); // Normal 1:1 pixel scale display.setTextColor(WHITE); // Draw white text display.setCursor(8, 0); // Start at top-left corner display.print(F("Connected \n")); display.drawBitmap( 33, 15, Wifi_connected_bits, Wifi_connected_width, Wifi_connected_height, WHITE); display.display(); Serial.print("IP address: "); Serial.println(WiFi.localIP()); //IP address assigned to your ESP } //=======================================================================
Registration of users:
Once the Program successfully uploaded to the NodeMCU, It will boot up with the Adafruit logo and then ModeMCU will try to establish the connection between the WiFi router which is provided in the program. Once it gets Connected it will display Connected. The same log can be seen on the Serial Monitor as well as in OLED Display.
So now you can start the registration process of the user on the website using the following link: http://localhost/biometricattendance/ManageUsers.php
The whole process of registration is explained very well in the video. You can follow the video for the complete registration process. The user fingerprint is taken twice i.e as mentioned in the datasheet and stored in EEPROM of Fingerprint Sensor. It is to be noted that only 127 fingerprints can be stored in this R303/R305/R307 module.
Pic: User registration Step1_ScanningPic: User registration Step1_Remove finger
Pic: User registration Step1_Fingerprint has been added.
Authentication of Users:
So once the User registration process is completed, you can start scanning and marking the attendance. If a registered user scans his/her finger for the first time on that day, It will display the welcome message as follows.
If a registered user scans his/her finger for the second time on that day, It will display the goodbye message as follows.
In case if the fingerprint is not matched or an unregistered candidate tries to authenticate it will display an error message as shown in the figure below.
Finally, you can access the entire Attendance data of the Students/Employee on the website by simply selecting the particular date as shown below, You can also download the same data in excel format by clicking on the Export to Excel button.
Realtime implementation of Portable IoT based Fingerprint Biometric Attendance System:
I wanted to take this project to the next level i.e Real-Time implementation, This includes additions circuitry and mechanical parts like Battery, Battery management system, Boost converter and a casing. but there will be no change in the Firmware(Source code)
Since R303a Fingerprint sensor will not work on 3.3v we need to have 5V supply, on the other hand, we should have rechargeable battery i.e Li-ion battery whose voltage is not sufficient to drive the R303a Fingerprint sensor. So I decided to add one boost converter(MT3608) to the circuitry to get 5v.
After these modifications circuit will be like this.
Realtime implementation circuit.
FInal Circuit: Portable IoT based Fingerprint Biometric Attendance System
I made one casing with the wooden stripers to keep all the circuitry in that just have a look at this. I showed this process in the video you can experience it there.
The dimensions for this box are 7x8x5 (cm), I cut down some area on the front part to accommodate the Fingerprint sensor and OLED display.
Final results:
Final product: Portable IoT based Fingerprint Biometric Attendance System
You can follow the video to understanding the whole process like how to add, update and remove the users from the database, how to access the attendance data, how to export the attendance data to the excel. This video will help you through the journey of making Portable IoT Based Fingerprint Biometric Attendance System using NodeMCU.
wow! great work ,, programmed using c …
yeah device program developed with c, but website developed with PHP
the code is showing error
no matching function for call to Softwareserial::Softwareserial(int,int)’
You have to install Software serial library in your machine, first install that and try again.
where do you make the circuit from?
What do you mean???
Circuit making software???
can u develop a project for me we can pay you
the respons payload is not get for adding or registration
thank you for your great work …can you give me the link to downlaod the webinterface(the data base) please. i need it for my graduation project
Provided source code getting too much errors!
provide better code, please.
Same here. The code shows error in the http.begin(link) which says it is an obsolete api. They tell to use begin(wificlient, link) instead
We are unable to do the connection we are using R307 finger sensor model which has 6 pin but in your fingerprint sensor has 4 pin. Please help we are making this as a final year project
Sir unable to do connection I am using R307 finger sensor which has only 6 pin .
Plz help sir I am making this as final year project. Dead line is really very near.
sir my attendance is not being marked, its registering student finger print id but not marking attendance what could be the possible mistake we are doing please help me
Hello sir, is this 1 device supposed for many person to record their attendance ?