Skip to content

Project Code

steigeia edited this page Mar 17, 2017 · 2 revisions

Libraries

#include <AddicoreRFID.h>
#include <Wire.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

These are the required libraries for the project. More information about these libraries can be found on the Libraries page of the wiki here.

Important Constant Variables

//change this depending on the SS pin for the SD slot
const int chipSelectSD = 10;

//change this depending on the SS pin for the RFID Module
const int chipSelectRFID = 7;

//change this depending on the Reset pin for the RFID Module
const int resetRFID = 3;

//change this depending on the file you want to save data to on the SD card
const char* saveFile = "dl.txt";

The pin based values are dependent on the SD shield you are using and the wiring of your RFID Module. The 'saveFile' is just so you can decide what file the UNIDs and time stamps will be saved to.

Getting RFID UNID

stat = myRFID.AddicoreRFID_Request(PICC_REQIDL , str);//search area for cards
stat = myRFID.AddicoreRFID_Anticoll(str);//read selected card with anticollision detection

The first function call searches the antenna area and selects a card. The next function call reads the UNID of the selected card which is stored into the first 4 bytes of str. The fifth byte of str is used a checksum which should be the exclusive or of all 4 of the UNID bytes. The value that is returned and put into stats signifies that a card was found if it equals MI_OK which can be found it the header file of the AddicoreRFID library here.

Using the RFID UNID

if (stat == MI_OK)//if stat = MI_OK then a card has been succesfully read
{
  checksum = str[0] ^ str[1] ^ str[2] ^ str[3];//calculate checksum

  //print RFID UNID
  Serial.print(str[0]);
  Serial.print(" , ");
  Serial.print(str[1]);
  Serial.print(" , ");
  Serial.print(str[2]);
  Serial.print(" , ");
  Serial.println(str[3]);

  //print out calculated checksum (checksum) and recieved checksum (str[4])
  Serial.println(str[4]);
  Serial.println(checksum);

  //if checksums do not match cancel SD card save and return to start of loop
  Serial.println();
  if(str[4]!= checksum){
    Serial.println("checksums do not match");
    free(out);
    myRFID.AddicoreRFID_Halt();//puts card into hibernation to avoid filling up chip's buffer
    return;
  }

  sprintf(out, "%d,%d,%d,%d", str[0], str[1], str[2], str[3]);//compile char* to save the UNID to SD card

  saveMessage(out, (char*)saveFile);//save out to SD card with date and time to file savefile

  delay(2000);//wait 2 second before re-reading to avoid reading the same card twice accidentally
}

If stat equal MI_OK then a RFID card has been tapped and a UNID has been acquired. First the checksum is calculated by exclusive oring all 4 bytes of the UNID then everything is printed out through Serial. If the calculated checksum does not equal the recieved checksum, the 5th byte of str, then a communication error has occurred and loop() is returned so that a UNID with an error is not written to the SD card. If the checksums match then out becomes a string of the 4 UNID bytes separated by commas which is how I wanted the UNIDs to be stored on the SD card. The saveMesage() function is then called with the parameters out, which hold the UNID bytes, and saveFile, which holds the file name to be saved to'. A delay of 2 seconds occurs so that the user has time to remove the card before the system attempt to locate and get a new UNID to save. This prevents the system from rereading an RFID card multiple time when it is not desired.

Getting the Date and Time

char* date() {
  DateTime t_now = rtc.now();//retrieves the current date and time from the real time clock
  char* date = (char*)malloc(30 * sizeof(char));
  //compile the date and time into a usable string
  sprintf(date, "%d/%d/%d %d:%d:%d\n", t_now.month(), t_now.day(), t_now.year(), t_now.hour(), t_now.minute(), t_now.second());
  return date;
}

This function is used to get the current date and time from the Real Time Clock and return it in a string with the format month/day/year hour/minute/second.

Saving to SD

void saveMessage(char* str, char* fileName) {
  // make a string for assembling the data to log:
  char *dataString = (char*)malloc(50 * sizeof(char));
  char *dateTime = date();
  sprintf(dataString, "%s\t%s", str, dateTime);//16 + 11 + 8
  Serial.println(dataString);

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("dl.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
  }
  // if the file isn't open, pop up an error:
  // some times an error will not come up even if there actually is an error
  else {
    Serial.println("error");
  }

  free(dataString);
  free(dateTime);
}

The saveMessage function takes in str which should contain the data to be saved to the SD card with the date and fileName' which contains the name of the file to save to. First dataStringis set to the data fromstrfollowed by a tab and the date and time fromdate(). Then the SD library attempts to open the file specified by fileNameand, if successful, writedataString` to a new line. If the file opening is not successful, nothing is writen to the SD card and the function ends.

Clone this wiki locally