Parenting a teenager is quite a difficult and tiring task.
At this age, they are no longer babies to be kept under continuous observation.
On the other hand, they’re not mature enough to be trusted with themselves.
Many teenagers go to school alone, but their parents are always worried. ‘Has my
daughter reached safely at school safely?’ ‘Is my son bunking classes and hanging out
with friends?’ Parents’ minds are often occupied with such questions. Keeping
their tension in mind, in this tutorial, we will make a fingerprint-based
attendance logger. It will keep a record of students’ attendance and
also send an SMS to their parents’
mobiles every time they enter and leave school.
Working principle:
This project works in the following steps:
- At first, the system will enrol
the fingerprints of all students one by one according to their roll
numbers.
- When a fingerprint matches with
an enrolled fingerprint, an LCD shows the student’s roll
number.
- The time of entry and exit is
determined by an RTC.
- The time will be recorded on a
microSD card.
5. The parents will
receive an SMS on their mobiles every time their children reach and leave the
campus.
Components needed:
|
Component’s name |
Quantity |
Website link |
|
Sanguino TSB |
1 |
|
|
Fingerprint Recognition Module (ZFM60) |
1 |
|
|
SIM900A kit |
1 |
|
|
Power distribution board |
1 |
|
|
3-wire LCD |
1 |
|
|
MicroSD card storage board |
1 |
|
|
Team Micro SD HC Card 32GB Class 10 |
1 |
|
|
PCF 8563 RTC Board |
1 |
|
|
Breadboard |
1 |
|
|
12V 700mA Power Adapter |
1 |
|
|
Male to male jumper |
4 |
|
|
Male to female jumper |
20 |
|
|
Soldering iron |
1 |
|
|
Solder lead mini |
1 |
|
|
Sim card |
1 |
What is Sanguino TSB, and
why did we choose it for this project?
Sanguino TSB is am Arduino board equivalent to Arduino UNO-R3. Whatever you can do with Arduino UNO R3, can be done with Sanguino. Sanguino has some benefits over Arduino UNO. Unlike Arduino UNO, it has both male and female headers. All the names of the pins are printed on the board for the User’s convenience. Sanguino TSB’s SRAM, EEPROM, Flash memory are double of Arduino UNO. Sanguino has 2 pairs of USART pins. Tx0, Rx0, Tx1, RX1. The fingerprint scanner and GSM module used in this experiment both use the USART communication protocol. So, it’s not possible to connect these two with an Arduino UNO by hardware serial. At least one had to be connected by software serial. Software serial has some limitations including allowable baud rate only up to 115200, chances of missing bits etc. Keeping this in mind, Sanguino TSB seemed to be the best for this project. It can be implemented with Arduino Mega also, but that will add a bit more to the cost.
Circuit connection:
Step 1- Soldering the fingerprint scanner: Following is the
pinout of the fingerprint scanner. 4 male to male jumpers must be soldered with
the wires as shown in the picture below:
Step 2: Complete the following connection between Sanguino and
Fingerprint scanner.
|
Sanguino TSB |
Fingerprint Recognition Module (ZFM60) |
|
VCC |
VCC |
|
GND |
GND |
|
TX |
RX1 |
|
RX |
TX1 |
Step 3- Connecting the SIM900A module: Following is the pinout of
SIM900A.
To power up SIM900A, we will use a 12V Adapter and power
distribution board. The power distribution board steps down the voltage to 5V
and keeps the output voltage constant.
Complete the following connection among SIM900A, power
distribution board and Sanguino TSB.
|
SIM900A |
Power distribution board |
Sanguino TSB |
|
VCC |
5V |
|
|
GND |
GND |
GND |
Power up the power distribution board with 12V adapter.
Step 4- Connecting the 3-wire LCD: Now connect the 3-wire
LCD with Sanguino TSB.
|
Sanguino TSB |
3-wire LCD |
|
VCC |
VCC |
|
GND |
GND |
|
12 |
DATA |
|
13 |
Clock |
|
3 |
Latch |
Step 5- Connecting the RTC: The PCF 8563 RTC module has an inbuilt
battery. So, there is no need to add any extra battery to power it up. Complete
the following connection between PCF 8563 RTC and Sanguino TSB.
|
Sanguino TSB |
PCF 8563 RTC Board |
|
VCC |
VCC |
|
GND |
GND |
|
SCL |
SCL |
|
SDA |
SDA |
Step 6-Connecting the microSD card holder: Insert the microSD card
inside the microSD card holder and complete the following connection.
|
Sanguino TSB |
MicroSD card storage board |
|
VCC |
VCC |
|
GND |
GND |
|
MISO |
MISO |
|
MOSI |
MOSI |
|
SCK |
SCLK |
|
SS |
CS |
Finally, power up the sanguino TSB with your computer’s USB
PORT.
The whole circuit will look like this:
Now it’s time for coding.
The coding must be done in multiple steps.
a) Library installation: Before starting to code, the
following libraries must be installed.
b) Board installation: If you’re using Sanguino TSB for
the first time, you have to install the board by following this
user manual.
c) Fingerprint enrollment: To enrol fingerprints, upload
the following code to Sanguino TSB
#include
<Adafruit_Fingerprint.h>
uint8_t id;
unsigned char studentname[50];
int i=0;
Adafruit_Fingerprint
finger = Adafruit_Fingerprint(&Serial1);
void setup()
{
Serial.begin(9600);
Serial.println("fingertest");
// set the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found
fingerprint sensor!");
}
else {
Serial.println("Did
not find fingerprint sensor :(");
while (1);
}
}
uint8_t readnumber(void)
{
uint8_t num =
0;
while (num == 0) {
while (! Serial.available());
num =
Serial.parseInt();
}
return num;
}
void loop()
//
run over and over again
{
Serial.println("Type
in the ID # you want to save this finger as...");
// int id = 0;
// while (true) {
// while (! Serial.available());
// char c = Serial.read();
// if (! isdigit(c)) break;
// id *= 10;
// id += c - '0';
//
// if (id == 0) {// ID #0 not allowed, try
again!
// return;
// }
// }
id =
readnumber();
if (id == 0) {// ID #0 not allowed, try again!
return;
}
Serial.print("Enrolling
ID #");
Serial.println(id);
while (!
getFingerprintEnroll(id) );
}
uint8_t getFingerprintEnroll(int id)
{
int p =
-1;
Serial.println("Waiting
for valid finger to enroll");
while (p != FINGERPRINT_OK) {
p =
finger.getImage();
switch (p)
{
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.println(".");
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(1);
switch (p)
{
case FINGERPRINT_OK:
Serial.println("Image converted");
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;
}
Serial.println("Remove
finger");
delay(2000);
p =
0;
while (p != FINGERPRINT_NOFINGER) {
p =
finger.getImage();
}
p =
-1;
Serial.println("Place
same finger again");
while (p != FINGERPRINT_OK) {
p =
finger.getImage();
switch (p)
{
case FINGERPRINT_OK:
Serial.println("Image taken");
break;
case FINGERPRINT_NOFINGER:
Serial.print(".");
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");
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!
p =
finger.createModel();
if (p == FINGERPRINT_OK)
{
Serial.println("Prints
matched!");
}
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!");
}
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;
}
}
#include <PCF8563.h>
PCF8563 pcf;
void setup() {
Serial.begin(9600);
pcf.init();//initialize the clock
pcf.stopClock();//stop the clock
//set time to to 31/3/2018 17:33:0
pcf.setYear(18);//set year
pcf.setMonth(10);//set month
pcf.setDay(28);//set dat
pcf.setHour(13);//set hour
pcf.setMinut(13);//set minut
pcf.setSecond(0);//set second
pcf.startClock();//start the clock
}
void loop() {
}
Main code: Upload the following code to Sanguino TSB. Your project
will be ready.
/***************************************************
This is an example sketch for our
optical Fingerprint sensor
Designed specifically to work with the
Adafruit BMP085 Breakout
----> http://www.adafruit.com/products/751
****************************************************/
#include <SPI.h>
#include <SD.h>
#include <PCF8563.h>
#include <LiquidCrystal_SR.h>
#include <Adafruit_Fingerprint.h>
LiquidCrystal_SR lcd(12, 13, 3);
//
DATA CLOCK LATCH
//SH_CP->CLOCK->13
//ST_CP->LATCH->3
//DS->DATA->12
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&Serial1);
const int pinCS = 4;
int count1=0,count2=0,count3=0;
File myFile;
PCF8563 pcf;
void setup()
{
lcd.begin(16, 2);
lcd.clear(); //
clear the screen
Serial.begin(9600);
pcf.init();//initialize
the clock
pinMode(pinCS, OUTPUT);
if (SD.begin(4))
{
Serial.println("fingerprint
sensor.");
Serial.println("SD
card is ready to use.");
} else
{
Serial.println("SD
card initialization failed");
return;
}
while (!Serial); // For
Yun/Leo/Micro/Zero/...
delay(100);
Serial.println("\n\nAdafruit
finger detect test");
// set
the data rate for the sensor serial port
finger.begin(57600);
if (finger.verifyPassword()) {
Serial.println("Found
fingerprint sensor!");
} else {
Serial.println("Did
not find fingerprint sensor :(");
while (1) { delay(1); }
}
finger.getTemplateCount();
Serial.print("Sensor
contains "); Serial.print(finger.templateCount); Serial.println("
templates");
Serial.println("Waiting
for valid finger...");
lcd.setCursor(0, 0); // put
cursor at colon 0 and row 0
lcd.print("Press
finger");
}
void loop()
// run
over and over again
{
getFingerprintIDez();
delay(50);
//don't
ned to run this at full speed.
}
uint8_t 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 p;
case FINGERPRINT_PACKETRECIEVEERR:
Serial.println("Communication
error");
return p;
case FINGERPRINT_IMAGEFAIL:
Serial.println("Imaging
error");
return p;
default:
Serial.println("Unknown
error");
return p;
}
// OK
success!
p = finger.image2Tz();
switch (p) {
case FINGERPRINT_OK:
Serial.println("Image
converted");
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!
p = finger.fingerFastSearch();
if (p == FINGERPRINT_OK) {
Serial.println("Found
a print match!");
} else if (p == FINGERPRINT_PACKETRECIEVEERR) {
Serial.println("Communication
error");
return p;
} else if (p == FINGERPRINT_NOTFOUND) {
Serial.println("Did
not find a match");
return p;
} else {
Serial.println("Unknown
error");
return p;
}
//
found a match!
Serial.print("Found
ID #"); Serial.print(finger.fingerID);
Serial.print("
with confidence of"); Serial.println(finger.confidence);
return finger.fingerID;
}
//
returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) return -1;
//
found a match!
Serial.print("\r");
delay(500);
Serial.print("AT+CMGF=1\r");
delay(500);
if(finger.fingerID==1)
{
count1++;
Serial.print("AT+CMGS=\"+8801---------\"\r"); //Number
to which you want to send the sms
delay(250);
if(count1%2==0)
{
Serial.print("Roll#1
has left class\r"); //The text of the message to be sent
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Goodbye
Roll #");
lcd.print(finger.fingerID);
delay(2000);
lcd.clear(); //
clear the screen
lcd.print("Press
finger");
}
else
{
Serial.print("Roll#1
has reached class \r");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Welcome
roll #");
lcd.print(finger.fingerID);
delay(2000);
lcd.clear(); //
clear the screen
lcd.print("Press
finger");
}
delay(250);
Serial.write(0x1A);
myFile = SD.open("finger.txt", FILE_WRITE);
if(count1%2==0)
{
myFile.print("Roll#1
left class at\r");
}
else
{
myFile.print("Roll#1
entered at\r");
}
myFile.print("
");
Time nowTime = pcf.getTime();//get
current time
myFile.print(nowTime.day);
myFile.print("/");
myFile.print(nowTime.month);
myFile.print("/");
myFile.print(nowTime.year);
myFile.print("
");
myFile.print(nowTime.hour);
myFile.print(":");
myFile.print(nowTime.minute);
myFile.print(":");
myFile.println(nowTime.second);
myFile.println();
myFile.close();
//myFile.println();
}
else if(finger.fingerID==2)
{
//similar
to if(finger.fingerID==1), just change the mobile number and use the cariable
count2
}
else if(finger.fingerID==3)
{
//similar
to if(finger.fingerID==1), just change the mobile number and use the cariable
count3. Similar loops can be written for total 152 fingerprints.
}
Serial.print("Found
ID #"); Serial.print(finger.fingerID);
Serial.print("
with confidence of "); Serial.println(finger.confidence);
return finger.fingerID;
}
Attention: SIM 900A should be
disconnected from the circuit at the time of uploading codes.
At the time
of entering the class, students will give their fingerprints. If the given
fingerprint matches with the enrolled fingerprint, a welcome message with the
roll number of the student will appear on the LCD. His/her parent will receive
an SMS immediately which confirms his/her arrival at the school.
Similarly, at
the time of leaving the class, when a fingerprint matches, a goodbye message
will appear on the LCD screen. The parent will receive an SMS and be
notified.
A file named
finger.txt will be created in the microSD card. The times of entry and exit
will be recorded. From this file, the school authority will get information
regarding students’ attendance.












