I have been given a task to build an attendance system for staff. The requirements are quite straight-forward. It needs to be standalone (without computer), fingerprint is preferred, record real time and the record should be in SD card.
1.0 Introduction
There has been various kinds of attendance record system in the market, RFID-based, fingerprint scanning-based and barcode-based, etc. Talking about this attendance system, you may think that it is quite complex and hard to build it. However, after you read this article, you may change your perception. In this tutorial, we are going to demonstrate how to make a simple attendance system using Cytron current on-sale product including Arduino board, SM630 fingerprint module, Arduino Ethernet Shield and other devices such as LCD display shield and RTC (Real Time Clock).
1.1 Feature
The objective of this tutorial is to build an example of standalone attendance record system.
Below are the features of the system:
- built using Arduino Mega 2560 main board
- utilizes SM630 fingerprint module for fingerprint scanning purpose and extra storage.
- utilizes embedded microSD slot on Ethernet Shield to store attendance information which can be easily accessed by user.
- includes LCD Keypad shield that displays time and attendance information.It also contains 5 buttons (not including reset button) in which the user can use them as navigation buttons.
- includes RTC module to store real date and clock time information.
- includes other device such as buzzer as indicator.
2.0 Getting Started
2.1 Components
The components you need:
- 1 x Arduino Mega 2560 R3-Main Board
- 1 x Fingerprint Reader Integrated SM630
- 1 x LCD keypad Shield
- 1 x DS3231 RTC Module
- 1 x Ethernet Shield V2.0
- 1 x micro SD card, you can get it from any computer store.
- 1 x Cytron Prototyping Shield (for buzzer, UART and power system)
- 1 x 12V-2A DC adaptor
Electronic components:
Indicator:
- 1 x Buzzer-PCB Mount
Fingerprint module UART connection:
Power System:
- 1 x diode 1N5822
- 1 x 25V 220uF cap
- 1 x 25V 10uF cap
- 2 x 0.1uF cap
- 1 x LM7805 voltage regulator
- 1 x transistor TIP42C
- 1 x 3R3 resistor
- 1 x HL2527 DC Plug
- connecting wires
RTC Module System:
- 1 x Arduino Type Header pin
2.2 Basic Connection:
The system is built by stacking up the main board and shields as shown below.
Before stacking up, we need build a circuit consists of all necessary systems on prototyping shield.
2.21 Power System
Primary objective of this power system is to provides 5VDC to be used by Arduino board and other devices.
For your information, we have been experimenting the built-in power system but it turned out that current output is not enough for the current project. The use of LCD keypad shield and Ethernet shield consumes significant amount of current. The external power system is required to provide additional current.
User can use the sample power system circuit below. This power system can provide up to 8 Amps, and it shouldn’t be a problem to this project.The user can also make their own power system if it is appropriate.
Note**: JP2 ,F1 and S1 can be ignored.
In the circuit above, we only connect the 5V from Arduino board to the power system output. User can connect DC plug voltage output to on board Vin for other uses. Ethernet shield has an embedded 5V to 3V3 DC power system so for those users who want to use 3V3 applications don’t need to build another one.
2.22 Indicator
In this project, we add a buzzer in the system to indicate the completion of attendance record process. For example, one beep sound indicates login success and 2 beep sounds means logout. If there are 3 beep sounds, error occurs such as improper installation of microSD card, unfound employee fingerprint, etc.
In the circuit, user just needs to connect one leg (longer leg) of buzzer to 5V and another to GND.
User can customize their own indicator systems. User can even include some visual indicatiors like LEDs.
2.23 Fingerprint Module UART Connection
The figure below shows the connection between the connector and Arduino prototyping shield.
2.24 RTC module
User can either directly solder the module to prototyping shield or solder a 5 pin or 6 pin header on the shield for easy removal of the module like we did. This RTC module stores current time information with the power of a coin cell lithium battery.
Note**: Removal of the battery will instantly erase the information stored and reset the time. Handle with care!
We are going to use 4 pins only :VCC, SCL, SDA and GND. Leave others as not connected.
You can either use jumper wires to connect to the legs of female header pin, or solder 2 wires onto the board as SDA and SCL wires.
Connect the SDA wire to pin 20 and SCL to pin21. There should labels for you as guidance.
While inserting battery, make sure the side of battery with “+” sign attached to the surface of coin cell holder with “+” sign.
2.3 Hardware setup
For your information, Ethernet shield and LCD keypad shield share same pins at pin 4 and pin 10. We are going to do some modification to prevent pin crashes.
Modification 1: Bend the leg of prototyping shield at pin 4 and 10.
It should be something like photo below if you stack prototyping shield onto Ethernet shield.
Modification 2: Connect pin 4 on prototyping shield to pin A3. We are going to use pin A3 as D4 for LCD.
OKAY, now we can proceed to programming stage!
3.0 Programming
Below is the flow diagram sketch of the designed system. The full sketch can be downloaded here.
Basically the programming involves 4 major parts:
- fingerprint scanning process and teaching process
- information storing and accessing with fingerprint module and micro SD,
- time settings and display
- menu interface for time setup, fingerprint teaching ,etc.
i) FINGERPRINT SCANNING AND TEACHING
How does SM630 Fingerprint module work? It is using packet data communication. If we wants the module to carry out some operations, we need to send a string of bytes in serial to the device as command. After the device receives the data bytes, it will send back a string of bytes in serial as response. It is our job to do some programming to ‘write’ and ‘read’ these bytes to determine the outcome of the device.
Generally the communication packet includes the following:
- packet head – 2 bytes
- packet flag – 1 byte
- packet length – 1 byte
- packet content – N bytes
- checksum – 1 byte
Let say we want to add fingerprint at position(id) 2, what should we send?
- packet head : 0x4D and 0x58
- packet flag: 0x01 (command)
- packet length:adding operation requires 3 data bytes for packet content, thus here we should put 0x03
- packet content: 0x40 (command code as stated in user manual), 0x00(high byte of value 2), 0x02 (low byte of value 2)
- checksum : 0xFA (low byte of total sum from packet head to packet content data)
So we should send a string of data bytes {0x4D,0x58,0x01,0x03,0x40,0x00,0x02,0xFA} in serial to the fingerprint module.
This is just a brief explanation on the working principle of fingerprint module. To know more details on how to communicate with the module and execute other functions, user can refer to the SM630 Fingerprint Module User’s Manual.
Below is the sample code of sending command and receive response. This sample code is not optimized to full functionality. User can play around to add in more functions or modify the program for the best performance.
//define fingerprint command code
#define ADD_FINGERPRINT 0x40
#define DELETE_FINGERPRINT 0x42
#define SEARCH_FINGERPRINT 0x44
#define EMPTY_DATABASE 0x46
#define MATCHING 0x4B
//define fingerprint response code
#define OP_SUCCESS 0x31
#define TIME_OUT 0x33
#define PROCESS_FAILED 0x34
#define PARAMETER_ERR 0x35
#define MATCH 0x37
#define FP_FOUND 0x39
#define FP_UNFOUND 0x3A
Sending command
Program | Program description |
void _cmd(byte cmd,int number)
{
if(number>767)
{
msg("INVALID ID");
return;
}
Serial.begin(57600);
byte packet_content;
switch(cmd)
{
case SEARCH_FINGERPRINT:packet_content=5;break;
case EMPTY_DATABASE:packet_content = 1;break;
default: packet_content = 3;break;
}
byte Hbyte = number/256;
byte Lbyte = number%256;
byte checksum = 0;
byte send_cmd[packet_content+5];
for(byte i=0;i<sizeof(send_cmd);i++)
send_cmd[i]=0;
send_cmd[0] = 0x4D;
send_cmd[1] = 0x58;
send_cmd[2] = 0x10;
send_cmd[3] = packet_content;
send_cmd[4] = cmd;
for(byte i=0;i<sizeof(send_cmd);i++)
checksum+=send_cmd[i];
if(packet_content>=3)
{
send_cmd[5] = Hbyte;send_cmd[6] = Lbyte;
checksum+=send_cmd[5];
checksum+=send_cmd[6];
if(cmd==SEARCH_FINGERPRINT)
{
for(byte i=7;i>4;i--)
send_cmd[i+2]=send_cmd[i];
send_cmd[5] = 0;send_cmd[6] = 0;
checksum+=send_cmd[5];
checksum+=send_cmd[6];
}
}
send_cmd[packet_content+5-1]=checksum;
Serial.write(send_cmd,sizeof(send_cmd));
delay(1);
} |
|
Receiving response
Program | Program description |
boolean _respond(byte cmd)
{
boolean end_flag = false;
boolean success = false;
byte addfp_count = 0;
while(!end_flag)
{
int packet_length = 9;
byte resp_temp[packet_length];
for(byte j=0;j<packet_length;j++)
{
while(Serial.available()==0)
{
//you can add something here
}
resp_temp[j]=Serial.read();
if(j==3) packet_length = resp_temp[3]+5;
}
switch(resp_temp[5])
{
case OP_SUCCESS:
if(cmd==SEARCH_FINGERPRINT)
//add something here
else if(cmd==ADD_FINGERPRINT)
{
//add something here
addfp_count++;
}
else if(cmd==DELETE_FINGERPRINT)
{
//add something here
end_flag = true;
success = true;
}
else if(cmd==EMPTY_DATABASE)
{
//add something here
end_flag = true;
success = true;
}
break;
case TIME_OUT:
//add something here
end_flag=true;
break;
case PROCESS_FAILED:
//add something here
end_flag=true;
break;
case PARAMETER_ERR:
//add something here
end_flag=true;
break;
case MATCH:
//add something here
success = true;
end_flag=true;
break;
case NO_MATCH:
// add something here
end_flag=true;
break;
case FP_FOUND:
//add something here
worker_id = response[6]*256+response[7];
end_flag=true;
success = true;
break;
case FP_UNFOUND:
//add something here
end_flag=true;
break;
}
if(cmd==byte(ADD_FINGERPRINT)&&addfp_count>1)
{
//add something here
success = true;
end_flag=true;
}
}
Serial.end();
return success;
} |
|
Fingerprint Searching
These 2 functions allows user to carry out fingerprint searching and teaching process. If user wants to start searching process, user can write the following lines in the program.
_cmd (SEARCH_FINGERPRINT,100);
_respond(SEARCH_FINGERPRINT);
These lines send a command to the module to search for matching fingerprint designated from id 0 to 100 and gives appropriate response.
Fingerprint Teaching
For fingerprint teaching process like adding fingerprint, user may write the following codes
int id = 10;
_cmd (ADD_FINGERPRINT,id);
_respond(ADD_FINGERPRINT);
The codes above allows user to add fingerprint with id 10 if the response indicates the process is successful. You can check the response from _respond function. You can also write a program to select a value for int id so you can add fingerprint with any id number less than 768. You can utilise the navigation buttons on LCD keypad shield to do so.
The code for deleting fingerprint is almost similar to adding fingerprint:
int id = 10;
_cmd (DELETE_FINGERPRINT,id);
_respond(DELETE_FINGERPRINT);
The codes above allows user to delete fingerprint with id 10 if the process is successful.
ii) INFORMATION STORING AND ACCESSING
Write and read info using SM630 fingerprint module
SM630 fingerprint module has 64K bytes user flash memory to store necessary information. It can serve as extra storage if user knows how to utilise this function. Below are the sample codes on how to write strings data into fingerprint flash memory and read data from it.
Write/store strings to flash
Program | Program description |
void wrFlash(int id,int type,String data2wr)
{
Serial.begin(57600);
char data[data2wr.length()+1];
data2wr.toCharArray(data,data2wr.length()+1);
if(sizeof(data)>128) {msg("too big");return;}
byte wr_data[sizeof(data)+9];
byte checksum = 0;
byte i;
wr_data[0] = 0x4D;
wr_data[1] = 0x58;
wr_data[2] = 0x10;
wr_data[3] = 4 + sizeof(data);
wr_data[4] = 0x64;
wr_data[5] = ((id-1)*ADDR + type)/256;
wr_data[6] = ((id-1)*ADDR + type)%256;
wr_data[7] = sizeof(data);
for(i = 0;i<sizeof(data);i++) wr_data[i+8] = data[i];
for(i=0;i<(sizeof(wr_data)-1);i++) checksum+= wr_data[i];
wr_data[sizeof(wr_data)-1] = checksum;
Serial.write(wr_data,sizeof(wr_data));
delay(1);
char rx[6];
while(Serial.available()==0){}
Serial.readBytes(rx,6);
if(rx[3]==0x01&&rx[4]==0x02)
{
//do something here if receive packet error
return;
}
char ops_[7];
while(Serial.available()==0){}
Serial.readBytes(ops_,7);
if(ops_[5]!=OP_SUCCESS)
{
//do something here if storing data not successful
return;
}
Serial.end();
} |
|
Read data from flash
Program | Program description |
char* rdFlash(int id,int type,byte num)
{
Serial.begin(57600);
if(num>128) {msg("too big");return 0;}
byte rd_data[9];
byte checksum = 0;
byte i;
rd_data[0] = 0x4D;
rd_data[1] = 0x58;
rd_data[2] = 0x10;
rd_data[3] = 0x04;
rd_data[4] = 0x62;
rd_data[5] = ((id-1)*ADDR + type)/256;
rd_data[6] = ((id-1)*ADDR + type)%256;
rd_data[7] = num;
for(i=0;i<8;i++) checksum+= rd_data[i];
rd_data[8] = checksum;
Serial.write(rd_data,sizeof(rd_data));
delay(1);
char rx[6];
while(Serial.available()==0){}
Serial.readBytes(rx,6);
if(rx[3]==0x01&&rx[4]==0x02)
{
//do something here if receive packet error
return 0;
}
char ops_[6+num];
while(Serial.available()==0){}
Serial.readBytes(ops_,sizeof(ops_));
char dat[num];
for(i=0;i<num;i++) dat[i] = ops_[i+5];
Serial.end();
return dat;
} |
|
Write and read info using micro SD
There are a few things you have to do before you proceed.
First you have to make sure pin 4 and pin 10 from Ethernet Shield is not connected with the same pins of LCD Keypad Shield. If you haven’t modified and disconnected these pins, you may refer to the instructions shown in 2.3 Hardware Setup.
Second, please include the latest SD library in your Arduino library directory. The file can be found and downloaded at the end of this tutorial. In this tutorial we are using this library.
Below are the sample codes for accessing,writing and reading data from micro SD.
#include <SdFat.h>
#define chipSelect 4 //CS pin for microSD
Sd2Card card;
SdVolume vol;
SdFat sd;
Checking micro SD condition
Program | Program description |
boolean checkSDCard()
{
boolean SDCard_status = card.init(SPI_HALF_SPEED,chipSelect);
if (!SDCard_status||!vol.init(&card))
{
//do something here if card is not detected
}
uint32_t volumesize= vol.blocksPerCluster()*vol.clusterCount()*512;
uint32_t freespace = 512*vol.freeClusterCount()*vol.blocksPerCluster();
//check free space available
if(freespace==0)
//do something here if memory is full
else if(freespace<0.1*volumesize)
//do something here if memory is nearly full
return true;
} |
|
Write/Store data to microSD
This is the example on how we store employee’s login and logout information in our company. User may modify it to suit their application.
Program | Program description |
void record(String dataString)
{
// do something here to indicate recording/storing
char filename[fileName.length()+1];
fileName.toCharArray(filename,fileName.length()+1);
//checking card condition
if (!sd.begin(chipSelect, SPI_HALF_SPEED))
{
if(!checkSDCard())
{
// do something if card failed
}
}
boolean title=false;
if(!sd.exists(filename)) title = true;
// create or open file
SdFile dataFile;
if(title==true)
{
SdFile::dateTimeCallback(dateTime);
dataFile.open(filename,O_WRITE| O_CREAT| O_APPEND);
dataFile.println("Date,Time,Worker ID,Status,Remark,");
dataFile.close();
title = false;
}
else dataFile.open(filename, O_WRITE| O_APPEND);
// if the file isn't open, pop up an error:
if (!dataFile.isOpen())
{
// do something if file cannot be opened
}
else
{// if the file is available, write to it:
dataFile.println(dataString);
dataFile.close();
} |
|
Read file from microSD
Program | Program description |
void rdAdmin()
{
SdFile dataFile;
if (!sd.begin(chipSelect, SPI_HALF_SPEED))
{
if(!checkSDCard())
{
//do something here if card failed
}
}
if (!dataFile.open("admin.csv", O_READ))
{
//do something here if file not opened
}
char data;
String worker_data[5];
int count = 0;
boolean title_flag = true;
int line_count = 0;
while ((data = dataFile.read()) >= 0)
{
if(data!=','&&int(data)!=13&&int(data)!=10)
worker_data[count]+=String(data);
else if(data==',') count++;
else if(int(data)==13) //if read data jumps to next line
{
dataFile.read();
if(line_count>0)
{
wrFlash((worker_data[0].toInt()),ID,worker_data[0]);
wrFlash((worker_data[0].toInt()),NAME,worker_data[1]);
wrFlash((worker_data[0].toInt()),POS,worker_data[2]);
}
line_count++;
count = 0;
memset(worker_data,0,sizeof(worker_data));
}
}
dataFile.close();
} |
|
iii) TIME SETTINGS AND DISPLAY
Include the libraries below in your program. DS3231 RTC module is almost similar to DS1307 RTC and both chip are I2C devices and have the same working principle. Thus DS1307 library can be used for this project. Wire.h is for I2C configuration, LiquidCrystal.h is for LCD display and LCD_Key.h is for LCD Keypad button.
#include <Time.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#include <LCD_Key.h>
//define keycode
#define None 0
#define Select 1
#define Left 2
#define Up 3
#define Down 4
#define Right 5
LiquidCrystal lcd(8, 9, A3, 5, 6, 7);
LCD_Key keypad;
Setup - Sync the system time with RTC
void setup()
{
.....................//
lcd.begin(16,2);
Wire.begin();
setSyncProvider(RTC.get);
//....................
}
Remember to include setSyncProvider(RTC.get) in void setup() to synchronize the system time with RTC time. In this project, we are actually using the system time from Arduino to do time-critical application. Time.h library will handle this job for us and give us specific details about the time like year,month,day,week day, hour, minute and second. Without RTC sync, the system time will reset after the system is off even though we have set it to the right time.
Current Time Display
Program | Program description |
void Time_Display()
{
lcd.setCursor(0,1);
lcd.print(Wday[weekday()-1]);lcd.print(" ");
lcd.setCursor(0,0);
printDigits(day());
lcd.print("-");
printDigits(month());
lcd.print("-");
printDigits(year()%100);
lcd.setCursor(11,0);
printDigits(hourFormat12());
lcd.print(":");
printDigits(minute());
//lcd.print(":");lcd.print(second());
lcd.setCursor(14,1);
if(isAM()==1){
lcd.print("AM");
}
else{
lcd.print("PM");
}
}
void printDigits(int digits)
{
if(digits < 10)
lcd.print('0');
lcd.print(digits);
} |
time_t tim = now()+3600; //3600 seconds printDigits(hour(tim)); User will find that the display time will be 1 hour past the current time. |
Time Change Settings
Program | Program description |
void setup_Time()
{
byte lcd_hpos[7]={0,3,6,11,14,14};
byte lcd_vpos[7]={0,0,0,0,0,1};
int lcd_pos = 0;
int cur_time=millis();
int prev_time=millis();
boolean display_stat;
boolean time_update = 0;
int localKey;
Time_Display();
while(1)
{
int sec_update = second();
int min_update = minute();
int hour_update = hour();
int day_update = day();
int month_update = month();
int year_update = year();
localKey = keypad.getKey();
cur_time = millis();
if(cur_time-prev_time>400)
{
display_stat = !display_stat;
prev_time = cur_time;
}
if(display_stat==true)
{
lcd.setCursor(lcd_hpos[lcd_pos],lcd_vpos[lcd_pos]);
lcd.print(" ");
}
else
{
Time_Display();
}
if(localKey==Select)
{
if(time_update==true)
setTime(hour(),minute(),0,day(),month(),year());
RTC.set(now());
msg("UPDATING TIME");
}
else if(localKey==Left)
{
if(--lcd_pos<0) lcd_pos = 5;
delay(pb_delay);
}
else if(localKey==Right)
{
if(++lcd_pos>5) lcd_pos = 0;
delay(pb_delay);
}
else if(localKey==Up)
{
switch(lcd_pos)
{
case 0: day_update++; if(day_update>31) day_update=1;break;
case 1: month_update++; if(month_update>12) month_update =1;break;
case 2: year_update++; if(year_update>2100) year_update = 2013;break;
case 3: hour_update++;
if(isAM()==1){if(hour_update>11) hour_update =0;}
else if(isPM()==1){if(hour_update>23) hour_update =12;}
time_update = 1;break;
case 4: min_update++;if(min_update>59) min_update =0;
time_update = 1;break;
case 5: if(isAM()==1)hour_update+=12;else hour_update-=12;break;
}
setTime(hour_update,min_update,sec_update,day_update,
month_update,year_update);
Time_Display();
delay(pb_delay);
}
else if(localKey==Down)
{
switch(lcd_pos)
{
case 0: day_update--;if(day_update<1) day_update = 31;break;
case 1: month_update--;if(month_update<1) month_update = 12;break;
case 2: year_update--; if(year_update<2013) year_update = 2013;break;
case 3: hour_update--;
if(isAM()==1){if(hour_update<0) hour_update =11;}
else if(isPM()==1) {if(hour_update<12) hour_update =23;}
time_update = 1;break;
case 4: min_update--;if(min_update<0) min_update =59;time_update = 1;break;
case 5: if(isAM()==1) hour_update+=12; else hour_update-=12;break;
}
setTime(hour_update,min_update,second(),day_update,
month_update,year_update);
Time_Display();
delay(pb_delay);
}
}
} |
|
iv) MENU INTERFACE
In this project we also create a menu interface for fingerprint teaching process and time setup and it requires navigation buttons on LCD Keypad Shield.
Below is the sample code of a simple interface.
Program | Program description |
//global variables for admin menu and interface
byte choice[2];
byte page_no;
void admin()
{
int category = 0;
int page = 0;
int localKey;
selection(category,page);// display first page
while(1)
{
if(reset_)
{
category-=1;
page = choice[category];
selection(category,page);
reset_=false;
}
localKey = keypad.getKey();
switch(localKey)
{
case Left: page--;
if(page<0) page = 0;
else if(page>page_no-1) page = page_no-1;
selection(category,page);
delay(200);
break;
case Right: page++;
if(page<0) page = 0;
else if(page>page_no-1) page = page_no-1;
selection(category,page);
delay(200);
break;
case Select:
choice[++category] = page;
choice[category-1] = choice[category];
lcd.clear();
selection(category,page);
delay(200);
break;
case Up: category--;
if(category<0)
{
lcd.clear();
return;
}
else
page = choice[category];
lcd.clear();
selection(category,page);
delay(200);
break;
}
}
}
void selection(int category,int page){
switch(category)
{
case 0:
page_no = 5;//set pages for first category
menu(page);
break;
case 1:
if(choice[category]==0){delay(pb_delay);//add function here}
else if(choice[category]==1){delay(pb_delay);//add function here}
else if(choice[category]==2){delay(pb_delay);//add function here}
else if(choice[category]==3){delay(pb_delay);//add function here}
else if(choice[category]==4){delay(pb_delay);//add function here}
//user can add more function here
reset_ = true;
break;
}
}
void menu(int page){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Menu ");
lcd.print(page+1);lcd.print(":");
switch(page)
{
case 0: //customise first page// break;
case 1: //customise second page// break;
case 2: //customise third page// break;
case 3: //customise forth page// break;
case 4: //customise fifth page// break;
//user can add more here
}
} |
|
All the codes above are just part of the full source code and are taken as guidance for user to learn how the system works. In order for whole project to run, you can download sample full source code at the end of this tutorial.
4.0 Nearly finish...
After you have finished programming and everything else, just plug in DC adapter (to DC plug you soldered, not that from Arduino main board) and turn on the power.
If you are not sure whether the power system works, just use multimeter to measure the voltage at pin 5V. The voltage should be 5V.
If everything is on, you are not done yet. Fingerprint and RTC module are new and you need to do something. As for RTC module, you will find that the date shown on LCD display will be different from current time ( should be 01-01-00). All you need to to do is go to time setup (I believe you have made a way to reach that menu and it is advisable to remove any verification process first for easy setup) and set up your time. If you have done this before finishing this project, then just skip it.
Fingerprint module now is free of data (except for its own ID and logo). You can teach it to read and store fingerprints or any information you want to store in the module.
If you are interested, you can make a container for the system. Nicer look and more 'professional'! The container we are using is the unwanted power supply casing.
Now your attendance system is ready to serve!!!
5.0 Precautions
After you run the system for a while, you will find that the power system is quite warm. Don't worry too much about the heat, components can withstand it. But of course don't bake up the whole thing by putting it in warm place or in a small closed container. Getting the board too hot will probably damage the thing and resetting the system rapidly. Put the system in cool place or place with open air.
That's all! Hope you can enjoy it to develop your own attendance record system. There are so much more to learn and explore its possible potentials. Have fun! 8-)
Attachment:
- Attendance System
hye! im doing the same project for my class subject project.
i had set up the same things but not using buzzer and ethernet and RTC ds1307. can i use the same coding here? i have compiled but there are some errors
attsys:72: error: ‘Time_t’ was not declared in this scope
attsys:62: error: ‘LCD_Key’ does not name a type
attsys:67: error: ‘SdFat’ does not name a type
attsys:70: error: ‘LCD_Key’ does not name a type
attsys.ino: In function ‘void setup()’:
attsys:105: error: ‘RTC’ was not declared in this scope
attsys:105: error: ‘setSyncProvider’ was not declared in this scope
attsys:108: error: ‘now’ was not declared in this scope
attsys:111: error: ‘month’ was not declared in this scope
attsys:112: error: ‘year’ was not declared in this scope
attsys.ino: In function ‘void loop()’:
attsys:117: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘boolean _respond(byte)’:
attsys:210: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘void attendance()’:
attsys:430: error: ‘worker_stat’ was not declared in this scope
attsys:432: error: ‘now’ was not declared in this scope
attsys.ino: In function ‘void Time_Display()’:
attsys:448: error: ‘weekday’ was not declared in this scope
attsys:452: error: ‘day’ was not declared in this scope
attsys:454: error: ‘month’ was not declared in this scope
attsys:456: error: ‘year’ was not declared in this scope
attsys:460: error: ‘hourFormat12’ was not declared in this scope
attsys:462: error: ‘minute’ was not declared in this scope
attsys:467: error: ‘isAM’ was not declared in this scope
attsys.ino: In function ‘void setup_Time()’:
attsys:500: error: ‘second’ was not declared in this scope
attsys:501: error: ‘minute’ was not declared in this scope
attsys:502: error: ‘hour’ was not declared in this scope
attsys:503: error: ‘day’ was not declared in this scope
attsys:504: error: ‘month’ was not declared in this scope
attsys:505: error: ‘year’ was not declared in this scope
attsys:507: error: ‘keypad’ was not declared in this scope
attsys:528: error: ‘setTime’ was not declared in this scope
attsys:529: error: ‘RTC’ was not declared in this scope
attsys:529: error: ‘now’ was not declared in this scope
attsys:555: error: ‘isAM’ was not declared in this scope
attsys:556: error: ‘isPM’ was not declared in this scope
attsys:560: error: ‘isAM’ was not declared in this scope
attsys:563: error: ‘setTime’ was not declared in this scope
attsys:576: error: ‘isAM’ was not declared in this scope
attsys:577: error: ‘isPM’ was not declared in this scope
attsys:580: error: ‘isAM’ was not declared in this scope
attsys:583: error: ‘setTime’ was not declared in this scope
attsys.ino: At global scope:
attsys:591: error: redefinition of ‘String showTime’
attsys:72: error: ‘String showTime’ previously declared here
attsys:591: error: ‘Time_t’ was not declared in this scope
attsys.ino: In function ‘void record(String)’:
attsys:624: error: ‘sd’ was not declared in this scope
attsys:634: error: ‘sd’ was not declared in this scope
attsys:642: error: no matching function for call to ‘SdFile::open(char [(((unsigned int)((int)fileName.String::length())) + 1)], int)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:647: error: no matching function for call to ‘SdFile::open(char [(((unsigned int)((int)fileName.String::length())) + 1)], int)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:670: error: ‘worker_stat’ was not declared in this scope
attsys.ino: In function ‘void wr_log(boolean)’:
attsys:681: error: ‘sd’ was not declared in this scope
attsys:691: error: ‘sd’ was not declared in this scope
attsys:699: error: no matching function for call to ‘SdFile::open(const char [8], int)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:708: error: no matching function for call to ‘SdFile::open(const char [8], const uint8_t&)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:725: error: ‘class SdFile’ has no member named ‘fgets’
attsys:733: error: ‘now’ was not declared in this scope
attsys:738: error: ‘now’ was not declared in this scope
attsys.ino: In function ‘char* rd_log(boolean)’:
attsys:755: error: ‘sd’ was not declared in this scope
attsys:766: error: no matching function for call to ‘SdFile::open(const char [8], const uint8_t&)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:779: error: ‘class SdFile’ has no member named ‘fgets’
attsys.ino: In function ‘void rdAdmin()’:
attsys:799: error: ‘sd’ was not declared in this scope
attsys:808: error: no matching function for call to ‘SdFile::open(const char [10], const uint8_t&)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys:808: error: no matching function for call to ‘SdFile::open(const char [12], const uint8_t&)’
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:223: note: candidates are: uint8_t SdFile::open(SdFile*, uint16_t, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:224: note: uint8_t SdFile::open(SdFile*, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:331: note: uint8_t SdFile::open(SdFile&, const char*, uint8_t)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:335: note: uint8_t SdFile::open(SdFile&, const char*)
C:\Program Files (x86)\Arduino\libraries\SD/utility/SdFat.h:341: note: uint8_t SdFile::open(SdFile&, uint16_t, uint8_t)
attsys.ino: In function ‘boolean checkSDCard()’:
attsys:855: error: ‘class SdVolume’ has no member named ‘freeClusterCount’
attsys.ino: In function ‘void dateTime(uint16_t*, uint16_t*)’:
attsys:867: error: ‘year’ was not declared in this scope
attsys:867: error: ‘month’ was not declared in this scope
attsys:867: error: ‘day’ was not declared in this scope
attsys:869: error: ‘hour’ was not declared in this scope
attsys:869: error: ‘minute’ was not declared in this scope
attsys:869: error: ‘second’ was not declared in this scope
attsys.ino: In function ‘void admin()’:
attsys:893: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘void add_fprint()’:
attsys:992: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘void del_fprint()’:
attsys:1097: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘void empty_database()’:
attsys:1155: error: ‘keypad’ was not declared in this scope
attsys.ino: In function ‘boolean password_check()’:
attsys:1232: error: ‘keypad’ was not declared in this scope
can you help me? thanks!
how to retrieve the fingers IDs and it’s time to be used in other application on PC
i’m using arduino due and finger print module FPS_GT511C3,,can i use this code.what else i have to do?
Shall we complete same project and some modification in the code with AT89S51
Can someone help with these kindly???
Read flash
Write flash
download fingerprint template
upload fingerprint template
Give an example code for arduino!
I have a problem with LCD keypad,
The buttons/keypad is no respons.
I use LCD Keypad DFRobot type.
Pls advice.
Thnx
Hi Cytron,
I can’t reach to the “menu” interface,
when i press “Select” button, screen write “PLACE FINGER ON SCREEN” and then “ACCESS Denied”
Could you help to make a simple user manual for operate and reach admin interface in this device?
Kindly send to my email.
Thank you,
Hi Januar P,
Just comment the following line in void admin() to remove fingerprint verification and proceed.
if(!admin_fpcheck()) return;
This line can only works if you have added the fingerprint to the database with the name “admin”.
You can also try out the password security to enter admin menu instead of fingerprint verification with password_check function.
Thanks.
Hello Cytron,
Before buying this hardware/component here, I want to try running using simulation software. So my question is, what software should I use to construct the circuit and run the coding?
Hello Cytron,
What type of database is used and if it save to the sdcard, what application can it be view on?
Thanks.
Hi Cytron,
I’m doing a project with similar system as this one. Using the power system provided by this page, I noticed that my voltage regulator, LM7805 heating so hot to the degree that I cannot touch it. Is that normal?
Thanks.
i cant upload any of your coding.
Sketch uses 30,882 bytes (12%) of program storage space. Maximum is 253,952 bytes.
Global variables use 1,995 bytes (24%) of dynamic memory, leaving 6,197 bytes for local variables. Maximum is 8,192 bytes.
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer
this is what it says
please help me asap
how to make a log in and log out using biometric