Professional Documents
Culture Documents
SESSION 2022/2023-1
SEEE 3223
GROUP :
SECTION : 16
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.
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
Power 12v adaptor (1) PCB or Breadboard (1) 16x2 LCD (1)
Connecting wires (1) BC547 Transistor (1) Burgs tips male female (1)
Servo motor
The Fingerprint module's Rx and Tx pins are directly connected to the serial pins PD0 and
PD1 of the microcontroller.
The LCD The Servo motor is connected to pin PC1 of the microcontroller.
https://drive.google.com/file/d/12ggFqY_quxHxNowjJJC5Vz-
EjiTg4jDq/view?usp=sharing
The Code
#MACROS
#define OK 3
#define UP 0
#define DOWN 1
#define DEL 3
#define MATCH 1
#define ENROL 2
#define LED 3
#define BUZ 2
#define LOCK 4
#define HIGH 1
#define LOW 0
#define PASS 0
#define ERROR 1
#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};
enum
{
CMD = 0,
DATA,
};
void buzzer(uint);
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);
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.
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);
}
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)