Marcazzan_M
Published © GPL3+

Attendance register

Are you sure that your boss pay you all your work?

IntermediateFull instructions provided3 hours959
Attendance register

Things used in this project

Story

Read more

Schematics

Schematic

pcb_sch

Code

code

Arduino
//RFID
#include <deprecated.h>
#include <MFRC522.h>
#include <MFRC522Extended.h>
#include <require_cpp11.h>

MFRC522 mfrc(8, 9); //Pin 9-> RST pin 8-> SDA (SS)
bool pr1 = 0;
bool pr2 = 0; //Variables to read the RFID tag



#include <EEPROM.h>
#define ADD_W1 0 //memory address for the first worker
#define ADD_W2 10 //memory address for the second worker

#include <SPI.h>
#include <SD.h>

const int chipSelect = 10; //Chip Select for micro SD



#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

//RTC
#include <RTClib.h>
#include <Wire.h>
DS1307 rtc;

#define BTN1 A0 //buttons
#define BTN2 A1 


//worker 1
bool W1 = 0; //First worker ( W1 ) 0=out 1=in
int hour_in_W1 = 0; //minutes from 00:00
int hour_out_W1 = 0; //minutes from 00:00
byte tag_W1[4] = {0xb9, 0x80, 0xc8, 0xb8}; //Tag first worker

//worker 2
bool W2 = 0; //Second worker ( W2 ) 0=out 1=in
int hour_in_W2 = 0; //minutes from 00:00
int hour_out_W2 = 0; //minutes from 00:00
byte tag_W2[4] = {0xd0, 0xf2, 0xad, 0x32}; //Tag second worker

//state of the system
int state = 0;


void setup() {
  Serial.begin(9600);
  pinMode(chipSelect, OUTPUT);
  pinMode(BTN1, INPUT);
  pinMode(BTN2, INPUT);

  //Serial.begin(9600);
  SPI.begin();
  mfrc.PCD_Init();

  //init I2C
  Wire.begin();

  rtc.begin();
  //init RTC with compilation's date and hour
  if (!rtc.isrunning()) {
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }

  lcd.begin(16, 2);

  //recovery of old state W1
  byte val = EEPROM.read(ADD_W1);
  lcd.print("init Stato");
  delay(1000);

  if (val > 0) {
    lcd.clear();
    W1 = 1;
    //hour_in
    val = EEPROM.read(1);
    hour_in_W1 = val << 8;
    val = 0;
    val = EEPROM.read(2);
    hour_in_W1 = hour_in_W1 | val;
  }
  else W1 = 0;

  //recovery of old state W2
  lcd.clear();
  val = EEPROM.read(ADD_W2);
  lcd.print("init Stato");
  delay(1000);

  if (val > 0) {
    lcd.clear();
    W2 = 1;
    //hour_in
    val = EEPROM.read(11);
    hour_in_W2 = val << 8;
    val = 0;
    val = EEPROM.read(12);
    hour_in_W2 = hour_in_W2 | val;
  }
  else W2 = 0;

  lcd.clear();
  lcd.print("Init SD...");
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    lcd.print("Fail");
    delay(1000);
    // don't do anything more
    return;
  }

  lcd.setCursor(0, 1);
  lcd.println("Done            ");
  delay(500);
  lcd.clear();

  //The system is ready!
}

void loop() {

  switch (state) {
    case 0:
      Home();
      break;
    case 3:
      W1Access();
      break;
    case 4:
      W2Access();
      break;
    default:
      Home();
      break;
  }
  delay(700);
  readKey();
  read_tag();
}

void readKey() {
  if (digitalRead(BTN1)) {
    delay(100);
    state=3;
    delay(500);
  }
  if(digitalRead(BTN2)){
    delay(100);
    state=4;
    delay(500);
  }
}


void read_tag(void) {
  if (mfrc.PICC_IsNewCardPresent()) {
    pr1 = 1;
  }

  if (mfrc.PICC_ReadCardSerial() && pr1 == 1) {
    pr2 = 1;
  }

  //if pr1 and pr2 are 1 then try to decode the tag
  if (pr1 == 1 && pr2 == 1) {
    int i;
    int count_W1 = 0;
    int count_W2 = 0;

    for (i = 0; i < mfrc.uid.size; i++) {
      byte b = mfrc.uid.uidByte[i];
      Serial.println(b,HEX);
      if (b == tag_W1[i]) {
        count_W1++;
      }
      if (b == tag_W2[i]) {
        count_W2++;
      }
    }
    //if is equal to .size -> all match ok
    if (count_W1 == mfrc.uid.size) state = 3;

    if (count_W2 == mfrc.uid.size) state = 4;
  }
  pr1 = 0;
  pr2 = 0;
  return;
}


void W1Access(void) {
  W1 = !W1; //new state
  EEPROM.write(ADD_W1, W1); //store the state

  String tmp = " ";
  tmp = tmp + readRTCHour(W1, 1) + " " + readRTCDate();

  lcd.clear();
  if (W1 == 0) {
    lcd.print("W1 out");
    tmp = tmp + " O"; //O-> out
    //worker 1 hour (minutes)
    int delta = hour_out_W1 - hour_in_W1;
    tmp = tmp + " " + String(delta);
  }
  else {
    EEPROM.write(1, highByte(hour_in_W1));
    delay(2);
    EEPROM.write(2, lowByte(hour_in_W1));
    delay(2);
    lcd.print("W1 in");
    tmp = tmp + " P"; //P-> present
  }

  //store on SD
  if (!saveM(tmp+" W1")) {
    lcd.clear();
    lcd.print("Err check SD");
    delay(5000);
  }

  lcd.setCursor(0, 1);
  tmp = "";
  tmp = "T: " + readRTCHour(3, 3); //Casual parameter so the function return only the date
  lcd.print(tmp);

  //Reset
  state = 0;
  delay(1000);
  return;
}

void W2Access(void) {
  W2 = !W2; //new state
  EEPROM.write(ADD_W2, W2); //store the state

  String tmp = " ";
  tmp = tmp + readRTCHour(W2, 2) + " " + readRTCDate();

  lcd.clear();
  if (W2 == 0) {
    lcd.print("W2 out");
    tmp = tmp + " O"; //O-> out
    //worker 2 hour (minutes)
    int delta = hour_out_W2 - hour_in_W2;
    tmp = tmp + " " + String(delta);
  }
  else {
    
    EEPROM.write(1, highByte(hour_in_W2));
    delay(2);
    EEPROM.write(2, lowByte(hour_in_W2));
    delay(2);
    lcd.print("W2 in");
    tmp = tmp + " P"; //P-> present
  }

  //store on SD
  if (!saveM(tmp+" W2")) {
    lcd.clear();
    lcd.print("Err check SD");
    delay(5000);
  }

  lcd.setCursor(0, 1);
  tmp = "";
  tmp = "T: " + readRTCHour(3, 3); //Casual parameter so the function return only the date
  lcd.print(tmp);

  //Reset
  state = 0;
  delay(1000);
  return;
}


void Home(void) {
  String tmp = "";
  lcd.clear();
  //read hour
  tmp = tmp + readRTCDate()+ +" "+ readRTCHour(3, 3);
  lcd.print(tmp);
  lcd.setCursor(0, 1);
  tmp = "";
  tmp = tmp + "W1:";
  if (W1 == 0)tmp = tmp + "O";
  else tmp = tmp + "P";
  tmp = tmp + " W2:";
  if (W2 == 0) tmp = tmp + "O";
  else tmp = tmp + "P";
  lcd.print(tmp);
  return;
}

//Read RTC Date
String readRTCDate(void) {
  DateTime now = rtc.now();
  String date = "";
  //formatting of date
  date = form(now.day()) + "/" + form(now.month()) + "/" + String(now.year());
  return date;
}

String readRTCHour(int e, int w) {
  DateTime now = rtc.now();
  String date = "";
  //formatting of hour
  date = form(now.hour()) + ":" + form(now.minute());

  //e=1 ingresso e=0 uscita
  if (e == 0) {
    if (w == 1)
      hour_out_W1 = now.minute() + now.hour() * 60;
    if (w == 2)
      hour_out_W2 = now.minute() + now.hour() * 60;
  }
  if (e == 1) {
    if (w == 1)
      hour_in_W1 = now.minute() + now.hour() * 60;
    if (w == 2)
      hour_in_W2 = now.minute() + now.hour() * 60;
  }
  return date;
}


//this function format the number n
String form(int n) {
  String tmp = "";
  if (n < 10) {
    tmp = "0" + String(n);
  }
  else tmp = String(n);
  return tmp;
}


//Store on SD
//This function give 1 if and only if everything go well
bool saveM(String data) {
  File dataFile = SD.open("acc.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(data);
    dataFile.close();
    return 1;
  }
  // if the file isn't open, pop up an error:
  else {
    return 0;
  }
}

Credits

Marcazzan_M
6 projects • 67 followers
I'm an Italian student, I'm studying electronic engineering. Sufficiently advanced technology is indistinguishable from magic.
Contact

Comments

Please log in or sign up to comment.