RFID Again!

If you look at the code I posted it is in there.

I still want to know how you would fix your broken code example to help me understand it.

OK I changed it a bit hoping to eliminate the pause but it didn't help. it did however put the printed messages through SoftSerial.

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

const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'#','0','*'}
};

byte rowPins[ROWS] = { 11, 6, 7, 9 }; // Connect keypad ROW0, ROW1, ROW2, ROW3 to these pins.
byte colPins[COLS] = { 10, 12, 8 }; // Connect keypad COL0, COL1 and COL2 to these pins.

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define ledpin 19

SoftwareSerial LCD = SoftwareSerial(rxPin, txPin); //create a Serial object LCD
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 tagCnt = 5;
int LOCK = 4;

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

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

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

void loop()

{
val = 0;
bytesread = 0;
if (Serial.available() > 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 <= tagCnt)*
  • digitalWrite(LOCK, HIGH);*
  • delay(5000);*
  • digitalWrite(LOCK, LOW);*
  • }*
    }
    char key = kpd.getKey();
    if(key) // same as if(key != NO_KEY)
    {
  • switch (key)*
  • {*
    _ case '*':_
  • digitalWrite(ledpin, LOW);*
  • break;*
  • case '#':*
  • digitalWrite(ledpin, HIGH);*
  • break;*
  • default:*
  • Serial.println(key);*
  • }*
    }
    }
    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]

Well I finally got my new Seeduino Mega after waiting nearly 3 weeks! It sure takes things awhile to get here from china! I'm gonna see if I can get the code working faster on it since it has more Hardware serial. It's a nice board, only slightly larger than the Arduino. I'll definately have plenty of I/O's on this board ;D

Ok I think I know what the problem is, it's the delay to allow people time to open the door! but how do I relocate it so it doesn't slow the read time down too???

Use millis to capture the time the door is unlocked. Set a time 5 seconds (or 10 or 15 would be better) in the future (timeToRelock) when the door should be locked again. Then, remove the delay(5000); statement.

Add a test in loop:

if(millis() - timeToRelock > 0)
    digitalWrite(LOCK, LOW);

Put this after the code that unlocks the door.

but how do I relocate it so it doesn't slow the read time down too?

If the door is open do you still need to read?

Thanks I'll give that a try.

So how do I declare "timeToRelock"? or better yet is there a better description of the use of millis somewhere besides the reference page??

here is what I tried.

if(tag > 0 && tag <= tagCnt)
digitalWrite(LOCK, HIGH);
timeToRelock = millis();
if(millis() - timeToRelock > 0)
digitalWrite(LOCK, LOW);

The timeToRelock variable is a long.

long timeToRelock = 0;

Your code should look more like this

if(tag > 0 && tag <= tagCnt)
{
     digitalWrite(LOCK, HIGH);
     timeToRelock = millis();
}
else
     timeToRelock = 0;

if(millis() - timeToRelock > 0)
     digitalWrite(LOCK, LOW);

Thanks and Merry Xmas!

Can you point me to someplace that better explains millis and other C programming?

Ok hereoute] is what I did

if(tag > 0 && tag <= tagCnt)

{
digitalWrite(LOCK, HIGH);
long timeToRelock = millis();
}
else
timeToRelock = 0;

if(millis() - timeToRelock > 0)
digitalWrite(LOCK, LOW);
}

I put this before Void setup

long timeToRelock = 0;

But it now only reads a null card and won't read a valid card it justs reads it as a null card??

Ok I think I know what the problem is. Because it's reading a null before reading the card, millis is stoping it from reading the card number??

I think I'm going to give up! and just use it without the LCD or keypad! Because I really need this finished. I'm a quadraplegic bound to a wheelchair, which makes unlocking and opening my front door very difficult. At least with basic function I can use it and maybe keep working on the program.

There just isn't enough info on programming the Arduino unless you already have programming experience! Which is very frustrating, I wish there were classes for the Arduino in my area!!!! I have nothing to do all day but work on this and still I'm stumped aarrrrgggg!

Broken and defeated
SubMicro :-[

What you have done should not have affected the reading of an RFID card. Please post your code again, and I'll have a look.

Your right I went through and re did everything and now it reads very fast however it still isn't working properly now the lock stays high instead of low. I tried changing millis to 5000 but that just kept it low for 5 seconds on startup. heres the code.

#include <Keypad.h>
#define rxPin 19
#define txPin 18
#define ledpin 13

long timeToRelock = 0;

const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'#','0','*'}
};

byte rowPins[ROWS] = { 11, 6, 7, 9 }; // Connect keypad ROW0, ROW1, ROW2, ROW3 to these pins.
byte colPins[COLS] = { 10, 12, 8 }; // Connect keypad COL0, COL1 and COL2 to these pins.

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define ledpin 7

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 tagCnt = 5;
int LOCK = 6;

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

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

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

void loop()

{
val = 0;
bytesread = 0;
if (Serial1.available() > 0)
{
while(bytesread < 12)
{
// read 12 digit code

val = Serial1.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 <= tagCnt)*
  • {*
  • digitalWrite(LOCK, HIGH);*
  • timeToRelock = millis();*
  • }*
  • else*
  • timeToRelock = 5000;*
  • if(millis() - timeToRelock > 0)*
  • digitalWrite(LOCK, LOW);*
  • }*
  • }*
  • char key = kpd.getKey();*
  • if(key) // same as if(key != NO_KEY)*
  • {*
  • switch (key)*
  • {*
    _ case '*':_
  • digitalWrite(ledpin, LOW);*
  • break;*
  • case '#':*
  • digitalWrite(ledpin, HIGH);*
  • break;*
  • default:*
  • Serial.println(key);*
  • }*
  • }*
    }
    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]

Also if you find the problem don't just post the fix please try to explain it to me if you have the time. I really want to learn this!

I'm still going to use the simple version until I get this working I post pics of the setup sometime after Xmas.

Thanx
SubMicro

     // Lock the door (this should be done in setup, not here
     digitalWrite(LOCK, LOW);

     // Check if the RFID tag was valid
     if(tag > 0 && tag <= tagCnt)
        {
        // It was, so unlock the door
        digitalWrite(LOCK, HIGH);

        // Define when to relock the door (5 seconds after unlocking it)
        timeToRelock = millis()[glow] + 5000[/glow];
        }
        else
        {
            // Tag was not valid. The time to relock the door is NOW
            timeToRelock = [glow]millis(); // was 5000[/glow]
        }
    } // End of serial.available loop

[glow]    // Move this outside of the Serial.available() loop.
    // We want to lock the door regardless of whether
    // or not there is Serial data available to read
    // See if the door has been unlocked long enough
    if(millis() - timeToRelock > 0)
        digitalWrite(LOCK, LOW);
[/glow]

I added some comments to a portion of the code, and highlighted some changes that need to be made. I think the comments explain why the changes are needed. If something isn't clear, ask again.

ooo...useful info,thanks...

PaulS

Ok I tried what you suggested, but there still seems to be a problem. I sure it's something I'm missing but I can't figure it out.

The program continually prints a single digit in sequence when no card is near, and when a card is presented it reads it then right back to what it was doing.

#include <Keypad.h>
#define rxPin 19
#define txPin 18
#define ledpin 13

long timeToRelock = 0;

const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};

byte rowPins[ROWS] = { 11, 6, 7, 9 }; // Connect keypad ROW0, ROW1, ROW2, ROW3 to these pins.
byte colPins[COLS] = { 10, 12, 8 }; // Connect keypad COL0, COL1 and COL2 to these pins.

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define ledpin 7

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 tagCnt = 5;
  int LOCK = 6;

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

  pinMode(rxPin, INPUT); //set pin on arduino for receiving RFID data
  pinMode(txPin, OUTPUT); //this is not important
  pinMode(ledpin, OUTPUT);
  digitalWrite(ledpin, HIGH);
  digitalWrite(LOCK, LOW);
  
  for(int i=0; i<tagCnt; i++)
  {
    pinMode(LOCK, OUTPUT);
  }
}

void loop()

{
  val = 0;
  bytesread = 0;
  if (Serial1.available() > 0)
  {
    while(bytesread < 12)
    {
     // read 12 digit code

     val = Serial1.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);

        if(tag > 0 && tag <= tagCnt)
        {
        digitalWrite(LOCK, HIGH);
        timeToRelock = millis() + 5000;
        }
        else
        timeToRelock = millis();

        }
     }
    
    if(millis() - timeToRelock > 0)
    digitalWrite(LOCK, LOW); 

  char key = kpd.getKey();
  if(key)  // same as if(key != NO_KEY)
  {
    switch (key)
    {
     case '*':
       digitalWrite(ledpin, LOW);
       break;
     case '#':
       digitalWrite(ledpin, HIGH);
       break;
     default:
       Serial.println(key);
    }
  }
}

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;
}

What does the output look like? The serial output should show stuff like:

Tag: [xxxxxxxxxxx]
Tag number: x
x

The Tag: and Tag number: lines should only be printed when a tag is read. The x lines should only be printed when a key is pressed.

Add

Serial.print("Key pressed: ");

after the default: line in the switch statement, so we know for certain what the number means.

Now it prints "key pressed " with a number but it goes so fast I cant read it. Could this be because I don't have the keyboard hooked up right now?

It looks like you described but now with key pressed being printed constantly scrolling down it never stops