RFID door lock with SD card data logging and real time clock

Hello,

I am trying to make a RFID door lock with the parallax RFID reader http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/rfid/List/0/SortField/4/ProductID/114/Default.aspx that will log which cards were swiped and when it was swiped onto a SD card. I was thinking I could either use the Adafruit SD card,http://www.adafruit.com/products/254#Learn and the adafruit real time clock http://www.adafruit.com/products/264

Or I could just use the Adafruit bundle of the two https://www.adafruit.com/product/1141 (The only reason I would use the two separate pieces as apposed to the bundle is so that I could use an Arduino mini later on)

My main concern is that a tutorial I found for the RFID card reader without the SD card and RTC has the baud rate as 2400, the bundle has a baud rate as 9600, and a baud rate of 57600 for the separate RTC. I don't know if that means if these components will work together or not. Any help would be appreciated. Thanks

Different devices usually cannot share a serial port even if they do have the same baud rate. You need to have a separate serial line going to each device. There are software serial libraries out there that would let you make more pins into serial lines. Additionally, many devices will operate at any common baud rate below their listed maximum, so its possible all of these devices might work at 2400, but still not on the same line.

If the RFID reader doesn't print anything to the serial monitor, then does it need to have a set baud rate, different lines, etc? So if I were to use the bundle shield which has a baud rate of 9600, and I didn't have the RFID reader print anything to the serial monitor, then will that work?

Actually the RFID reader uses serial protocol, the DS1307 RTC uses I2C and the SD card module uses SPI. So, they all use different pins and protocols. You've nothing top worry about.

That sounds good, but the example sketch for each piece has a serial.begin() in the setup, and each one has a different baud rate within it. So if they all work together, would would i put in there, and in the setup. Sorry, i'm not very good at this.

I’ve attempted to combine the code, this is the result

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
//Begin RFID
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // initialize the library with the numbers of the interface pins

#define TAG_LEN 12
char tag[12] = {'3', '6', '0', '0', '7', '8', '9', '9', '8', '7'}; //tag 1
char tag2[12] = {'3', '6', '0', '0', '7', '8', '9', 'B', 'B', '5'}; //tag 2
char code[12];
int bytesread = 0;

//Connections to be made:
int ledPin = 13; // Connect LED to pin 13
int rfidPin = 2; // RFID enable pin connected to digital pin 2
//Connect SOUT Pin to pin 0, does not need to be defined because 0 is the default RX pin
int val=0;

//end RFID

// A simple data logger for the Arduino analog pins

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define photocellPin 0           // analog 0
#define tempPin 1                // analog 1
#define BANDGAPREF 14            // special indicator that we want to measure the bandgap

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File myFile;;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

void setup(void)
{
  //begin RFID
  lcd.begin(16, 2); // set up the LCD's number of rows and columns
lcd.print("Initializing...");
delay (1000);
digitalWrite(rfidPin, LOW); // Activate the RFID reader
  //End RFID
  Serial.begin(9600);
  //RFID
  pinMode(rfidPin,OUTPUT);   // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
pinMode(ledPin,OUTPUT); // Set ledPin to output
//RFID
  Serial.println();
  
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
  
#if WAIT_TO_START
  Serial.println("Type any character to start");
  while (!Serial.available());
#endif //WAIT_TO_START

  // initialize the SD card
  Serial.print("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)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");
}

void loop()
{
  DateTime now;
  
 digitalWrite(ledPin,LOW); //LED off
digitalWrite(rfidPin, LOW); // Activate the RFID reader

digitalWrite(ledPin,LOW); //LED off
digitalWrite(rfidPin, LOW); // Activate the RFID reader
 lcd.clear(); //Clears LCD
 lcd.setCursor(0, 0);
 lcd.print("  Please Swipe");
 lcd.setCursor(0, 1);
 lcd.print("   Your Card");
  if(Serial.available() > 0) {	    // if data available from reader
    if((val = Serial.read()) == 10) {   // check for header
	bytesread = 0;
	while(bytesread<10) {		  // read 10 digit code
	  if( Serial.available() > 0) {
	    val = Serial.read();
	    if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
		break;			     // stop reading
	    }
	    code[bytesread] = val;	   // add the digit
	    bytesread++;			 // ready to read next digit
digitalWrite(rfidPin, HIGH); //Turns off RFID reader, THIS IS IMPORTANT so it doesn't double read the card
	  }
	}
if(bytesread >= 10) {		  // if 10 digit read is complete
 
	 if(strcmp(code, tag) == 0) {
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print(" Access Granted");
 lcd.setCursor(0, 1);
 lcd.println(code);
 delay (1500);
 lcd.setCursor(0, 1);
 lcd.print("Jonnyblanch  ");
         digitalWrite(ledPin,HIGH);
	   Serial.print("Tag matches: ");
	   Serial.println(code);
           //digitalWrite(ledPin,HIGH);
           digitalWrite(rfidPin, HIGH);
           // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("log.txt", FILE_WRITE);
 
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to log.txt...");
    myFile.println("Jonnyblanch -");
     // fetch the time
  now = RTC.now();
  // log time
  myFile.print(now.unixtime()); // seconds since 1/1/1970
  myFile.print(", ");
  myFile.print('"');
  myFile.print(now.year(), DEC);
  myFile.print("/");
  myFile.print(now.month(), DEC);
  myFile.print("/");
  myFile.print(now.day(), DEC);
  myFile.print(" ");
  myFile.print(now.hour(), DEC);
  myFile.print(":");
  myFile.print(now.minute(), DEC);
  myFile.print(":");
  myFile.print(now.second(), DEC);
  myFile.print('"');
  myFile.print('--');
	// close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening log.txt");
  }
            delay(2000);	     // wait for a second or two
           return;                   //Go to the top, skip the bottom
         }
    }
  }
}
}

the code is very long and confusing, at least for me it is. But this seems like a good place to start. Is anyone bold enough to read it? Or at least see if you think the components will work together?

If anyone is still willing, this is my improved code

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
//Begin RTC
    #include <Wire.h>
    #include "RTClib.h"
 
    RTC_DS1307 RTC;
//End RTC

//Begin RFID
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // initialize the library with the numbers of the interface pins

    #define TAG_LEN 12
    char tag[12] = {'3', '6', '0', '0', '7', '8', '9', '9', '8', '7'}; //tag 1
    char tag2[12] = {'3', '6', '0', '0', '7', '8', '9', 'B', 'B', '5'}; //tag 2
    char code[12];
    int bytesread = 0;
    //Connections to be made:
    int ledPin = 13; // Connect LED to pin 13
    int rfidPin = 2; // RFID enable pin connected to digital pin 2
    //Connect SOUT Pin to pin 0, does not need to be defined because 0 is the default RX pin
    int val=0;
//End RFID

//Begin SD
    #include <SD.h>
 
    File myFile;
//End SD


 
void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();
 
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // uncomment it & upload to set the time, date and start run the RTC!
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  pinMode(10, OUTPUT);
 
}
 
void loop () {
  DateTime now = RTC.now();
  //Begin RFID
  digitalWrite(ledPin,LOW); //LED off
digitalWrite(rfidPin, LOW); // Activate the RFID reader
 lcd.clear(); //Clears LCD
 lcd.setCursor(0, 0);
 lcd.print("  Please Swipe");
 lcd.setCursor(0, 1);
 lcd.print("   Your Card");
  if(Serial.available() > 0) {	    // if data available from reader
    if((val = Serial.read()) == 10) {   // check for header
	bytesread = 0;
	while(bytesread<10) {		  // read 10 digit code
	  if( Serial.available() > 0) {
	    val = Serial.read();
	    if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
		break;			     // stop reading
	    }
	    code[bytesread] = val;	   // add the digit
	    bytesread++;			 // ready to read next digit
digitalWrite(rfidPin, HIGH); //Turns off RFID reader, THIS IS IMPORTANT so it doesn't double read the card
	  }
	}
//End RFID

if(bytesread >= 10) {		  // if 10 digit read is complete
 
	 if(strcmp(code, tag) == 0) {
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print(" Access Granted");
 lcd.setCursor(0, 1);
 lcd.println(code);
 delay (1500);
 lcd.setCursor(0, 1);
 lcd.print("Jonnyblanch  ");
         digitalWrite(ledPin,HIGH);
	   Serial.print("Tag matches: ");
	   Serial.println(code);
           //digitalWrite(ledPin,HIGH);
           digitalWrite(rfidPin, HIGH);
           myFile = SD.open("log.txt", FILE_WRITE);
           // if the file opened okay, write to it:
            if (myFile) {
              Serial.print("Writing to log.txt...");
              myFile.print("Jonnyblanch");
              myFile.print(now.month(), DEC);
              myFile.print('/');
              myFile.print(now.day(), DEC);
              myFile.print(' ');
              myFile.print(now.hour(), DEC);
              myFile.print(':');
              myFile.print(now.minute(), DEC);
              myFile.print(':');
              myFile.print(now.second(), DEC);
              myFile.println();
          	// close the file:
              myFile.close();
            delay(2000);	     // wait for a second or two
           return;                   //Go to the top, skip the bottom
         }
      }  else {
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("Access Denied");
 lcd.setCursor(0, 1);
 lcd.println(code);
	   Serial.print(code);
	   Serial.println(" does not match");
           digitalWrite(rfidPin, HIGH);
        }
      }
  bytesread = 0;
	     delay(2000);	     // wait for a second
        digitalWrite(ledPin,LOW);    
    }
  }
}

I wouldn’t worry about the baud rates on the serial port. Each example sketch was using it to talk to the serial monitor on your PC, but they were using another method (I2C or SPI to talk to the other devices. For the most part these communications are hidden inside the libraries that you have.

As far as code improvements are concerned. Will it pass verification, and if so what parts of it don’t work the way you would like?

ColeH:
If anyone is still willing, this is my improved code

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

//Begin RTC
    #include <Wire.h>
    #include “RTClib.h”

RTC_DS1307 RTC;
//End RTC

//Begin RFID
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // initialize the library with the numbers of the interface pins

#define TAG_LEN 12
    char tag[12] = {‘3’, ‘6’, ‘0’, ‘0’, ‘7’, ‘8’, ‘9’, ‘9’, ‘8’, ‘7’}; //tag 1
    char tag2[12] = {‘3’, ‘6’, ‘0’, ‘0’, ‘7’, ‘8’, ‘9’, ‘B’, ‘B’, ‘5’}; //tag 2
    char code[12];
    int bytesread = 0;
    //Connections to be made:
    int ledPin = 13; // Connect LED to pin 13
    int rfidPin = 2; // RFID enable pin connected to digital pin 2
    //Connect SOUT Pin to pin 0, does not need to be defined because 0 is the default RX pin
    int val=0;
//End RFID

//Begin SD
    #include <SD.h>

File myFile;
//End SD

void setup () {
    Serial.begin(9600);
    Wire.begin();
    RTC.begin();

if (! RTC.isrunning()) {
    Serial.println(“RTC is NOT running!”);
    // following line sets the RTC to the date & time this sketch was compiled
    // uncomment it & upload to set the time, date and start run the RTC!
    //RTC.adjust(DateTime(DATE, TIME));
  }
  pinMode(10, OUTPUT);

}

void loop () {
  DateTime now = RTC.now();
  //Begin RFID
  digitalWrite(ledPin,LOW); //LED off
digitalWrite(rfidPin, LOW); // Activate the RFID reader
lcd.clear(); //Clears LCD
lcd.setCursor(0, 0);
lcd.print("  Please Swipe");
lcd.setCursor(0, 1);
lcd.print("  Your Card");
  if(Serial.available() > 0) {     // if data available from reader
    if((val = Serial.read()) == 10) {  // check for header
bytesread = 0;
while(bytesread<10) {   // read 10 digit code
  if( Serial.available() > 0) {
    val = Serial.read();
    if((val == 10)||(val == 13)) { // if header or stop bytes before the 10 digit reading
break;     // stop reading
    }
    code[bytesread] = val;   // add the digit
    bytesread++; // ready to read next digit
digitalWrite(rfidPin, HIGH); //Turns off RFID reader, THIS IS IMPORTANT so it doesn’t double read the card
  }
}
//End RFID

if(bytesread >= 10) {   // if 10 digit read is complete

 if(strcmp(code, tag) == 0) {

lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Granted");
lcd.setCursor(0, 1);
lcd.println(code);
delay (1500);
lcd.setCursor(0, 1);
lcd.print("Jonnyblanch  ");
        digitalWrite(ledPin,HIGH);
  Serial.print(“Tag matches: “);
  Serial.println(code);
          //digitalWrite(ledPin,HIGH);
          digitalWrite(rfidPin, HIGH);
          myFile = SD.open(“log.txt”, FILE_WRITE);
          // if the file opened okay, write to it:
            if (myFile) {
              Serial.print(“Writing to log.txt…”);
              myFile.print(“Jonnyblanch”);
              myFile.print(now.month(), DEC);
              myFile.print(’/’);
              myFile.print(now.day(), DEC);
              myFile.print(’ ‘);
              myFile.print(now.hour(), DEC);
              myFile.print(’:’);
              myFile.print(now.minute(), DEC);
              myFile.print(’:’);
              myFile.print(now.second(), DEC);
              myFile.println();
          // close the file:
              myFile.close();
            delay(2000);     // wait for a second or two
          return;                  //Go to the top, skip the bottom
        }
      }  else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(“Access Denied”);
lcd.setCursor(0, 1);
lcd.println(code);
  Serial.print(code);
  Serial.println(” does not match”);
          digitalWrite(rfidPin, HIGH);
        }
      }
  bytesread = 0;
    delay(2000);     // wait for a second
        digitalWrite(ledPin,LOW);   
    }
  }
}