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.
{
lcdbegin(): This function initializes the LCD screen. It
while (*str) 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
communication. It sets the baud rate and enables the
uchar lcdcmd[5] = { 0x02,0x28,0x0E,0x06,0x01 };
receiver and transmitter. The sei() function is called to
uint i = 0;
globally enable interrupts.
for (i = 0; i < 5; i++)
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
EEDR = data; (EEMWE) in the EECR to initiate a write operation
EECR |= (1 << EEMWE); and sets the Write Enable bit (EEWE) to start
EECR |= (1 << EEWE); the actual writing process. Finally, the
return 0; function 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
while (EECR & (1 << EEWE)); Memory) of the microcontroller.
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
uint cIndex = eeprom_read(id); value of EECR (EEPROM Control Register) with
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
// lcdprint("1st"); passes, the function checks if the seventh byte of
// _delay_ms(1000); buf is 0x07, which indicates an acknowledgement
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
uint id = data[0]; format, and the sensor returns the image of
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
score += data[3]; successful, the function sends the command
"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
_delay_ms(2000); code displays "Entrance Registered" on the
lcdwrite(1, CMD); LCD 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
lcdprint("Not Found");
can 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
i = 2; 2. Populate the "f_delete" array with the delete command and the ID
} of the fingerprint to be deleted: The function updates the "f_delete"
break; 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
if (i == 2) 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
{ "f_delete[11]".
lcdwrite(0xc0, CMD);
lcdprint("No Finger"); 3. Send the "f_delete" array to the fingerprint sensor: The function
} calls the "sendcmd2fp" function, passing the "f_delete" array and the
size of the array as arguments. The "sendcmd2fp" function sends the
}
"f_delete" command to the fingerprint sensor to initiate the deletion
_delay_ms(2000); process.
}
4. Check the result of the deletion process: If the "sendcmd2fp"
void deleteFinger() function returns "0", indicating that the deletion was successful, the
function displays a message on the LCD screen indicating that the
{ fingerprint was deleted successfully. If the "sendcmd2fp" function
id = getId(); returns a non-zero value, indicating that there was an error during the
f_delete[10] = id >> 8 & 0xff; deletion process, the function displays an error message on the LCD
f_delete[11] = id & 0xff; screen.
f_delete[14] = (21 + id) >> 8 & 0xff;
5. Wait for 2 seconds: The function then waits for 2 seconds before
f_delete[15] = (21 + id) & 0xff; returning control to the calling function. This allows the user to see
if (!sendcmd2fp(&f_delete[0], sizeof(f_delete))) the result of the deletion process on the LCD screen before the
{ function returns.
lcdwrite(1, CMD);
sprintf((char*)buf1, "Finger ID %d ", id); In summary, the "deleteFinger()" function is used to delete a specific
fingerprint from a fingerprint sensor by sending the appropriate
lcdprint((char*)buf1); command to the sensor and checking the result of the deletion
lcdwrite(192, CMD); process.
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
_delay_ms(2000); register of 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-
void lcdinst() Enroll Finger" as an argument. The lcdprint() function is used to display
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
void buzzer(uint t)
provides a 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
BUZHigh; likely defined somewhere else in the code and is used to set a particular pin to a low state,
for (int i = 0; i < t; i++) which turns the buzzer off. In summary, this function is used to turn on the buzzer for a
_delay_ms(1); duration specified by the "t" parameter and then turn it off. The BUZHigh and BUZLow
BUZLow; macros 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.
lcdwrite(0x01, CMD);
2. Initializes serial communication and
lcdprint(" X->Limit");
the buzzer.
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