Go Down

Topic: RFID, SD card and real time clock door lock (Read 13953 times) previous topic - next topic

ColeH

Hello,
I am trying to make a RFID lock that logs who swipes their card and when, onto a SD card.  I am planning to use parallax's RFID reader, http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/rfid/List/0/SortField/4/ProductID/114/Default.aspx  And Adafruit's Sd card and RTC Arduino shield, http://www.adafruit.com/products/1141

This is my current code, it is made up of example code from both the shield and RFID reader.  Any help would be appreciated.

Thanks

Code: [Select]
// 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);   
    }
  }
}

ColeH

So in short, I have included what I believe to be everything, I have done some of the setup, and I have set it so that if a certain card is swiped, it unlocks the lock and logs it to the SD card.  I have not completed the setup portion of the code due to the fact that I am not sure what to set the baud rate as.  The example sketches for the SD shield and the RFID reader both have the baud rate set differently, the RFID is 2400 and the SD shield is 9600.  So I am not sure what to set it as.  Once again, any help would be greatly appreciated.

Grumpy_Mike

Why does the SD card need any specific serial speed?
The RFID reader needs to be at that speed so set it up as 2400.

ColeH

I honestly don't know why the SD card has a different baud rate, but I guess 2400 could work for the whole project.  Thank you.  But is anyone up to the challenge of reading over my code? Thanks.

PaulS

Quote
I have not completed the setup portion of the code due to the fact that I am not sure what to set the baud rate as.  The example sketches for the SD shield and the RFID reader both have the baud rate set differently, the RFID is 2400 and the SD shield is 9600.


Quote
I honestly don't know why the SD card has a different baud rate

This is rubbish. The SD card is not a serial device, so there is no concept of a baud rate when dealing with the SD card.

You really should develop some functions. You don't really intend to repeat that huge block of code to write another entry to the file, for another person, do you?

Quote
But is anyone up to the challenge of reading over my code?

I did. What am I looking for, though?
The art of getting good answers lies in asking good questions.

ColeH

When I read the example sketch for the Adafruit SdDcard and Real Time Clock, It says serial.begin(9600).  Although I have been using Arduino for a little while now, I Know next to nothing about baud rate rate and all of this stuff that made me come here for help.

I quite new to programming so when you say functions, I am not totally sure what you mean, i'm sorry.  IS that when you define a "function" such as, "Print.Time", and then in the loop you call that "function"?

And finally there is nothing in particular that you are looking for in my code.  I just posted it so that you could see how I was doing all of this, and also so that someone might be able to spot a bug for me.  I do not have the SD and RTC shield yet,  nor do I have the RFID reader, so I can't test if it will work yet.

Grumpy_Mike

Quote
I quite new to programming so when you say functions,...

We expect you to take the hint and look up what a function actually is, they are important for reusing code and packaging it up into small chunks you can arrange more easly.

A baud rate only matters if it is communicating with something that you dan't change the baud rate of. So the SD card examples just use serial as a feedback so the baud rate can be anything you can set the serial monitor to. The RFID however is fixed.


ColeH

OK, I get it now,thanks.  I'll go look up functions now.  Sorry, I just asked what they are because I have a feeling that you guys might explain it a little better.  Thanks

ColeH

Ok, so I set up a couple of functions, do you think this is better?
Code: [Select]
// 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 () {

  //Begin RFID
startRFID();
//End RFID
Jonnyblanch();


  bytesread = 0;
     delay(2000);      // wait for a second
        digitalWrite(ledPin,LOW);   
    }
 


void startRFID()
{
   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
  }
}
    }
  }
}

void Jonnyblanch()
{
   DateTime now = RTC.now();
  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);
        }
      }
}

Grumpy_Mike

Look at the setup and loop function. That is what your functions should look like only with diffrent names.
That code will not compile. Do not use #includes inside a function.

ColeH

I don't see any #includes in any of my functions.  Also, I don't see a real difference in the structure of my functions and the loop and setup functions.  I looked up functions and, honestly, mine seems to make sense(as far as I know).  Also, my sketch does compile, but that doesn't mean that it will work.

Grumpy_Mike

When I try and compile your code I get:-
Quote

Arduino: 1.0.5 (Mac OS X), Board: "Arduino Uno"
sketch_jul20a.ino: In function 'void setup()':
sketch_jul20a:38: error: 'class RTC_DS1307' has no member named 'isrunning'


Anyway your function Jonnyblanch() while contains the chunk of code you copied from the original is very specific. The point about functions is that you should try to make them general.  In this case you should pass in the string containing the name and also a number representing the tag. This can then be checked against your list of allowed tags. If you write the function the way you have done the you need to write that same function with minor modifications for everyone who is allowed access. Where you have a constant, make it a variable and pass those variables into the function. That way they are reusable.

Code: [Select]
delay(2000);      // wait for a second or two
It's two.  :)
Why wait?

ColeH

I'm not sure why i get an error and i don't, odd.  I honestly don't really understand what you are trying to get me to do, but, would it make sens to, instead of have the whole jonnyblanch function, have a function for the get time, so that instead of having to have thoes 10 or lines each time, i just have a function.  And I could also have a function for the access granted part, but not for a specific tag, to be more generic?

Grumpy_Mike

Quote
would it make sens to, instead of have the whole jonnyblanch function,

No no sense at all, that is not what computing is about.

Quote
but not for a specific tag, to be more generic?

Yes you can you pass the tag into the function as a variable instead of having it hard coded.

.....
Just as an aside, did you know that what you are trying to do is illegal in some countries, mainly Scandinavia. Recording of positive information, that is the time and data of an access by a person authorized to access is considered a breach of your privacy. In other countries this is not illegal.

ColeH

So instead of what I put before, it would be something more like this?
Code: [Select]
// 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 () {
 
  //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) {
         accessgranted();
         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");
           timestamp();
           // 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);   
    }
  }
}

void timestamp()
{
  DateTime now = RTC.now();
              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();
}

void accessgranted()
{
  lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Granted");
lcd.setCursor(0, 1);
lcd.println(code);
delay (1500);
lcd.setCursor(0, 1);
}


Also, I had no idea that this is illegal in some countries.  At least I'm only going to be using this on the door to my room. :)

Go Up