haarislabs
Published © GPL3+

NFC-Based Employee Time Logging System

NFC-based smart employee in/out management system which keeps track of your employees working hours and logs this data to Google sheets.

IntermediateFull instructions provided3,633
NFC-Based Employee Time Logging System

Story

Read more

Schematics

circuit

Code

nfc_esp.ino

C/C++
#include <ESP8266WiFi.h>
#include <time.h>
#include <Wire.h>

const char WEBSITE[] = "api.pushingbox.com"; //pushingbox API server
const String devid = "enter your device id"; //device ID from Pushingbox

const char* ssid = "enter-your-wifi";
const char* password = "enter-your-password";
String spent_time, compare;

uint8_t year, month, day, hour, minute, sec;

#define UTC_OFFSET +5.5

#define NTP_SERVERS "0.in.pool.ntp.org", "3.asia.pool.ntp.org", "2.asia.pool.ntp.org"

void setup() {
  Wire.begin();
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("\nConnecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(1000);
  }

  configTime(UTC_OFFSET * 3600, 0, NTP_SERVERS);


  Serial.println("\nWaiting for time");
  while (!time(nullptr)) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("");
}

void loop() {
  time_t now = time(nullptr) + 1800; // adding 1800 because there is an offset of 30mins
  struct tm* brokentime = localtime(&now);  // Using the pre-defined struture format to break-out time

  year = brokentime->tm_year;
  month = brokentime->tm_mon;
  day = brokentime->tm_mday;
  hour = brokentime->tm_hour;
  minute = brokentime->tm_min;
  sec = brokentime->tm_sec;

  Wire.beginTransmission(8);

  Wire.write(year);
  Wire.write(month);
  Wire.write(day);
  Wire.write(hour);
  Wire.write(minute);
  Wire.write(sec);

  Wire.endTransmission();

  Serial.println(ctime(&now));
  delay(1000);



  compare = spent_time;
  Wire.requestFrom(8, 8);   // request 1 byte from slave device with address #8
  while (Wire.available()) { // slave may send less than requested
    spent_time = Wire.readString(); // receive a byte as int

    Serial.println(spent_time);         // print the character
  }

  if (spent_time!=compare) {
  WiFiClient client;  //Instantiate WiFi object

  //Start or API service using our WiFi Client through PushingBox
  if (client.connect(WEBSITE, 80))
    {
      client.print("GET /pushingbox?devid=" + devid
                   + "&timeData=" + spent_time);

      client.println(" HTTP/1.1");
      client.print("Host: ");
      client.println(WEBSITE);
      client.println("User-Agent: ESP8266/1.0");
      client.println("Connection: close");
      client.println();
    }
  }
}

Atmega

C/C++
/**************************************************************************/
/*!
    @file     iso14443a_uid.pde
    @author   Adafruit Industries
  @license  BSD (see license.txt)

    This example will attempt to connect to an ISO14443A
    card or tag and retrieve some basic information about it
    that can be used to determine what type of card it is.

    Note that you need the baud rate to be 115200 because we need to print
  out the data and read from the card at the same time!

  This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
  This library works with the Adafruit NFC breakout
  ----> https://www.adafruit.com/products/364

  Check out the links above for our tutorials and wiring diagrams
  These chips use SPI or I2C to communicate.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

Modified by Startoonlabs

*/
/**************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>
#include <Wire.h>
#include <TFT.h>
#include<time.h>


// For v0.1
#define cs   6
#define dc   17
#define rst  16

//For v0.0
//#define cs   6
//#define dc   9
//#define rst  7


TFT TFTscreen = TFT(cs, dc, rst);

uint8_t year, month, day, hour, minute, sec;

struct tm t;



struct employee {
  bool id_swipe;
  int count;
  float difference;
  struct tm in, out;
  time_t time_t_in, time_t_out, time_t_spent;
  String in_s, out_s, spent_s, spent_format,  in_s_format, out_s_format;
  char print_tft_timespent[30], print_tft_in[30], print_tft_out[30];

} emp1, emp2;



// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK  4
#define PN532_MISO 3
#define PN532_MOSI 2
#define PN532_SS   7



Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);


String uuid_temp, uuid_compare;
int var;



void setup(void) {
  TFTscreen.begin();
  TFTscreen.background(0, 0, 0);
  Serial.begin(115200);
  Serial.println("Hello!");
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent);

  nfc.begin();

  // Setting up initiale values of time.h variables

  memset(&t, 0, sizeof(struct tm));  //setting all the values to 0
  time_t time_t_in = time(NULL);
  time_t time_t_out = time(NULL);


  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    TFTscreen.stroke(255, 255, 255);
    TFTscreen.setTextSize(2);
    TFTscreen.text("Didn't find", 20, 40);
    TFTscreen.text("PN531 board", 20, 70);
    while (1); // halt

  }

  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

  // Set the max number of retry attempts to read from a card
  // This prevents us from waiting forever for a card, which is
  // the default behaviour of the PN532.
  nfc.setPassiveActivationRetries(0xFF);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A card");
}

void loop(void) {
  TFTscreen.background(0, 0, 0);
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.setTextSize(2);
  TFTscreen.text("Swipe your", 20, 40);
  TFTscreen.text("Card", 60, 70);



  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
  delay(1000);
  if (success) {
    Serial.println("Found a card!");
    //  Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    //  Serial.print("UID Value: ");

    for (uint8_t i = 0; i < uidLength; i++)
    { uuid_temp += uid[i];
      //Serial.print(" 0x");Serial.print(uid[i], HEX);
    }
    
    // For comparing the UID 
    
    uuid_compare = uuid_temp;
    uuid_temp = {"\0"};
    Serial.println(uuid_compare);
    var = uuid_compare.toInt();

    switch (var) {
      case 17313419489:
        Serial.println("Authorised person - Haaris");
        emp1.id_swipe = true;
        break;
      case 22208177172:
        Serial.println("Authorised person - Mohan");
        emp2.id_swipe = true;;
        break;
      default:
        Serial.println("UNAUTHOIRSED PERSON !!! LEAVE THE PREMESIS ASAP");
    }
  }
  else
  {
    // PN532 probably timed out waiting for a card
    Serial.println("Timed out waiting for a card");
  }

  // For emp1

  if (emp1.id_swipe == true) {
    if (emp1.count == 0) {
      Serial.println("Employee Entering");
      memset(&emp1.in, 0, sizeof(struct tm));
      emp1.in = t;
      TFTscreen.background(0, 0, 0);
      TFTscreen.stroke(255, 255, 255);
      TFTscreen.text("Emp Details:", 0, 3);
      TFTscreen.text("SLID01", 0, 40);
      TFTscreen.text("Emp. Entering", 0, 70);
      delay(3000);

    }
    else {
      Serial.println("Emp1 Leaving");
      memset(&emp1.out, 0, sizeof(struct tm));
      emp1.out = t;

      // To take the difference between IN time and OUT time 
      //we must convert the employee struct to time_t format
      
      emp1.time_t_in = mktime(&emp1.in);
      emp1.time_t_out = mktime(&emp1.out);
      emp1.difference = difftime(emp1.time_t_out, emp1.time_t_in);   //gives difference in seconds

      emp1.time_t_spent = time(NULL) + emp1.difference; //Adding the difference in seconds

      emp1.in_s = ctime(&emp1.time_t_in);                     // converting time_t type to string
      emp1.out_s = ctime(&emp1.time_t_out);
      emp1.spent_s = ctime(&emp1.time_t_spent);

      emp1.spent_format = emp1.spent_s.substring(11, 20);    // Getting only the time
      emp1.in_s_format = emp1.in_s.substring(11, 20);
      emp1.out_s_format = emp1.out_s.substring(11, 20);


      emp1.in_s_format.toCharArray(emp1.print_tft_in, 30);    // Converting to char such that if could be displayed on tft
      emp1.out_s_format.toCharArray(emp1.print_tft_out, 30);
      emp1.spent_format.toCharArray(emp1. print_tft_timespent, 30);


      Serial.println("IN TIME:");
      Serial.println(emp1.in_s);

      Serial.println("OUT TIME");
      Serial.println(emp1.out_s);

      Serial.println("TIME SPENT");
      Serial.println(emp1.spent_format);



      TFTscreen.background(0, 0, 0);
      TFTscreen.stroke(255, 255, 255);
      TFTscreen.text("Emp Details:", 0, 0);
      TFTscreen.text("SLID01 Leaving", 0, 30);
      TFTscreen.text("Time spent", 0, 60);
      TFTscreen.text(emp1.print_tft_timespent, 0, 90);
      delay(3000);
      TFTscreen.background(0, 0, 0);
      TFTscreen.stroke(255, 255, 255);
      TFTscreen.text("In Time:", 0, 0);
      TFTscreen.text(emp1.print_tft_in, 0, 30);
      TFTscreen.text("Out Time", 0, 60);
      TFTscreen.text(emp1.print_tft_out, 0, 90);
      delay(3000);


    }
    emp1.count ^= 1;
    emp1.id_swipe = false;
  }

  // For Employee 2 : addition details to be filled by the user for practice purposes.
  // For demonstration purpose it is left empty

  if (emp2.id_swipe == true) {
    if (emp2.count == 0) {
    }
    else {
    }
  }
}

void receiveEvent(int howMany) {

  year = Wire.read();
  month = Wire.read();
  day = Wire.read();
  hour = Wire.read();
  minute = Wire.read();
  sec = Wire.read();


  t.tm_year = 2018 - 1900;
  t.tm_mon = month - 1;
  t.tm_mday = day;
  t.tm_hour = hour;
  t.tm_min = minute;
  t.tm_sec = sec;

  // For debugging
  //time_t apple = mktime(&t);
  // Serial.println(ctime(&apple));

}

void requestEvent() {

  Wire.write(emp1.print_tft_timespent);
}

Esp

C/C++
No preview (download only).

Gscript

JavaScript
//-----------------------------------------------
//Originally published by Mogsdad@Stackoverflow
//Modified for jarkomdityaz.appspot.com
//Modified for Hackster.io by Stephen Borsay
//-----------------------------------------------
/*

GET request query:

https://script.google.com/macros/s/<gscript id>/exec?celData=data_here
----------------------------------------------------------------------

GScript, PushingBox and Arduino/ESP8266 Variables in order:

timeData
empidData
----------------------------------------------------
*/

/*Modified by Startoon-labs for application use */

/* Using spreadsheet API */

function doGet(e) { 
  Logger.log( JSON.stringify(e) );  // view parameters

  var result = 'Ok'; // assume success

  if (e.parameter == undefined) {
    result = 'No Parameters';
  }
  else {
    var id = '1rMnWzdaoPR0ght5dOa5iCqn_1IVjIQMgSfL8y4g-maw';//docs.google.com/spreadsheetURL/d
    var sheet = SpreadsheetApp.openById(id).getActiveSheet();
    var newRow = sheet.getLastRow() + 1;
    var rowData = [];
    //var waktu = new Date();
    rowData[0] = new Date(); // Timestamp in column A
    
    for (var param in e.parameter) {
      Logger.log('In for loop, param='+param);
      var value = stripQuotes(e.parameter[param]);
      //Logger.log(param + ':' + e.parameter[param]);
      switch (param) {
        case 'timeData': //Parameter
          rowData[1] = value; //Value in column B
          break;
        case 'empidData':
          rowData[2] = value;
          break;
        default:
          result = "unsupported parameter";
      }
    }
    Logger.log(JSON.stringify(rowData));

    // Write new row below
    var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
    newRange.setValues([rowData]);
  }

  // Return result of operation
  return ContentService.createTextOutput(result);
}

/**
* Remove leading and trailing single or double quotes
*/
function stripQuotes( value ) {
  return value.replace(/^["']|['"]$/g, "");
}

Credits

haarislabs

haarislabs

4 projects • 4 followers

Comments