/*
SD card datalogger (RFID swipe-time logger)
Log data from UART RFID reader to an SD card using the SD library.
*/
#include <RX8025.h>
#include <Wire.h>
#include <SD.h>
#include <NewSoftSerial.h>
//Define the value of rfid start bit
#define stx 2
//Define the value of rfid end bit
#define etx 3
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 10;
//Dont forget to change the values in 'NewSoftSerial' below if you move the rfid rx and tx pins somewhere else
NewSoftSerial mySerial(2, 3);
int counter;
byte data[14];
byte hexBlock1,hexBlock2,hexBlock3,hexBlock4,hexBlock5;
byte hexCalculatedChecksum,hexChecksum;
void setup() {
pinMode(8,OUTPUT);//LED pin set to OUTPUT
Serial.begin(9600);
mySerial.begin(9600);
//To set the clock - uncomment two lines below
unsigned char RX8025_time[7]={0x00,0x35,0x00,0x00,0x11,0x05,0x11};//second, minute, hour, week, date, month, year, BCD format
RX8025.setRtcTime(RX8025_time);
//RTC
RX8025.init();
//Announce the script
Serial.println("RFID Logger V1.02");
//initializ sd card
Serial.println("Initializing SD Card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("SD Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("SD Card initialized.");
}
void loop() {
digitalWrite(8,LOW);//LED pin set to OUTPUT
//read the rfid tag if present
if (mySerial.available() > 0) {
data[counter] = mySerial.read();
counter++;
if(counter > 13) {
//we read the whole message, so reset counter
counter = 0;
//check if start of text and end of text is correct
if(data[0] == stx && data[13] == etx) {
digitalWrite(8,HIGH);//LED pin set to OUTPUT
Serial.println("Start of text and end of Tag St correctly received.");
Serial.print("ID: ");
//show ID
for(int x = 1; x < 11; x++) {
Serial.print(data[x], BYTE);
}
Serial.println("");
Serial.print("Checksum: ");
//show checksum
Serial.print(data[11], BYTE);
Serial.println(data[12], BYTE);
//Hex ID blocks. Two transmitted Bytes form one Hex ID block.
//Hex ID blocks: 6 2 | E 3 | 0 8 | 6 C | E D
//Transmitted Bytes: 36H 32H | 45H 33H | 30H 38H | 36H 43H | 45H 44H
hexBlock1 = AsciiCharToNum(data[1])*16 + AsciiCharToNum(data[2]);
hexBlock2 = AsciiCharToNum(data[3])*16 + AsciiCharToNum(data[4]);
hexBlock3 = AsciiCharToNum(data[5])*16 + AsciiCharToNum(data[6]);
hexBlock4 = AsciiCharToNum(data[7])*16 + AsciiCharToNum(data[8]);
hexBlock5 = AsciiCharToNum(data[9])*16 + AsciiCharToNum(data[10]);
//Transmitted checksum.
hexChecksum = AsciiCharToNum(data[11])*16 + AsciiCharToNum(data[12]);
//XOR algorithm to calculate checksum of ID blocks.
hexCalculatedChecksum = hexBlock1 ^ hexBlock2 ^ hexBlock3 ^ hexBlock4 ^ hexBlock5;
if ( hexCalculatedChecksum == hexChecksum )
{
Serial.println("Calculated checksum matched transmitted checksum.");
//going to write it all to sd now
Serial.println("Will try to write ID and checksum to datalog.txt on SD now.");
// open datalog.txt. 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("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
//Write the RFID Card ID
//***************I am sure I need to convert to ascii befor printing? is the byte already ascii?
//***************but will see if this works for now think will print hex?, same with the output to the serial monitor
dataFile.print("Card ID: ");
dataFile.print(data[1], BYTE);
dataFile.print(data[2], BYTE);
dataFile.print(data[3], BYTE);
dataFile.print(data[4], BYTE);
dataFile.print(data[5], BYTE);
dataFile.print(data[6], BYTE);
dataFile.print(data[7], BYTE);
dataFile.print(data[8], BYTE);
dataFile.print(data[9], BYTE);
dataFile.print(data[10], BYTE);
dataFile.print(", ");
//write RFID cards checksum
dataFile.print("Checksum: ");
dataFile.print(data[11], BYTE);
dataFile.print(data[12], BYTE);
dataFile.print(", ");
//Log the time from the rtc
int rtc_sec, rtc_min, rtc_hou, rtc_wee, rtc_dat, rtc_mon, rtc_yea;
delay(300); // There will be new values every 100ms
RX8025.getRtcTime(&rtc_sec, &rtc_min, &rtc_hou, &rtc_wee, &rtc_dat, &rtc_mon, &rtc_yea);
dataFile.print(rtc_dat,DEC);
dataFile.print("/");
dataFile.print(rtc_mon,DEC);
dataFile.print("/");
dataFile.print(rtc_yea,DEC);
dataFile.print(" ");
dataFile.print(rtc_wee,DEC);
dataFile.print(" ");
dataFile.print(rtc_hou,DEC);
dataFile.print(":");
dataFile.print(rtc_min,DEC);
dataFile.print(":");
dataFile.println(rtc_sec,DEC);
//close the sd file?
dataFile.close();
// print to the serial port for monitoring
monitorout();
//turn led off
digitalWrite(8,HIGH);//LED pin set to OUTPUT
mySerial.flush();
delay(1000);
}
// if the file isn't open, pop up an error:
else {
Serial.println("Error opening data file - datalog.txt");
return;
}
}
else {
Serial.println("Calculated checksum didn't match transmitted checksum. Corrupt data!");
Serial.println("Please scan again");
// don't do anything more:
return;
}
}
}
}
}
uint8_t AsciiCharToNum(byte data) {
//First substract 48 to convert the char representation
//of a number to an actual number.
data -= '0';
//If it is greater than 9, we have a Hex character A-F.
//Substract 7 to get the numeral representation.
if (data > 9)
data -= 7;
return data;
}
void rfiddata() {
}
void monitorout(){
Serial.print("Card Sc ");
Serial.print("Card ID: ");
Serial.print(data[1], BYTE);
Serial.print(data[2], BYTE);
Serial.print(data[3], BYTE);
Serial.print(data[4], BYTE);
Serial.print(data[5], BYTE);
Serial.print(data[6], BYTE);
Serial.print(data[7], BYTE);
Serial.print(data[8], BYTE);
Serial.print(data[9], BYTE);
Serial.print(data[10], BYTE);
Serial.print(", ");
//print cards checksum
Serial.print("Checksum: ");
Serial.print(data[11], BYTE);
Serial.print(data[12], BYTE);
Serial.print(", ");
// print time
int rtc_sec, rtc_min, rtc_hou, rtc_wee, rtc_dat, rtc_mon, rtc_yea;
delay(1000); // There will be new values every 100ms
RX8025.getRtcTime(&rtc_sec, &rtc_min, &rtc_hou, &rtc_wee, &rtc_dat, &rtc_mon, &rtc_yea);
Serial.print("Time:");
Serial.print(rtc_dat,DEC);
Serial.print("/");
Serial.print(rtc_mon,DEC);
Serial.print("/");
Serial.print(rtc_yea,DEC);
Serial.print(" ");
Serial.print(rtc_wee,DEC);
Serial.print(" ");
Serial.print(rtc_hou,DEC);
Serial.print(":");
Serial.print(rtc_min,DEC);
Serial.print(":");
Serial.println(rtc_sec,DEC);
Serial.println("Done!");
Serial.println(" ");
}