You are on page 1of 15

GROUP ASSIGNMENT

SESSION 2022/2023-1

SEEE 3223

NAME : ABDULLAH BARK MOHAMED BIN BESHR A19EE4058

MOHAMMED SAFIR SAEED MOHAMMED A19EE4046

MAHMOUD MOHAMED IBRAHIM ATWA A19EE4047

MOHAMMED A.M. ABUJARAD A19EE4071

GROUP :

SECTION : 16

SUPERVISED BY : DR FAUZAN KHAIRI BIN CHE HARUN


1.0 Project Title

Fingerprint Based Biometric Attendance System using Atmega32 Microcontroller

2.0 OBJECTIVES

The main objective of this project is to develop a fingerprint-based biometric attendance system using an
Atmega32 micro-controller. This system will be able to accurately identify individuals based on their
fingerprints and track their attendance in real-time.

3.0 INTRODUCTION

The increasing demand for efficient and secure methods of tracking attendance has led to the
development of biometric-based systems. One such system is a fingerprint-based biometric attendance
system. This technology uses fingerprints as a means of identifying individuals for the purpose of
tracking attendance. The system typically includes a fingerprint sensor, a microcontroller, and software
for capturing and analyzing fingerprints, as well as storing and processing attendance data.

4.0 The System Specification


The fingerprint-based biometric attendance system works by capturing an individual's fingerprint using a
fingerprint sensor. The sensor uses a variety of technologies such as optical, capacitive, or thermal to capture the
image of the fingerprint. Once the image is captured, it is processed by the microcontroller (Atmega32) to extract
the unique features of the fingerprint, which are called minutiae. These minutiae are then compared with the
stored templates in the system's database to check for a match.

The system in this project utilizes a Fingerprint Sensor to authenticate individuals by capturing their fingerprints.
It includes four buttons that are used for different purposes such as registering new fingerprints, deleting existing
fingerprints, and navigating through the stored fingerprints. The button labeled "1" is used to add a new person to
the system, when the user wants to register a new fingerprint, they press this button and the LCD prompts them to
place their finger on the sensor twice and enter an employee ID. The button labeled "2" has two functions, when
adding new fingerprints, it allows the user to select which fingerprint they want to register by using buttons 3 and
4, and then confirms the selection by pressing button 1 again. This button also allows for the deletion of data from
the micro-controller's memory.
5.0 Components needed

Atmega32 (1) Fingerprint module(r305) (1) Push Button or membrane buttons ( 4 )

LEDs (2 ) 1K Resistor (2) 2.2K resistor ( 1 )

Power 12v adaptor (1) PCB or Breadboard (1) 16x2 LCD (1)

Connecting wires (1) BC547 Transistor (1) Burgs tips male female (1)

Buzzer (1) 1000uf, 10uf capacitor (1) DC JACK (optional) (1)

Servo motor (1)

6.0 Circuit Diagram

Servo motor

Figure 1: Circuit Design For The System


The circuit diagram shows that the push-button switches, are connected to specific pins on the
microcontroller:

 The Enroll button, labeled (key) "1", is connected to pin PA2.

 The Delete button, labeled (key) "2", is connected to pin PA3.

 The Up button, labeled (key) "3", is connected to pin PA0.

 The Down button, labeled (key) "4", is connected to pin PA1.

 A LED is connected to pin PC3 of the microcontroller through a 1k resistor.

 A Buzzer is connected to pin PC2 of the microcontroller through a 1k resistor.

 The Fingerprint module's Rx and Tx pins are directly connected to the serial pins PD0 and
PD1 of the microcontroller.

 The Servo motor is connected to pin PC1 of the microcontroller.

 The LCD The Servo motor is connected to pin PC1 of the microcontroller.

7.0 Pics of The System

Figure 2: Pics of The System

8.0 Video Explanation for Our System

https://drive.google.com/file/d/12ggFqY_quxHxNowjJJC5Vz-
EjiTg4jDq/view?usp=sharing
The Code

#define F_CPU 8000000ul


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>

#MACROS

#define USART_BAUDRATE 9600


#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#define uchar unsigned char


#define uint unsigned int

#define LCDPORTDIR DDRB


#define LCDPORT PORTB
#define rs 0
#define rw 1
#define en 2

#define RSLow (LCDPORT&=~(1<<rs))


#define RSHigh (LCDPORT|=(1<<rs))
#define RWLow (LCDPORT&=~(1<<rw))
#define ENLow (LCDPORT&=~(1<<en))
#define ENHigh (LCDPORT|=(1<<en))

#define KeyPORTdir DDRA


#define key PINA
#define KeyPORT PORTA

#define OK 3
#define UP 0
#define DOWN 1
#define DEL 3
#define MATCH 1
#define ENROL 2

#define enrol (key & (1<<ENROL)) // key 1


#define match (key & (1<<MATCH)) // key 4
#define delet (key & (1<<DEL)) // key 2
#define up (key & (1<<UP)) // key 3
#define down (key & (1<<DOWN)) // key 4
#define ok (key & (1<<OK)) // key 2

#define LEDdir DDRC


#define LEDPort PORTC

#define LED 3
#define BUZ 2
#define LOCK 4

#define LEDHigh (LEDPort += (1<<LED))


#define LEDLow (LEDPort &= ~(1<<LED))
#define BUZHigh (LEDPort += (1<<BUZ))
#define BUZLow (LEDPort &= ~(1<<BUZ))

#define LOCKHigh (LEDPort += (1<<LOCK))


#define LOCKLow (LEDPort &= ~(1<<LOCK))

#define HIGH 1
#define LOW 0

#define PASS 0
#define ERROR 1

#define check(id) id=up<down?++id:down<up?--id:id;

#define maxId 5
#define dataLenth 6
#define eepStartAdd 10

#Variable

uchar buf[20];
uchar buf1[20];
volatile uint ind;
volatile uint flag;
uint msCount = 0;
uint g_timerflag = 1;
volatile uint count = 0;
uchar data[10];
uint id = 1;
int s, a, b, c;

const char passPack[] = { 0xEF, 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0x7, 0x13, 0x0, 0x0, 0x0, 0x0,
0x0, 0x1B };
const char f_detect[] = { 0xEF, 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0x3, 0x1, 0x0, 0x5 };
const char f_imz2ch1[] = { 0xEF, 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0x4, 0x2, 0x1, 0x0, 0x8 };
const char f_imz2ch2[] = { 0xEF, 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0x4, 0x2, 0x2, 0x0, 0x9 };
const char f_createModel[] = { 0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x3,0x5,0x0,0x9 };
char f_storeModel[] = { 0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x6,0x6,0x1,0x0,0x1,0x0,0xE };
const char f_search[] = { 0xEF, 0x1, 0xFF, 0xFF, 0xFF, 0xFF, 0x1, 0x0, 0x8, 0x1B, 0x1, 0x0, 0x0, 0x0,
0xA3, 0x0, 0xC8 };
char f_delete[] = { 0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x7,0xC,0x0,0x0,0x0,0x1,0x0,0x15 };
//const char f_readNotepad[]={0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x4,0x19,0x0,0x0,0x1E};
//char f_writeNotepad[]={0xEF,0x1,0xFF,0xFF,0xFF,0xFF,0x1,0x0,0x24};

int timeStamp[7], day;

enum
{
CMD = 0,
DATA,
};
void buzzer(uint);

void lcdwrite(char ch, char r)


{ The code is written in C language and contains four
LCDPORT = ch & 0xF0; functions: lcdwrite(), lcdprint(), lcdbegin() and
RWLow; serialbegin().
if (r == 1)
RSHigh; 1.
else
lcdwrite(char ch, char r): This function writes a single
RSLow; character to the Liquid Crystal Display (LCD) screen. The
ENHigh; first argument ch is the character to be written and the
_delay_ms(5); second argument r determines if it is a command or data.
ENLow; The function starts by setting the high 4-bits of the
_delay_ms(10); character to the LCDPORT. The RW pin is set to low (i.e.
write mode). Then the RS pin is set high if the character is
LCDPORT = ch << 4 & 0xF0; data, or low if it is a command. Finally, the EN pin is set
RWLow; high to enable the LCD to receive the data, then low to
if (r == 1) end the transfer. The same process is repeated with the
RSHigh; low 4-bits of the character.
else 2.
RSLow; 3.
ENHigh; lcdprint(char* str): This function writes a string of
_delay_ms(5); characters to the LCD screen. It takes a pointer to the
ENLow; string as an argument. The function uses a loop to iterate
_delay_ms(10); over the characters in the string and passes each character
} to the lcdwrite() function.
4.
void lcdprint(char* str)
{ 5.
while (*str) lcdbegin(): This function initializes the LCD screen. It
{ sends a series of commands to the LCD to set the
configuration and clear the screen. The commands are
lcdwrite(*str++, DATA);
stored in an array lcdcmd. The function uses a for loop to
//__delay_ms(20);
iterate over the array and send each command to the
} lcdwrite() function.
}
6.
void lcdbegin() 7.
{ serialbegin(): This function initializes the serial
uchar lcdcmd[5] = { 0x02,0x28,0x0E,0x06,0x01 }; communication. It sets the baud rate and enables the
uint i = 0; receiver and transmitter. The sei() function is called to
for (i = 0; i < 5; i++) globally enable interrupts.
lcdwrite(lcdcmd[i], CMD); 8.
}

void serialbegin()
This is a function for writing a single byte of data to
{
a specified address in the EEPROM (Electrically
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); Erasable Programmable Read-Only Memory)
UBRRH = (BAUD_PRESCALE >> 8); memory of an AVR microcontroller. The function
UBRRL = BAUD_PRESCALE; starts by checking if the Write Enable bit (EEWE)
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); in the EEPROM Control Register (EECR) is set,
sei(); indicating that a write operation is already in
} progress. If it is set, the function waits until it is
cleared before proceeding. Next, the address to be
int eeprom_write(unsigned int add, unsigned char data) written to is stored in the EEPROM Address
{ Register (EEAR) and the data to be written is stored
while (EECR & (1 << EEWE)); in the EEPROM Data Register (EEDR).The
EEAR = add; function then sets the Master Write Enable bit
(EEMWE) in the EECR to initiate a write operation
EEDR = data;
EECR |= (1 << EEMWE); and sets the Write Enable bit (EEWE) to start the
EECR |= (1 << EEWE); actual writing process. Finally, the function
return 0; returns 0 to indicate that the write operation
} was successful.
This function eeprom_read(unsigned int add)
char eeprom_read(unsigned int add) reads a single byte of data from the EEPROM
{ (Electrically Erasable Programmable Read-Only
Memory) of the microcontroller.
while (EECR & (1 << EEWE));
EEAR = add;
EECR |= (1 << EERE); The function takes an argument add, which is the
return EEDR; address of the EEPROM location from where the
} data is to be read.

void saveData(int id) Before reading the data, the function checks if the
{ write operation is in progress by checking the
value of EECR (EEPROM Control Register) with
uint cIndex = eeprom_read(id);
a logical AND operation and the EEWE bit
if (cIndex == 0) (EEPROM Write Enable). If the write operation
cIndex = 1; is in progress, the function will wait until it is
uint cAddress = (cIndex * 6) + (id - 1) * 48; completed.

for (int i = 0; i < 6; i++) Next, the function sets the address of the
eeprom_write(cAddress + i, timeStamp[i]); EEPROM location to be read using the EEAR
eeprom_write(id, cIndex + 1); register. The EERE bit of the EECR register is
} set to start the EEPROM read operation.

int sendcmd2fp(char* pack, int len) Finally, the function returns the data stored at the
{ specified address, which is stored in the EEDR
int res = ERROR; register.
// serialFlush();
ind = 0;
_delay_ms(100);
for (int i = 0; i < len; i++) The given code is a C function that saves data to
{ EEPROM (electrically erasable programmable read-
// serialwrite(*(pack + i)); only memory) and sends a command to another
} device via a serial interface.
_delay_ms(1000);
if (flag == 1) The function saveData takes an id as an input and
{ reads the current index from the EEPROM using
/* lcdwrite(1,CMD); eeprom_read. It then calculates the address to write
lcdprint("flag = 1"); to by multiplying the index by 6 and adding it to the
_delay_ms(1000); base address calculated from the id. The function
then writes the current timeStamp to the calculated
for (int i = 0; i < 20; i++) { address and updates the index in the EEPROM using
lcdwrite(1,CMD); eeprom_write.
char te[20];
int temp = bcdtochar(buf[i]); The function sendcmd2fp takes a pointer to a buffer
sprintf(te, "%d", temp); pack and the length of the buffer as inputs. The
lcdprint(te); function first initializes the result as ERROR and
_delay_ms(5000); delays the execution by 100 ms. It then sends the
} contents of the pack buffer to the serial interface.
*/ After a delay of 1000 ms, the function checks the
if (buf[0] == 0xEF && buf[1] == 0x01) value of the flag variable. If flag is 1, the function
{ further checks the first two bytes of the buffer buf to
// lcdwrite(1,CMD); see if they match 0xEF and 0x01. If this check
passes, the function checks if the seventh byte of
// lcdprint("1st");
buf is 0x07, which indicates an acknowledgement
// _delay_ms(1000);
from the device. The function then checks the ninth
if (buf[6] == 0x07) // ack byte of buf to see if it is 0, indicating a successful
{ response from the device. If so, the function
// lcdwrite(1,CMD); calculates the length of the data and stores it in the
// lcdprint("2nd"); data buffer. The function returns PASS if the data
// _delay_ms(1000); was successfully received, or ERROR otherwise.
if (buf[9] == 0)
{
// lcdwrite(1,CMD);
// lcdprint("3rd");
// _delay_ms(1000);

uint data_len = buf[7];


data_len <<= 8;
data_len |= buf[8];
for (int i = 0; i < data_len; i++)
data[i] = 0;
//data=(char *)calloc(data_len, sizeof(data));
for (int i = 0; i < data_len - 2; i++)
{
data[i] = buf[10 + i];
} The getId function is used to read
res = PASS; the ID value from a user input
} interface. This function implements
a simple user interface loop that
else waits for user input and displays the
{ current value of the ID on an LCD
// lcdwrite(1,CMD); screen. The function starts by
// lcdprint("4th"); initializing the ID value to 0 and
// _delay_ms(1000); writing a command to the LCD to
set the cursor position to the first
res = ERROR; row of the screen. A while loop then
} waits for user input. In each
}
iteration of the loop, the current
}
value of the ID is displayed on the
// lcdwrite(1,CMD);
first row of the LCD screen. The
// lcdprint("5th");
function checks the state of the up
// _delay_ms(1000);
and down buttons to see if the user
ind = 0; wants to increment or decrement the
flag = 0; ID value. If the up button is pressed,
return res; the ID is incremented by 1. If the
} down button is pressed, the ID is
return res; decremented by 1. If the value of
} the ID is 0 and the user presses the
down button, the value of the ID
uint getId() remains unchanged. Once the user
{ presses the OK button, the function
uint id = 0; returns the current value of the ID
lcdwrite(1, CMD); as the result. Before returning the
while (1) ID, the function calls the buzzer
{ function with an argument of 200
lcdwrite(0x80, CMD); milliseconds to provide feedback to
(void)sprintf((char*)buf1, "Enter Id:%d ", id); the user. This indicates that the
lcdprint((char*)buf1); function has recognized the button
_delay_ms(200); press and is about to return the
result.Overall, the getId function
if (up == LOW) provides a simple user interface for
{ reading an ID value from a user
id++;
input interface, using an LCD
buzzer(200);
screen and buttons for input.
}
else if (down == LOW)
{
id--;
if (id == 0)
id = 0;
buzzer(200);
} The matchFinger function is a C language
else if (ok == LOW) implementation of a fingerprint matching
{ algorithm. It is intended to be used with a
buzzer(200); fingerprint sensor and an LCD screen. The
function performs several steps to match a
return id;
detected fingerprint with one stored in the
} system.
} Here are the detailed steps of the algorithm:
}
void matchFinger() 1. Check if a finger is detected: The function
starts by sending the command "f_detect" to
{ the fingerprint sensor to check if a finger is
if (!sendcmd2fp((char*)&f_detect[0], sizeof(f_detect))) present. If the command returns a failure, the
{ algorithm moves to the next step.
if (!sendcmd2fp((char*)&f_imz2ch1[0], sizeof(f_imz2ch1)))
{ 2. Convert the image of the finger to a
character file: If a finger is detected, the
if (!sendcmd2fp((char*)&f_search[0], sizeof(f_search))) function sends the command "f_imz2ch1" to
{ convert the image of the finger to a character
LEDHigh; file. This step is required because the
buzzer(200); fingerprint data is stored in a character file
format, and the sensor returns the image of
uint id = data[0];
the finger in a different format. If this step
id <<= 8; returns a failure, the algorithm moves to the
id += data[1]; next step.
uint score = data[2];
score <<= 8; 3. Search for a match: If the previous step is
successful, the function sends the command
score += data[3]; "f_search" to search for a match. The search
(void)sprintf((char*)buf1, "Id: %d", (int)id); is performed in the system's database of
lcdwrite(1, CMD); stored character files. If a match is found, the
lcdprint((char*)buf1); code retrieves the ID and score of the
lcdwrite(0xc0, CMD); matched fingerprint.
lcdprint("Welcome Home :)"); 4. Display the result and trigger the lock: If a
LOCKHigh; match is found, the code displays "Welcome
Home" on the LCD screen and turns on the
saveData(id); lock by setting the LOCKHigh flag. It also
stores the matched ID using the "saveData"
function. After a delay of 2 seconds, the code
_delay_ms(2000); displays "Entrance Registered" on the LCD
lcdwrite(1, CMD); screen and turns off the lock by setting
lcdprint("Entrance"); LOCKLow. The lock remains on for 1
lcdwrite(192, CMD); second and is then turned off.
lcdprint("Registered");
5. Display "Not Found" and trigger the
_delay_ms(1000); buzzer: If a match is not found, the code
LOCKLow; displays "Not Found" on the LCD screen and
_delay_ms(1000); sounds a buzzer four times.
LEDLow;
6. Display "No Finger": If no finger is
} detected, the code does not display anything
else on the LCD screen.
{
LEDHigh; This function implements a simple
lcdwrite(1, CMD); fingerprint matching algorithm that is
intended to be used as a basic example. It can
lcdprint("Not Found"); be modified and extended based on the
for(int i=0;i<4;i++) specific requirements of the application.
{
buzzer(500);
_delay_ms(100);
}
LEDLow;
}
}
else
{
LEDHigh;
lcdwrite(1, CMD);
lcdprint("Not Found");
buzzer(2000);
LEDLow;
}
}

else
{
//lcdprint("No Finger");
}
}
void enrolFinger()
{
lcdwrite(1, CMD);
lcdprint("Enroll Finger");
_delay_ms(2000);
lcdwrite(1, CMD);
lcdprint("Place Finger");
lcdwrite(192, CMD);
_delay_ms(1000);
for (int i = 0; i < 3; i++)
{
if (!sendcmd2fp((char*)&f_detect[0], sizeof(f_detect)))
{
if (!sendcmd2fp((char*)&f_imz2ch1[0], sizeof(f_imz2ch1)))
{
lcdwrite(192, CMD);
lcdprint("Finger Detected");
_delay_ms(1000);
lcdwrite(1, CMD);
lcdprint("Place Finger");
lcdwrite(192, CMD);
lcdprint(" Again ");
_delay_ms(2000);
if (!sendcmd2fp((char*)&f_detect[0], sizeof(f_detect)))
{
if (!sendcmd2fp((char*)&f_imz2ch2[0], sizeof(f_imz2ch2)))
{
lcdwrite(1, CMD);
lcdprint("Finger Detected");
_delay_ms(1000);
if (!sendcmd2fp((char*)&f_createModel[0], sizeof(f_createModel)))
{
id = getId();
f_storeModel[11] = (id >> 8) & 0xff;
f_storeModel[12] = id & 0xff;
f_storeModel[14] = 14 + id;
if (!sendcmd2fp((char*)&f_storeModel[0], sizeof(f_storeModel)))
{
buzzer(200);
lcdwrite(1, CMD);
lcdprint("Finger Stored");
(void)sprintf((char*)buf1, "Id:%d", (int)id);
lcdwrite(192, CMD);
lcdprint((char*)buf1);
_delay_ms(1000);
}

else
{
lcdwrite(1, CMD);
lcdprint("Finger Not Stored");
buzzer(3000);
}
}
else The "deleteFinger()" function is a piece of code that is used to delete
lcdprint("Error"); a specific fingerprint from a fingerprint sensor. The function follows
these steps to delete the fingerprint:
}
else
lcdprint("Error"); 1. Retrieve the ID of the fingerprint to be deleted: The function calls
the "getId()" function to retrieve the ID of the fingerprint that needs
} to be deleted.
else 2. Populate the "f_delete" array with the delete command and the ID
i = 2; of the fingerprint to be deleted: The function updates the "f_delete"
} array with the command to delete a fingerprint, along with the ID of
the fingerprint that needs to be deleted. The ID of the fingerprint is
break; placed in the appropriate positions in the array, with the high-order
} byte stored in "f_delete[10]" and the low-order byte stored in
if (i == 2) "f_delete[11]".
{
lcdwrite(0xc0, CMD); 3. Send the "f_delete" array to the fingerprint sensor: The function
calls the "sendcmd2fp" function, passing the "f_delete" array and the
lcdprint("No Finger"); size of the array as arguments. The "sendcmd2fp" function sends the
} "f_delete" command to the fingerprint sensor to initiate the deletion
} process.
_delay_ms(2000);
} 4. Check the result of the deletion process: If the "sendcmd2fp"
function returns "0", indicating that the deletion was successful, the
function displays a message on the LCD screen indicating that the
void deleteFinger() fingerprint was deleted successfully. If the "sendcmd2fp" function
{ returns a non-zero value, indicating that there was an error during the
id = getId(); deletion process, the function displays an error message on the LCD
screen.
f_delete[10] = id >> 8 & 0xff;
f_delete[11] = id & 0xff; 5. Wait for 2 seconds: The function then waits for 2 seconds before
f_delete[14] = (21 + id) >> 8 & 0xff; returning control to the calling function. This allows the user to see
f_delete[15] = (21 + id) & 0xff; the result of the deletion process on the LCD screen before the
if (!sendcmd2fp(&f_delete[0], sizeof(f_delete))) function returns.
{ In summary, the "deleteFinger()" function is used to delete a specific
lcdwrite(1, CMD); fingerprint from a fingerprint sensor by sending the appropriate
sprintf((char*)buf1, "Finger ID %d ", id); command to the sensor and checking the result of the deletion
lcdprint((char*)buf1); process.
lcdwrite(192, CMD); 窗体底端
lcdprint("Deleted Success");

}
else
{ The function lcdinst() is used to display the available options on the LCD
lcdwrite(1, CMD); screen of an embedded system. It is written in the C programming language
and is used to interact with the display component of the device.Here's a step-
lcdprint("Error"); by-step explanation of what the function does:The first line of the function sets
} the cursor position on the LCD display by writing to the command register of
_delay_ms(2000); the LCD. The value 0x80 is sent to the command register, which is the
} instruction to set the cursor position to the first line of the display.The next
line of the function calls the lcdprint() function and passes the string "1-
Enroll Finger" as an argument. The lcdprint() function is used to display
void lcdinst()
characters on the LCD screen. The string passed as an argument is displayed
{ on the first line of the LCD screen.In the next line, the cursor position is set to
lcdwrite(0x80, CMD); the second line of the LCD screen by writing 0xc0 to the command
lcdprint("1-Enroll Finger"); register.The following line calls the lcdprint() function and passes the string
lcdwrite(0xc0, CMD); "2-Delete Finger" as an argument. This string is displayed on the second line
lcdprint("2-Delete Finger"); of the LCD screen.Finally, the function waits for 10 milliseconds with the
_delay_ms(10) function. This delay allows the text to be displayed on the
_delay_ms(10); screen before moving on to other operations.In summary, the lcdinst()
} function is used to display two options "1-Enroll Finger" and "2-Delete
Finger" on the LCD screen of the embedded system. These two options
represent the two functions available to the user, enrolling a new fingerprint or
deleting an existing fingerprint.
This is a function in C language for controlling a buzzer.The function takes in a single
parameter "t", which is an unsigned integer type. This parameter determines the duration
for which the buzzer will be turned on. Within the function, the first line activates a macro
called "BUZHigh". Macros are a preprocessor feature in C language and are used to
replace a specific text in the code with a different text. In this case, the macro "BUZHigh"
is likely defined somewhere else in the code and is used to set a particular pin to a high
state, which turns the buzzer on.Next, there is a for loop that runs "t" times. The purpose
of this loop is to create a delay of "t" milliseconds. The loop uses the "_delay_ms"
function to create this delay. This function is likely from a library that provides a
void buzzer(uint t) convenient way to create a delay in milliseconds. Finally, the BUZLow macro is activated
{ to turn off the buzzer. Like the BUZHigh macro, the BUZLow macro is also likely
BUZHigh; defined somewhere else in the code and is used to set a particular pin to a low state, which
for (int i = 0; i < t; i++) turns the buzzer off. In summary, this function is used to turn on the buzzer for a duration
_delay_ms(1); specified by the "t" parameter and then turn it off. The BUZHigh and BUZLow macros
BUZLow; are used to control the state of the buzzer and the for loop with the "_delay_ms" function
} is used to create the delay.

/function to show attendance data on serial monitor using softserial pin PD7/
void ShowAttendance()
{ This code is written in C and contains two functions,
char buf[128]; ShowAttendance() and DeleteRecord().
lcdwrite(1, CMD);
lcdprint("Downloading....");
// SerialSoftPrintln("Attendance Record");
// SerialSoftPrintln(" ");
// SerialSoftPrintln("S.No ID1 ID2 Id3 ID4 ID5
");
//serialprintln("Attendance Record");
//serialprintln(" ");
//serialprintln("S.No ID1 ID2 Id3
ID4 ID5");
for (int cIndex = 1; cIndex <= 8; cIndex++)
{
sprintf((char*)buf, "%d "
"%d:%d:%d %d/%d/20%d "
"%d:%d:%d %d/%d/20%d "
"%d:%d:%d %d/%d/20%d "
"%d:%d:%d %d/%d/20%d "
"%d:%d:%d %d/%d/20%d ",
cIndex,
eeprom_read((cIndex * 6)), eeprom_read((cIndex * 6) + 1), eeprom_read((cIndex * 6) + 2),
eeprom_read((cIndex * 6) + 3),
eeprom_read((cIndex * 6) + 4), eeprom_read((cIndex * 6) + 5),
eeprom_read((cIndex * 6) + 48), eeprom_read((cIndex * 6) + 1 + 48), eeprom_read((cIndex *
6) + 2 + 48),
eeprom_read((cIndex * 6) + 3 + 48), eeprom_read((cIndex * 6) + 4 + 48),
eeprom_read((cIndex * 6) + 5 + 48),
eeprom_read((cIndex * 6) + 96), eeprom_read((cIndex * 6) + 1 + 96), eeprom_read((cIndex *
6) + 2 + 96),
eeprom_read((cIndex * 6) + 3 + 96), eeprom_read((cIndex * 6) + 4 + 96),
eeprom_read((cIndex * 6) + 5 + 96),
eeprom_read((cIndex * 6) + 144), eeprom_read((cIndex * 6) + 1 + 144), eeprom_read((cIndex
* 6) + 2 + 144),
eeprom_read((cIndex * 6) + 3 + 144), eeprom_read((cIndex * 6) + 4 + 144),
eeprom_read((cIndex * 6) + 5 + 144),
eeprom_read((cIndex * 6) + 192), eeprom_read((cIndex * 6) + 1 + 192), eeprom_read((cIndex
* 6) + 2 + 192),
eeprom_read((cIndex * 6) + 3 + 192), eeprom_read((cIndex * 6) + 4 + 192),
eeprom_read((cIndex * 6) + 5 + 192));
>> ShowAttendance() function downloads and displays
// SerialSoftPrintln(buf); attendance records of multiple people stored in EEPROM
//serialprintln(buf); memory. It first writes the text "Downloading...." to an LCD
} display. Then it iterates through 8 records (cIndex = 1 to 8),
lcdwrite(192, CMD); retrieves the attendance data from EEPROM memory, and
lcdprint("Done"); formats the data into a string buffer "buf". The formatted string is
_delay_ms(2000);
then printed to an LCD display. The function ends with writing
}
"Done" to the LCD display and delaying for 2 seconds.
void DeleteRecord()
This code is written in C and appears to be a function that deletes a
{
lcdwrite(1, CMD); record stored in an EEPROM memory by writing the value of 10 to
lcdprint("Please Wait..."); each of its 255 memory locations. It also displays "Please Wait..." and
for (int i = 0; i < 255; i++) "Record Deleted Successfully" messages on an LCD screen after
eeprom_write(i, 10); performing the delete operation. The function uses the "eeprom_write"
_delay_ms(2000); function to write to the EEPROM memory and "lcdwrite" and
lcdwrite(1, CMD); "lcdprint" functions to write and print messages to the LCD screen.
lcdprint("Record Deleted");
The "_delay_ms" function is used to create a delay of 2000
lcdwrite(192, CMD);
lcdprint("Successfully");
milliseconds after the record deletion and display of messages on the
_delay_ms(2000); LCD screen.
}

int main()
{
LEDdir = 0xFF;
LEDPort = 0x03;
KeyPORTdir = 0xF0;
KeyPORT = 0x0F;
LCDPORTDIR = 0xFF;
DDRD += 1 << 7;
PORTD += 1 << 7;
serialbegin(); This is a C++ code for a smart lock
// SerialSoftPrint("Circuit Digest"); system that uses AVR and FP (likely an
buzzer(1000); fingerprint sensor). The code does the
following:
lcdbegin();
lcdprint("Smart lock Systm");
lcdwrite(0xc0, CMD); 1. Initializes the LED, key, and LCD
lcdprint("Using AVR and FP"); ports.
_delay_ms(2000); 1.
2. Initializes serial communication and
lcdwrite(0x01, CMD);
the buzzer.
lcdprint(" X->Limit");
lcdwrite(0xc0, CMD);
lcdprint(" Team"); 3. Displays the name of the system on t
_delay_ms(2000); he LCD.

if (down == LOW) 4. Checks if the down button is pressed.


ShowAttendance(); If so, it calls the ShowAttendance()
function.
else if (delet == LOW)
DeleteRecord(); 5. Checks if the delete button is pressed.
If so, it calls the
ind = 0;
DeleteRecord() function.
while (sendcmd2fp((char*)&passPack[0], sizeof(passPack)))
{ 6. Tries to send a command to the FP.
lcdwrite(1, CMD); If it fails, it displays"FP Not Found"
lcdprint("FP Not Found"); on the LCD. If it succeeds,
_delay_ms(2000); it displays "FP Found".
ind = 0;
}

lcdwrite(1, CMD);
lcdprint("FP Found");
_delay_ms(1000);
lcdinst();
_delay_ms(2000);
lcdwrite(1, CMD);
// RTCTimeSet();
while (1)
{
// RTC();

matchFinger();

if (enrol == LOW)
{
buzzer(200);
enrolFinger();
_delay_ms(2000);
}

else if (delet == LOW)


{
buzzer(200);
getId();
deleteFinger();
_delay_ms(1000);
}
}
    return 0;
}

9.0 Conclusion

In conclusion, the fingerprint-based biometric attendance system is an efficient and secure method for
tracking attendance. It utilizes a fingerprint sensor and an Atmega32 microcontroller to capture and
process fingerprints, and has buttons for registering, deleting and navigating through stored fingerprints.
The system works by capturing the unique minutiae of a fingerprint and comparing it with stored
templates in the database to check for a match. This technology provides a convenient and accurate way
of identifying individuals and keeping track of attendance.

10. References

[1] GitHub - Avarjana/R30X: Llibrary for R30X fingerprint module compatible with Atmega32A

[2] Interfacing Servo Motor with Atmega32 Atmel AVR Microcontroller (electrosome.com)

[3] LCD16x2 Interfacing with AVR ATmega16/ATmega32 | AVR ATmega Contr.. (electronicwings.com)

[4] GPIO Ports and Registers in AVR ATmega16/ATmega32 | AVR ATmega Co.. (electronicwings.com)

You might also like