RFID Again!

Ok I've officially gone mad!

My project is simply this....

RFID reader to scan tags
3X4 keypad for user input upon RFID failure
16X4 LCD for feedback
electric door latch or lock which ever I get my hands on first

Ok user swipes card or key fob, scanner sends data to Arduino
which compares data to database, if a match, opens or unlocks door . If RFID tag fails user inputs code using keypad and LCD. After X number of failures system locks out for X amount of time. Records all activity in log on SD / MMC Card or I2C Eprom etc.. Possibly add intercom if possible.

Do I use If Else statements to compare RFID strings?
How do I implement a database?
Should I get a Sanguino or Mega Arduino for this?

And will Batman escape the Jokers devious trap??
Will Robin come out of the closet????
Stay tuned for this and more!! Muwa ha ha ha ha!
Told ya I went Mad! [smiley=2vrolijk_08.gif]

SubMicro

How many RFID tags/cards will be given out? If it's a small number, you don't need a database. You could have a file on the SD that contains the valid numbers. Read the file looking for the number. If it's found, open the door.

If it's a large number, you might need a database. Of course, stuffing a database onto an Arduino is like parking a semi in a compact spot.

You're not attaching enough stuff to max out an Arduino. It's capable of all you want to do. Well, except the database, and that won't fit on a Mega, either.

Of course Batman will escape. Wouldn't be able to make another pointless movie and a bazillion bucks if he didn't. >:(

I thought Robin was out of the closet. :wink:

I'm not sure I'm ready for more.

Just a small number of tags will be issued 5 at max. I think using part of your code will work

#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 3

//create a Serial object RFID
SoftwareSerial RFID = SoftwareSerial(rxPin, txPin);
char code[20];

int val = 0;
int bytesread = 0;

char Red[]    = "3900A502C35D";     // Tag ID.
char Blue[]   = "39009F2DAD26";    // Tag ID.
char Yellow[] = "39005082A843";    // Tag ID.
char Card1[]  = "140029A6079C";   //  etc..
char Card2[]  = "14002943BFC1";  //   etc..

int ledCnt = 5;
int LED[] = {13, 11, 9, 7, 5};

void setup()
{
  Serial.begin(9600); //open serial hardware
  RFID.begin(9600); //open serial software

  pinMode(rxPin, INPUT); //set pin on arduino for receiving RFID data
  pinMode(txPin, OUTPUT); //this is not important

  for(int i=0; i<ledCnt; i++)
  {
    pinMode(LED[i], OUTPUT);
  }
}

void loop()
{
  val = 0;
  bytesread = 0;

  while(bytesread < 12)
  {
    // read 12 digit code
    val = RFID.read();
    if(val == 3)
    { // if header or stop bytes before the 10 digit reading
      break; // stop reading
    }

    if(val != 2)
    {
      code[bytesread] = val; // add the digit
      bytesread++; // ready to read next digit
      code[bytesread] = '\0'; // add the NULL
    }
  }

  if(bytesread >= 12)
  { // if 12 digit read is complete
    Serial.print("Tag: [");
    for(int i=0; i<bytesread; i++)
    {
      Serial.print(code[i]);
    }
    Serial.println("]"); //print the whole 13 bytes
    int tag = FindValidTag(code);
    Serial.print("Tag number: ");
    Serial.println(tag);

    for(int i=0; i<ledCnt; i++)
      digitalWrite(LED[i], LOW);
    if(tag > 0 && tag <= ledCnt)
      digitalWrite(LED[tag-1], HIGH);
  }
}

int FindValidTag(char *code)
{
  if(strcmp(code, Red) == 0)
    return 1;
  else if(strcmp(code, Blue) == 0)
    return 2;
  else if(strcmp(code, Yellow) == 0)
    return 3;
  else if(strcmp(code, Card1) == 0)
    return 4;
  else if(strcmp(code, Card2) == 0)
    return 5;
  else
    return 0;
}

However how to modify this to include the keypad, LCD, and triggering a relay instead of LED's is what I'm working on now.

How can I eliminate the LED's and just pull one pin high on a matched read regardless of the number? I also need to be able to manually enter a code and pull a pin high to energize a relay module I have to power the electric door latch.

Triggering the relay should be exactly the same as lighting an LED, except that you want to trigger the relay when any valid tag is presented, instead of lighting a specific LED.

Depending on which LCD and which keypad you have, there may be libraries that make communicating with them simple. Getting the logic right should be the only hard part. And that isn't even too difficult. Start with comments, without code, that describe what you want to do. Then add code that does what the comments say.

If you have difficulties, post you code, and we'll help.

Thanx I appreciate the help. I really like your suggestion of adding comments first then adding code to do what the comments say, great idea. :smiley:

I'm afraid of breaking the code i'm not sure what I can remove of the LED prt of the code.

Make a copy of the code, before making changes. When the changes work, save them.

The LED code is this:

int ledCnt = 5;
int LED[] = {13, 11, 9, 7, 5};

That code defines the number of LEDs to be manipulated and the pins that the LEDs are connected to.

  for(int i=0; i<ledCnt; i++)
  {
    pinMode(LED[i], OUTPUT);
  }

That code declares the LED pins to be output pins.

and:

    for(int i=0; i<ledCnt; i++)
      digitalWrite(LED[i], LOW);
    if(tag > 0 && tag <= ledCnt)
      digitalWrite(LED[tag-1], HIGH);

That code turns off all the LED pins, and turns on one LED pin, depending on which tag was read.

Here's what I did to use only one pin to go high with a good read.

 int ledCnt = 5;
  int LED[] = {5};

Heres what I added to turn the pin low after enuff time to open the door.

 for(int i=0; i<ledCnt; i++)
      digitalWrite(LED[i], LOW);
    if(tag > 0 && tag <= ledCnt)
      digitalWrite(LED[tag-1], HIGH);
        delay(5000);
        digitalWrite(LED[tag-1], LOW);

Woo Hoo!!! it works!
I know it's not pretty but it works, now I'm working on the keypad which will be much more difficult!
Thank you for letting me turn your code into a mess :wink: and helping me understand it.
Any tips as where to insert the keypad code??

Ok it doesn't work! The LED only lights for one tag! I know it's just an ID10T problem, I'm working on it.

got now had to change this line

 int LED[] = {5};

to this

 int LED[] = {5, 5, 5, 5, 5};

Simpler would have been to change

int LED[] = {5};

to

int LED = 5;

and change:

 for(int i=0; i<ledCnt; i++)
      digitalWrite(LED[i], LOW);
    if(tag > 0 && tag <= ledCnt)
      digitalWrite(LED[tag-1], HIGH);
        delay(5000);
        digitalWrite(LED[tag-1], LOW);

to:

    digitalWrite(LED, LOW);
    if(tag > 0 && tag <= ledCnt)
      digitalWrite(LED, HIGH);
    delay(5000);
    digitalWrite(LED, LOW);

I tried something similar but couldn't get it to work, then I tried your changes. I had to change one other line from

 pinMode(LED[i], OUTPUT);

to

pinMode(LED, OUTPUT);

but after that worked like a charm. My problem was that, tag-1 couldn't figure it out!

Now I'm on hold untill I figure out the pin out for the keypad! my DVM is on the fritz. (cheap Harbor Freight crud) I need to invest in a decent DVM.

I'm through for the night, all the wires are blurring together! time for a break!

Ok PaulS

Now that I've got the keypad wired up and functional, where in the code should the keypad code go?? My thought is at the beginning.

start up, check for keypad input if so do this, check for tag input if so do this, loop

What do ya think?

You got it.

I just thought of something, the keypad used up all my digital I/O pins. The LCD has nowhere to go!

Time for a Mega. Or, the analog pins can also be used as digital pins 14 thru 19.

Which is better Arduino Mega or Sanguino??

The Mega has way more I/O's

http://www.wulfden.org/TheShoppe/freeduino/sanguino.shtml

If I get a serial backpack for the LCD I can get away with using the analog pins as digital and have just enuff pins to get by.

Well I went and ordered myself a Christmas present, a Seeduino Mega! Just in case I can't do this with the Duemilanove. I will still try and pull it off with the Duemilanove though.

SubMicro

Hey PaulS

Riden over at the SparkFun forum suggested that in order for me to be able to read keypad input I should use serial instead of softserial. Otherwise it will be constantly scanning for RFID tags, and I wont be able to interupt for the keypad. Here is what he suggested.

You will have to find a way to determine if data is ready from the RFID reader, otherwise your code is going to be waiting for a tag to be read. That would effectively disable your keypad functionality. If you use the Seral library instead of the SoftwareSerial library, you can poll to see if data is ready.

void setup() {
   Serial.begin(9600);   // opens serial port at 9600 bps
}

void loop() {
    // This gets the data from the RFID if any is available
    if (Serial.available() > 0) {
        // here you would loop to get all your characters and do something
        // with them. This snippet just reads one character
       int  data = Serial.read();

        // ... other processing...
    }

    // Now look at your keyboard
    char key = keypad.getKey();
    if (key != NO_KEY) {
        /./ do something interesting with the key
    }
}

I really don't want to rewrite half the code, :-? is there another way around this?

SubMicro

Where ya at ? Anything?

I don't spend 24 hours a day in front of my computer. Only 20.

It's not that big a deal changing from a SoftwareSerial port to the hardware port. Just change RFID.read to Serial.read.

My apologies I spend 23 7/8th's a day :wink:

Ok if I use hardware Uart instead of Softserial, won't that affect the LCD? If not then how do I stop the loop so I can check the keypad? I can't find a good explanation of while loops. Or I'm having a temporary (I hope it's temporary) case of the Dumb A$$ ! [smiley=sad.gif]
I'm so close it's killing me! maybe I need a break, spend some time RTFM!!

I forgot here's the modified code using Hardware serial. I just commented out the SoftSerial stuff.

//#include <SoftwareSerial.h>
#include <Keypad.h>
//#define rxPin 2
//#define txPin 3

//SoftwareSerial RFID = SoftwareSerial(rxPin, txPin); //create a Serial object RFID
char code[20];

int val = 0;
int bytesread = 0;

char Red[] = "3900A502C35D"; // Define valid tags
char Blue[] = "39009F2DAD26"; // "
char Yellow[] = "39005082A843"; // "
char Card1[] = "140029A6079C"; // "
char Card2[] = "14002943BFC1"; // "

int ledCnt = 5;
int LOCK = 4;

void setup()
{
Serial.begin(9600); //open serial hardware
//RFID.begin(9600); //open serial software

// pinMode(rxPin, INPUT); //set pin on arduino for receiving RFID data
// pinMode(txPin, OUTPUT); //this is not important

for(int i=0; i<ledCnt; i++)
{
pinMode(LOCK, OUTPUT);
}
}

void loop()
{
val = 0;
bytesread = 0;

while(bytesread < 12)
{
// read 12 digit code
val = Serial.read();
if(val == 3)// if header or stop bytes before the 10 digit reading
{
break; // stop reading
}

if(val != 2)
{
code[bytesread] = val; // add the digit
bytesread++; // ready to read next digit
code[bytesread] = '\0'; // add the NULL
}
}

if(bytesread >= 12)
{ // if 12 digit read is complete
Serial.print("Tag: [");
for(int i=0; i<bytesread; i++)
{
Serial.print(code*);*

  • }*
  • Serial.println("]"); //print the whole 13 bytes*
  • int tag = FindValidTag(code);*
  • Serial.print("Tag number: ");*
  • Serial.println(tag);*
  • digitalWrite(LOCK, LOW);*
  • if(tag > 0 && tag <= ledCnt)*
  • digitalWrite(LOCK, HIGH);*
  • delay(5000);*
  • digitalWrite(LOCK, LOW);*
  • }*
    }
    int FindValidTag(char *code)
    {
  • if(strcmp(code, Red) == 0)*
  • return 1;*
  • else if(strcmp(code, Blue) == 0)*
  • return 2;*
  • else if(strcmp(code, Yellow) == 0)*
  • return 3;*
  • else if(strcmp(code, Card1) == 0)*
  • return 4;*
  • else if(strcmp(code, Card2) == 0)*
  • return 5;*
  • else*
  • return 0;*
    *} *
    [/quote]