0

RFID repeating
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

RFID repeating

by drummerboyx on Sun Mar 28, 2010 8:50 pm

Here is my RFID code made to be used with the Parallax RFID reader:
Code: Select all | TOGGLE FULL SIZE
#define TAG_LEN 12

char tag[12] = {'0', '8', '0', '0', 'E', '1', '0', 'F', 'E', '9'}; //0800E10FE9
char code[12];
int bytesread = 0;
int ledPin = 8; // Connect LED to pin 13
int rfidPin = 2; // RFID enable pin connected to digital pin 2
int val=0;

void setup() {
   
 Serial.begin(2400);
 
pinMode(rfidPin,OUTPUT);   // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin
pinMode(ledPin,OUTPUT); // Set ledPin to output
}

 void loop() {
  digitalWrite(rfidPin, LOW); // Activate the RFID reader
  if(Serial.available() > 0) {       // if data available from reader
    if((val = Serial.rnead()) == 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
     }
   }
   if(bytesread >= 10) {        // if 10 digit read is complete

    if(strcmp(code, tag) == 0) {
      Serial.print("Tag matches: ");
      Serial.println(code);
      digitalWrite(ledPin,HIGH); //hold light loop
           delay(5000); //wait 5 seconds
           digitalWrite(ledPin,LOW);

    }
    else {
      Serial.print(code);
      Serial.println(" does not match");
      blink();

    }


   }
   bytesread = 0;
        delay(500);              // wait for a second
    }
  }
}

void blink() { //blink loop
  digitalWrite(ledPin, HIGH);
  delay(250);
  digitalWrite(ledPin, LOW);
  delay(250);
}


Eventually I want this to unlock a door when I put the correct RFID card in front of the reader. As of now, if I hold a card over the reader for a little too long (probably a second or two), the program does the blink loop/light hold twice. This can't happen when I hook this up to a lock. How do I make this not repeat?

Also, how would I be able to add more than 1 card that unlocks my door?

Thanks,
Elijah
drummerboyx
 
Posts: 80
Joined: Wed Feb 10, 2010 7:36 am

Re: RFID repeating

by franklin97355 on Sun Mar 28, 2010 9:20 pm

Don't end the loop() but you will want it to reset sometime or it won't ever work again until you power it off. However you plan to do that will reset the program to look for the cards again.

franklin97355
 
Posts: 21362
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: RFID repeating

by drummerboyx on Sun Mar 28, 2010 9:33 pm

I don't really understand...can you give me that in more detail?
drummerboyx
 
Posts: 80
Joined: Wed Feb 10, 2010 7:36 am

Re: RFID repeating

by johngineer on Sun Mar 28, 2010 9:34 pm

I'd suggest adding some sort of delay count. Computers work a lot faster than people, so sometimes you need to add delays to account for the "human timing" vs. "computer timing" problem.
Adafruit Director of Imaging
Member of Technical Staff
Poles up, zeroes down.
johngineer
 
Posts: 105
Joined: Fri Aug 14, 2009 6:05 pm
Location: Brooklyn, NY, USA

Re: RFID repeating

by drummerboyx on Sun Mar 28, 2010 10:06 pm

I just tried adding some delays, but still no luck... Any other ideas?
drummerboyx
 
Posts: 80
Joined: Wed Feb 10, 2010 7:36 am

Re: RFID repeating

by pstemari on Sun Mar 28, 2010 11:10 pm

Easiest way is to set up a state machine. You have three states: IDLE, ACTIVE, and RESETTING. IDLE goes to ACTIVE when a card is scanned, ACTIVE goes to RESETTING once you activated the bolt, and RESETTING goes to IDLE after it's been in RESETTING for 5-10 seconds. Code looks like this:

Code: Select all | TOGGLE FULL SIZE
enum State {IDLE, ACTIVE, RESETTING};
unsigned long lastStateTransition = 0;
unsigned long resetExpires = 0;
int currentState = IDLE;

void loop()  {
  switch (currentState)  {
    case IDLE:
      if (readCardInput())  {
        currentState = ACTIVE;
        lastStateTransition = millis();
      }
      break;

    case ACTIVE:
      unlockDoor();
      if (lastStateTransition + 5000L < millis())  {  // Stay in ACTIVE for 5 seconds
        currentState = RESETTING;
        lastStateTransition = millis();
        resetExpires = lastStateTransition + 5000L;  // or whatever delay you need
      }
      break;

    case RESETTING:
      lockDoor();
      if ((Serial.available() > 0) {
        Serial.flush();  // ignore input
        resetExpires = millis() + 5000L; // move up the expiration time 5 seconds
      }
      if (resetExpires < millis())  {
        currentState = IDLE;
        lastStateTransition = millis();
      }
      break;
  }
}


Essentially you let it sit in a resetting state for whatever timeout is needed to avoid the double read, and while in that resetting state you discard all input. The card reader has to remain silent for five seconds before you start accepting card swipes again.

Play around with the various delays to tune the behavior for a good "feel".
--Paul

A wholly owned subsidiary of:
Persephone: DL R+W+B C 7 X L W C++ I++ T+ A E H++ S+ V-- F+ Q P B PA+ PL
Aldebaran: DM Rt H 5 Y L- W+ C+ I++ T++ A+++ E H++ S+ V+ F++ Q+ P B++ PA- PL--
User avatar
pstemari
 
Posts: 310
Joined: Sun Mar 21, 2010 6:10 pm
Location: Seattle, WA

Please be positive and constructive with your questions and comments.