Parallax RFID Reader <--> Arduino

A while back, I purchased a Parallax RFID reader and used it for authentication for my house door. It was kind of a hack job and wasn’t as stable as I would have liked so I never documented it and put it on the backburner. I recently decided to revisit the device for a project for Gumbo Labs.

The Parallax reader

The Parallax reader

BTW, you can now get this at your local Radioshack?!?. Maybe they are starting to move in the right direction again? Who knows.

Anyway, this device was initially easy to get running but it was not as stable as I hoped it would be. The example code online did not fully account for the quirks of this reader. I had to closely read the manual to make it work as expected. I am going to briefly describe how to get the best out of this reader and properly integrate it with your Arduino.

First you want to get them connected. The quickest way to do this is with a breadboard and some wires like this guy does:

Connecting Arduino to RFID reader

Connecting Arduino to RFID reader

The mapping should be similar to this:

  • Arduino serial RX to Parallax TX
  • Arduino GND to Parallax GND
  • Arduino digital pin (i.e. #2) to Parallax /ENABLE
  • Arduino +5V to Parallax Vcc

Keep in mind that when you upload your binary to the Arduino, you may need to disconnect the Parallax TX connection, just a warning.

Now to the Arduino code…

I will explain each piece in detail and give the whole code at the end. If you are impatient and hate learning, go there.

First let’s deal with this /ENABLE pin. Here is what the documentation says about it:

The RFID Card Reader is activated via the /ENABLE line. When the RFID Card Reader is powered and the /ENABLE line is pulled HIGH, the module will be inactive (standby mode) and the LED will be GREEN. When the /ENABLE line is pulled LOW, the RFID Card Reader enter its active state and enable the antenna to interrogate for tags. The current consumption of the module will increase dramatically when the module is active.

So, when the pin is HIGH, the reader is inactive and in a low current consumption mode. When the pin is LOW, the reader is active and can read tags. To utilize this pin, I created two functions:

#define RFID_ENABLE 2  //pin connected to ENABLE
 
void enableRFID() {
    digitalWrite(RFID_ENABLE, LOW);
}
 
void disableRFID() {
    digitalWrite(RFID_ENABLE, HIGH);
}

The usage of this functionality depends on your application. If you (and by you here I mean the Arduino) know when you will need to read a tag, keep the reader inactive until then to conserve current. This situation is not as likely as you usually want the Arduino to just know when a tag is next to it at any time. In this case, we will use it to briefly deactivate the reader after a tag is read. This will keep the Arduino from getting duplicate or junk/half reads and it will reset the reader for the next tag.

Reading a Tag’s Unique ID

As the documentation describes, when the reader is in active mode and a tag is placed near the antenna, a 12 byte message will come across the Parallax TX serial line. The documentation says this about the serial configuration:

All communication is 8 data bits, no parity, 1 stop bit, and least significant bit first (8N1). The baud rate is configured for 2400 bps, a standard communications speed supported by most any microprocessor or PC, and cannot be changed.

8N1 is the standard for your Arduino, you just have to tell it to start up the UART at 2400 baud in your setup() function:

Serial.begin(2400);

The designer of the RFID reader, KingPin if I am not mistaken, designed a custom protocol so we can determine where the tag starts and ends. Once again, we refer to the documentation (click to get a larger view of the picture):

RFID tag message protocol

RFID tag message protocol

The start byte and stop byte are used to easily identify that a correct string has been received from the
reader (they correspond to a line feed and carriage return characters, respectively). The middle ten bytes are the actual tag’s unique ID.

In other words, you should read the incoming serial bytes until you find the start byte [hex 0x0A || decimal 10 || line feed]. You should then read the next 10 bytes as the tag’s unique ID and hope that the stop byte [hex 0x0D || decimal 13 || carriage return] shows up last. BTW, if you ever need to know something like the hex and decimal values of line feed, check here.

Now let’s take a look at the piece of code which reads the tag. I am going to litter it with comments, it looks huge but it is actually pretty concise:

//you need to define these
#define CODE_LEN 10          //Max length of RFID code
#define START_BYTE 0x0A   //decimal 10 or LINE-FEED
#define STOP_BYTE 0x0D     //decimal 13 or CARRIAGE-RETURN
 
char tag[CODE_LEN];    //this is the character where we store the tag
 
/**
 * Blocking function, waits for and gets the RFID tag.
 */
void getRFIDTag() {
 
  /**
   * next_byte is temporary storage for every byte we read
   */
  byte next_byte;
 
  /**
   * this next part blocks the code until we get something in
   * the incoming serial buffer. This is what makes this a
   * "blocking function". You may want to comment this out
   * if you have stuff to do if a tag is not present.
   */
  while(Serial.available() <= 0) {}
 
  /**
   * if we get here, there is at least one byte in the buffer
   * the next if reads it and checks to see if it is the start_byte
   * if it isn't, we are just moving on.
   */
  if((next_byte = Serial.read()) == START_BYTE) {
    //bytes_read keeps track of how many bytes into the tag we are
    byte bytes_read = 0; 
 
   /**
    * This while loop makes sure we don't read
    * more bytes than we can store in tag array.
    */
    while(bytes_read < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
 
          /**
           * Here we read the next byte and make sure it
           * is not the STOP byte, if it is, we must break
           */
          if((next_byte= Serial.read()) == STOP_BYTE) break;        
 
          /**
           * Now we store that byte into the
           * tag at the next position by incrementing
           * bytes_read and storing next_byte at that position
           * in the tag array.
           */
          tag[bytes_read++] = next_byte;
      }
    }
  }
}

Dealing with radio interference

Let’s say you implement the getRFIDTag() function like this:

void loop() {
  enableRFID();
  getRFIDTag();
  disableRFID();
  sendCode();
  delay(3000); //wait 3 seconds
  Serial.flush();
  clearCode();
} 
 
/**
 * Clears out the memory space for the tag to 0s.
 */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}
 
/**
 * Sends the tag to the computer.
 */
void sendCode() {
    Serial.print("TAG:");  
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    } 
}

So, you have this running and you are using the Arduino’s serial listener in the IDE, and you notice that every once in a while, you get a random tag for no reason. This kind of bug can be a problem and it is one of the things that made my door authentication device so unstable. I wish I would have RTFM a little closer:

The Parallax RFID Card Reader, like many RF devices, may experience RF noise in its frequency range.
This may cause the reader to transmit a spurious tag response when no tag is near the unit. This will not
affect most uses of the RFID Card Reader. To completely prevent spurious responses, it is recommended
to simply read two responses in a row within a given amount of time (e.g. 1 second) to ensure that you
are reading a valid tag and not a “tag” generated by noise.

I originally thought I was the lone genius who came up with this solution until I read that paragraph :( Oh well.

Let’s look at a way we can implement this idea. I noticed when you hold a tag to the reader, considering you don’t deactivate after a read, it just continues to spit out the number until you pull the tag away. So, what we need is a function that is called immediately after getRFIDTag() that reads the code again and validates that it is the same. Most of this function is the same as getRFIDTag(), and I hate to break DRY principles, but we are going for simplicity here and I don’t want this to turn into tutorial on pointers!:

/**
 * Waits for the next incoming tag to see if it matches
 * the current tag.
 */
boolean isCodeValid() {
  byte next_byte;
  while(Serial.available() <= 0) {}
  if((next_byte = Serial.read()) == START_BYTE) {
    byte bytes_read = 0;
    while(bytes_read < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;
          /**
           * this is the only part that is really different,
           * if we find one byte that is off, we return false,
           */
          if(tag[bytes_read++] != next_byte) return false;
      }
    }
  }
  return true; // if we get here, 'it must be good'
}

So, this is all good right? No, not really. If you were able to see a problem with this line:

  while(Serial.available() <= 0) {}

you are very perceptive. This will work for real tags but will make things complicated when noise occurs. Consider the believable case in which we get a junk tag from noise every 30 minutes. When we get that junk tag, we will be stuck on that line. One way to get around it is to apply a timeout. Here is a pretty ghetto way to implement that, just change the above line to this [UPDATE, there is a bug with this, see end of page]:

  int count = 0;
  while(Serial.available() <= 0) { //passes when we get a byte
    delay(1); //wait one millisecond
    if(count++ > VALIDATE_LENGTH) return false; //else check again
  }

We define VALIDATE_LENGTH to be the number of milliseconds, roughly, that the isCodeValid() function will wait until it realizes the tag you are asking to validate is just noise.

#define VALIDATE_LENGTH 200 //wait 200 ms

So, now you should be good to go. If you are looking to storing and comparing keys in non-volatile memory, I suggest looking at the EEPROM library. I already wrote some code to do this so if you are curious let me know in the comments. As promised, here is all the code for this article:

/**
 * author Benjamin Eckel
 * date 10-17-2009
 *
 */
#define RFID_ENABLE 2   //to RFID ENABLE
#define CODE_LEN 10      //Max length of RFID tag
#define VALIDATE_TAG 1  //should we validate tag?
#define VALIDATE_LENGTH  200 //maximum reads b/w tag read and validate
#define ITERATION_LENGTH 2000 //time, in ms, given to the user to move hand away
#define START_BYTE 0x0A 
#define STOP_BYTE 0x0D
 
char tag[CODE_LEN];  
 
void setup() { 
  Serial.begin(2400);  
  pinMode(RFID_ENABLE,OUTPUT);   
}
 
void loop() { 
  enableRFID(); 
  getRFIDTag();
  if(isCodeValid()) {
    disableRFID();
    sendCode();
    delay(ITERATION_LENGTH);
  } else {
    disableRFID();
    Serial.println("Got some noise");  
  }
  Serial.flush();
  clearCode();
} 
 
/**
 * Clears out the memory space for the tag to 0s.
 */
void clearCode() {
  for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0; 
  }
}
 
/**
 * Sends the tag to the computer.
 */
void sendCode() {
    Serial.print("TAG:");  
    //Serial.println(tag);
    for(int i=0; i<CODE_LEN; i++) {
      Serial.print(tag[i]); 
    } 
}
 
/**************************************************************/
/********************   RFID Functions  ***********************/
/**************************************************************/
 
void enableRFID() {
   digitalWrite(RFID_ENABLE, LOW);    
}
 
void disableRFID() {
   digitalWrite(RFID_ENABLE, HIGH);  
}
 
/**
 * Blocking function, waits for and gets the RFID tag.
 */
void getRFIDTag() {
  byte next_byte; 
  while(Serial.available() <= 0) {}
  if((next_byte = Serial.read()) == START_BYTE) {      
    byte bytesread = 0; 
    while(bytesread < CODE_LEN) {
      if(Serial.available() > 0) { //wait for the next byte
          if((next_byte = Serial.read()) == STOP_BYTE) break;       
          tag[bytesread++] = next_byte;                   
      }
    }                
  }    
}
 
/**
 * Waits for the next incoming tag to see if it matches
 * the current tag.
 */
boolean isCodeValid() {
  byte next_byte; 
  int count = 0;
  while (Serial.available() < 2) {  //there is already a STOP_BYTE in buffer
    delay(1); //probably not a very pure millisecond
    if(count++ > VALIDATE_LENGTH) return false;
  }
  Serial.read(); //throw away extra STOP_BYTE
  if ((next_byte = Serial.read()) == START_BYTE) {  
    byte bytes_read = 0; 
    while (bytes_read < CODE_LEN) {
      if (Serial.available() > 0) { //wait for the next byte      
          if ((next_byte = Serial.read()) == STOP_BYTE) break;
          if (tag[bytes_read++] != next_byte) return false;                     
      }
    }                
  }
  return true;   
}

I have tested this as well as I can. I have yet to catch any noise events ‘in the wild’ so to speak, which concerns me [read Updates, lol]. But I have tested each case in the isCodeValid() function. I have caused a false validation by timeout and by differing keys [repetitive noise]. But I have also broken it by causing it to read “half” of a key. If it still doesn’t work for you, get creative, there are many ways around the interference issue.

Please let me know if you find faults or improvements and Enjoy :)

Updates

02/07/2010 – For those of you who have been using this code and still getting some noise, I apologize because I just found a bug with the isCodeValid function. For some reason, I was not getting past the line:

if ((next_byte = Serial.read()) == START_BYTE) {

I ran this code right before that line:

  for (int i = 0; i < 30; i++) {
    Serial.print("a");
    Serial.print(Serial.available(), DEC);
    Serial.print("r");
    Serial.print(Serial.read(), DEC);
    Serial.println();
  }

And this came on the port:

a1r13
a0r-1
a0r-1
a0r-1
a0r-1
a0r-1
a0r-1
a0r10
a6r48
a10r52
a9r49
a8r54
a9r50
a15r66
a17r69
a16r65
a15r49
a14r54
a13r13
a12r10
a11r48
a10r52
a9r49
a8r54
a7r50
a6r66
a5r69
a4r65
a3r49
a2r54

Now, ignore the line a0r10. It is not a bug, it is just that it takes so long to print to the serial port at 2400 baud. Anyway, what is obvious is that my whole function was breaking b/c the STOP_BYTE (13), was still in the buffer. I tried to do a flush before the function but that didn’t work for whatever reason. So what I did is change the while loop to this:

while (Serial.available() < 2) {

and then after the while loop breaks, throw that 13 away:

Serial.read();

Sorry this took so long for me to figure out, I was on hiatus, I hope it didn’t mess anyone up. This change is reflected in the whole piece of code.

This entry was posted in Arduino, Tutorial/Documentation and tagged , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

41 Comments

  1. Posted October 21, 2009 at 2:46 pm | Permalink

    This is almost exactly what I have done for the RFID access at my hackerspace. The one main difference is that I used software serial instead of the tx/rx serial pins on the Arduino. With this, you can run several of these readers from one Arduino. Might be something useful to look at. Also, I’m shooting the tag out via serial to a python script that looks in a tag database and sends back access codes. Great write up on the process.

  2. Andrew Larimer
    Posted October 21, 2009 at 3:02 pm | Permalink

    Thanks for this! Can’t wait to get a chance to try it out.

  3. Posted October 21, 2009 at 3:21 pm | Permalink

    @Chris

    Thanks for the tip, software serial is a good way to go and has become more reliable over the last couple of iterations. Especially if you need the serial port for bidirectional serial communication. The one problem I had with it was I could not think of a way to check for a timeout while I was waiting for the next tag to come across. The disadvantage to the Software Serial library is that you can’t check a buffer to see if there are any bytes available, when you do a read(), you have to wait for the bytes to come in. I am not sure if this is still the case though.

    My original purposes are to use this reader with the ethernet shield though, so I decided to use the serial port. You should use the UART any chance you get as it is more reliable and it doesn’t block your micro while waiting for a serial read. I am going to post another article when I am done with the project I am using it for. Please stay tuned.

  4. aerohead
    Posted October 21, 2009 at 3:41 pm | Permalink

    Nice, this is great documentation. I want to use this project as a remote entry system that would allow access to a specific tag.

    I don’t see in your code that you check for a unique identification once a tag is acquired. Wouldn’t that mitigate if not solve the radio interference issues? Instead of simply checking for the start/stop bytes, couldn’t you validate the code in between to eliminate false positives?

  5. Posted October 21, 2009 at 4:08 pm | Permalink

    @aerohead,

    The thing about the “interference” is that it is experienced by the Parallax reader and not the Arduino. What I mean is, the Parallax reader “sees” radio interference and thinks it is a valid code, it then forms a valid packet with a proper start and stop byte but a random 10 byte UniqueID in the middle and happily sends it to the Arduino. This code could be any number, even a valid RFID tag in your system, although this is highly unlikely for a 10 byte tag. But, as far as your Arduino knows, once it comes in, it is a valid code.

    You do bring up a good point if I am reading that correctly. We are assuming that a tag is going to be compared with a stored tag at some point, or likely checked against multiple tags. If you do the tag comparison right after getRFIDTag() and it matches a tag, then it is valid? Maybe, maybe not. As the number of tags grow that you are checking against, the higher the chances are that a junk tag will match a real tag, although minutely higher. This risk can also be compounded when you are in an environment with a lot of interference in the reader’s spectrum. For most cases though, this scenario is small enough to ignore. But checking the tag this way is more reliable and the added time is almost unnoticeable to the user.

    Implementing the isCodeValid() function depends on your use case. If you are using it as authentication to something important that is constantly running, like your house or car, I would suggest taking as much precaution as possible. Another thing it helps you do is distinguish the difference from when someone or something is denied access and when there is just noise, this distinction may be important to your project.

  6. Chris
    Posted October 21, 2009 at 6:41 pm | Permalink

    I just picked up a parallax RFID reader from my local RadioShack today (thanks for the tip!). Came with a credit card form-factor tag and a circular tag.

    I have the revision B version of the parallax reader and I’m wondering if something isn’t different about implementation. I copied the code verbatim from your page and it’s not reading a single tag. Serial is working because I get “TAG: ” back but its always blank when using no isCodeValid regardless of the presence of a card.

    When using isCodeValid, it always comes back believing the code is not valid (even without the presence of a tag) thus triggering the interference message printed to serial.

  7. Posted October 22, 2009 at 10:54 am | Permalink

    @Chris

    I can’t say for sure what your problem is. I would say first double check you connections, read the manual for your version [probably isn't any different than others] and make sure there have not been any changes, start tearing out code [like isCodeValid() first] and see if that changes anything.

    My best guess is that it may have something to do with the way you are printing the tags. I don’t see why you would be printing “Tag” if it didn’t actually read one. Note that I used this function:

    void sendCode() {
        Serial.print("TAG:");  
        for(int i=0; i<CODE_LEN; i++) {
          Serial.print(tag[i]); 
        }
        Serial.println(); 
    }

    to print the tag b/c trying to use this gave me problems:

    void sendCode() {
        Serial.print("TAG:");  
        Serial.println(tag); 
    }

    So maybe try the second function?

    I can only guess what the problem is. If you figure it out, please report it back here in case anyone else has the same issues.

  8. Chris
    Posted October 22, 2009 at 7:21 pm | Permalink

    I’ve been doing some debugging.

    Checked and rechecked connections. They’re correct.

    Swapped out jumpers with 20 gauge solid core in case one was bad.

    Included the wallwart for additional power to the arduino.

    I’ve tried the methods mentioned in the Arduino playground – no dice.

    Software serial doesn’t even enable the device (again, I’ve checked connections).

    Using your code:

    RFID VCC -> Arduino 5V
    RFID Enable -> Arduino digital pin 2
    RFID SOUT -> Arduino RX digital pin 0
    RFID GND -> Arduino GND

    Standard code
    My serial console is 2400bps and receives text fine from the Arduino. The RFID reader just flashes red and occasionally green while printing the noise line.

    Debugging
    It apparently doesn’t have a stable read on whether serial is available or not. I had it printing from inside the loop that is supposed to wait for a tag to be in range (ie: just loop doing nothing while Serial is not available) but it seems to think there is constant noise coming in somehow and jumping out of there. I tried printing the value returned by “Serial.available()” typecasted as an int to Serial. It prints nothing. Same with the tag code – no matter where I print it in the sketch, it never prints anything – not even junk characters after it has supposedly read data.

    So it doesn’t appear to be real interference.

    Maybe my reader is borked? Doesn’t seem like SOUT is producing anything.

  9. Chris
    Posted October 23, 2009 at 1:25 pm | Permalink

    Borked reader indeed. Returned it to RadioShack today and got a new one. Working flawlessly. Sorry to spam your comments :)

  10. Posted October 23, 2009 at 1:50 pm | Permalink

    @Chris

    LOL :) No problem. Glad you got it resolved.

    I wonder what happened to it? Seems weird. Maybe there was a short or a firmware problem of some kind.

    If you need help on your project don’t hesitate on contacting us. My email is ben [at] gumobolabs {dot} org .

  11. Jasper
    Posted October 31, 2009 at 4:18 pm | Permalink

    Thank you very much for your great, after searching the web for a long time, this was the code which actually read out the tags i had, but i am still trying to store the four tags in the EEPROM memory, since i am a real newbie to arduino, can you maybe tell me how to store these tag id’s?

    The idea is also to give this id tag’s their own Color as an output, this put through an RGB led.

    Well i hope you can help me, thanks in advance for your help and your fantastic code,

    Greetings

    Jasper

  12. Posted November 2, 2009 at 1:11 pm | Permalink

    Hey Jasper,

    Sure thing, check back here tonight. I will post append it to the post.

  13. Posted November 2, 2009 at 7:43 pm | Permalink

    Okay, I am not testing any of this code and it is not at all efficient but this should help you get the basic idea:

    The EEPROM is like a 512 byte array that persists in memory even if the Arduino is turned off or restarted. First thing you need to do is include the library to access it:

    #include <EEPROM.h>

    Then from there you can use:

    byte b = EEPROM.read(int address);
    //and
    EEPROM.write(int address, byte value);

    Alright, now to store and read keys, we need to abstract out a few things. We need to define a ‘key_address’. This number will correspond to the order in which you store a key. We also need to persists the number of keys we have stored in memory, there is probably a better way to do this but this should work:

     
    /**
     * +We are saving address 511 [last address in memory]
     * to store how many keys are in memory. 
     * +Call this in setup() with b=0; [setNumKeys(0);]
     */
    void setNumKeys(byte b) {
       EEPROM.write(511, b);
    } 
     
    byte getNumKeys() {
       return EEPROM.read(511);
    }
     
    //considering we are using code in above post
    void addKey() {
       byte num_keys = getNumKeys();
        // get the real address of the key in memory
       byte real_address = CODE_LEN*num_keys;
      // store the current tag there 
       for(int i = 0; i < CODE_LEN; i++) {
           EEPROM.write(real_address+i, tag[i]);
       }
       //increment the number of keys
       setNumKeys(num_keys+1);
    }
     
    // to get the first key, call getKey(0) etc.
    // could use pointer for storage here
    void getKey(int key_address, byte[] storage) {
        //get real address
        byte real_address = CODE_LEN*key_address;
        for(int i = 0; i < CODE_LEN; i++) {
            storage[i] = EEPROM.read(real_address+i);
        }
    }
     
    //clears memory out if needed, replace 0 with whatever
    void clearEEPROM() {
      for (int i = 0; i < 512; i++) EEPROM.write(i, 0); 
    }

    You may also want to see if the current key is in memory, this may work:

     
    /**
     * Checks the keys in EEPROM to see if current key [tag] matches a valid key.
     */
    boolean currentKeyInMemory() {
      for(int key_index=CODE_LEN; key_index<=getNumKeys(); key_index+=CODE_LEN) {
        if(compareKeys(key_index)) return true;      // found a match
      }
      return false;  // no matches
    }
     
    /**
     * Compares one key with current key.
     */
    boolean compareKeys(int key_index) {
      for(int j=0; j<CODE_LEN; j++) {
          if(EEPROM.read(j+key_index) != tag[j]) return false;  // not a match  
      }  
      return true;   // all must have gone well
    }

    As for your RGB stuff, maybe you can expand it out to handle 3 extra bytes, like so :

     
    void addKeyThing(byte r, byte g, byte b) {
       byte num_keys = getNumKeys();
        // get the real address of the key in memory
       byte real_address = (CODE_LEN+3)*num_keys;
      // store the current tag there
       while(real_address < real_address+CODE_LEN) {
           real_address++;
           EEPROM.write(real_address, tag[real_address]);
       }
       EEPROM.write(real_address++, r);
       EEPROM.write(real_address++, g);
       EEPROM.write(real_address++, b);
       //increment the number of keys
       setNumKeys(num_keys+1);
    }
     
    // to get the first key, call getKey(0) etc.
    //could use pointer for storage[] here
    void getKeyThing(int key_address, byte[] storage) {
        //storage.length == CODE_LEN+3;
        //get real address
        byte real_address = (CODE_LEN+3)*key_address;
        for(int i = 0; i < CODE_LEN; i++) {
            storage[i] = EEPROM.read(real_address+i);
        }
        int color_index = CODE_LEN;
        storage[color_index] = EEPROM.read(real_address+color_index);
        storage[color_index] = EEPROM.read(real_address+color_index++);
        storage[color_index] = EEPROM.read(real_address+color_index++)
    }

    Like I said, I don’t really have time to test this or even compile it and I am sure there is plenty wrong with it so let me know how this works for you.

  14. LUKE
    Posted November 5, 2009 at 9:02 pm | Permalink

    First of all…This is an awesome write up. I’m very much like Jasper, trying to use your original code with a write to the EEPROM. The order of operations that I’m trying to accomplish is this (setup has 2 buttons and 2 LEDs): check if Button1 is pressed, if yes – store the tag value presented to the reader and flash both LEDs when complete, check if Button2 is pressed, if yes – read tag value and compare against a single value stored and light LED1 if a match or light LED2 if it is not a match. If I want to get fancy I could say pressing BOTH Button1 and Button2 for 5 seconds will clear the memory.

    Try as I might, I can’t get the code you posted to adapt to this setup. The code above works and I can get it to print to the serial monitor, but I can’t figure out this EEPROM stuff. Can anyone point me to an analogous example on the web? Thanks in advance.

  15. Posted November 19, 2009 at 1:59 pm | Permalink

    @LUKE,

    yeah, sorry that EEPROM code is so messy and probably buggy. If you are only comparing against one key, it should be a lot easier. All you need are 2 functions, writecurrentkey and comparecurrentkey. You can just assume that your one key is stored at the first 10 bytes of the EEPROM Something like this I guess:

     
    /**
     *  Write the key in 'tag' array into the EEPROM
     */
    void storeCurrentKey() {
       for(int i=0; i<CODE_LEN; i++) {
          EEPROM.write(i, tag[i]);
       }
    }
     
    /**
     * Compare the key currently in 'tag' array with the one we have stored
     */
    boolean compareCurrentKey() {
       for(int i=0; i<CODE_LEN; i++) {
          if(EEPROM.read(i) != tag[i]) return false;  // not a match  
       }
       return true;  //if we got here, it must be the same key that is stored
    }
  16. Posted January 21, 2010 at 6:32 pm | Permalink

    this is rad!!! i am excited to hear your presentation at ignitenola!

  17. Posted December 19, 2010 at 9:37 am | Permalink

    Fantastic write-up! I bought a couple of these readers at RS a few months ago on clearance and finally got around to hooking them up and trying your code. It works perfectly. Now I just have to decide what I want to control with them. Thanks for posting this, I would never have been able to use these without it.

  18. Sarah
    Posted January 3, 2011 at 5:02 pm | Permalink

    Hi,

    I was just working on a project that uses an RFID reader but different from the Parallax. We are having trouble interfacing the reader with the Arduino. We are still using the serial ports however we’re wondering if the when the Arduino receives the info from the reader does it take into account the start and stop bit and what does Arduino define to be the start and stop bit?
    Any help will be greatly appreciated.

    Thanks,

    Sarah

  19. d
    Posted January 17, 2011 at 1:31 pm | Permalink

    Hi,

    I’m trying the Read/Write module from Parallax with the Arduino UNO.
    I just want to read the tags ID can somebody help me. I have the wires correct connected to the Arduino board. and the red LED are on. Im trying this code but dont get the tag ID.

    #include

    //Reader/Writer Commands
    #define RFID_READ 0×01

    #define rxPin 8
    #define txPin 6

    //Error Codes
    #define ERR_OK 0×01
    #define ERR_LIW 0×02
    #define ERR_NAK 0×03
    #define ERR_NAK_OLDPW 0×04
    #define ERR_NAK_NEWPW 0×05
    #define ERR_LIW_NEWPW 0×06
    #define ERR_PARITY 0×07

    NewSoftSerial mySerial(rxPin, txPin);
    int enable = 6;
    int buffer = 0;

    void setup() {
    Serial.begin(9600);
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);
    mySerial.begin(9600);
    Serial.println(“RFID Read/Write Test”);

    }

    void loop() {
    mySerial.print(“!RW”);
    mySerial.print(RFID_READ, BYTE);
    mySerial.print(32, DEC);
    if(ERR_OK){
    Serial.println(“Ok”);
    Serial.println(“RFID Data:”);
    Serial.print(mySerial.read(), HEX);
    Serial.print(mySerial.read(), HEX);
    Serial.print(mySerial.read(), HEX);
    Serial.println(mySerial.read(), HEX);
    Serial.println(ERR_OK, HEX);
    }

    else {
    Serial.println(“Not Ok”);
    }

    delay(2000);

    }

    Thanks for the help,

  20. arnaud
    Posted June 7, 2011 at 9:07 am | Permalink

    Hi
    Thanks a lot for this code and detailed explanations :)

    Do you think it would be possible to plug 2 of these parallax reader on the board and read their tags as well ?

  21. arnaud
    Posted June 7, 2011 at 9:21 am | Permalink

    i suppose it works by connecting a second reader to the DIgital pin 3 of the Arduino, and enabling readers one by one. Which means modifying the present code in order to pass the id of the reader as an argument to enableRFID()

    Has anyone tried ?


    #define RFID0_ENABLE 2 //pin connected to ENABLE
    #define RFID1_ENABLE 3

    void enableRFID(RFID_ENABLE) {
    digitalWrite(RFID_ENABLE, LOW);
    }

    void disableRFID(RFID_ENABLE) {
    digitalWrite(RFID_ENABLE, HIGH);
    }

  22. Allen Mosley
    Posted July 17, 2011 at 11:52 pm | Permalink

    Hi, I’m new to using the Arduino and I was thinking about using a RFID reader on my robot. I did some searching and came across this posting. It’s great by the way!

    I just wanted to ask a question – which RFID reader do you think is better, the Parallax one that you used or the ID-12 or ID-20 (flat black squares)? Sparkfun sells them and there is a posting about using them also.

    Thanks,

    Allen

  23. Posted November 9, 2011 at 5:41 pm | Permalink

    I have posted a C# app for the USB version of the Parallax RFID reader. Refer to
    http://wb9coy.com/Projects.html

  24. Steve
    Posted January 22, 2012 at 9:12 pm | Permalink

    First of all, thanks SO MUCH for this blog entry.. Having someone else’s code helped me troubleshoot what I’ve been working on for months (on and off)… I was getting NOWHERE with it.. I had NEVER gotten even ONE CHARACTER out of this darned thing, using an Arduino or an MBED micro.. Then, I saw Chris’ post about the dead reader, and I decided to try a different reader, and it worked the FIRST TIME.. Imagine that.. and I had several spare readers on the bench and never tried another one, because “why would this brand new reader be bad!?” I guess Parallax’s QC on this device isn’t that great…

    Thanks so much! Hopefully my garage door will be open-able by RFID sometime this week!!

    -Steve

  25. alexkulet
    Posted February 24, 2012 at 2:25 am | Permalink

    guy day everyone… i am having a problem with interfacing b/n arduino to rfid read/write module….i try several codes but nothings happen… the red led lights up but no response when the tag is swipe at the reader… icheck the connection properly to make sure that nothings leak…. but seems no luck…. i tried code from this website… but still the no response… i wondering about the dead rfid …i dont know how to check if my rfid is working properly… does any body here can help me…???

  26. Mufaddal raja
    Posted February 25, 2012 at 2:08 am | Permalink

    I have rfid reader (125khz) in which serial port is given ,if i connect my rfid reader to aruino serialy than how can i connect my arduino with pc. i cant find pin description of my reader (i purchase it from vegarobokit.com) need help and i want my tag info which is display on serial monitor of arduino vl display on lcd ..need help

  27. Posted March 16, 2012 at 7:11 pm | Permalink

    I apologize for posting to such an old writeup but I am going to do it anyway.

    I uploaded your code but I had two problems.

    1) After every successful read I get a “Got Some Noise” comment.
    2) I frequently get “TAG:TAG:TAG:TAG:” indicating that though it has no valid data it is cycling 4 times before it clears. I believe this is the problem you described where the stop byte doesn’t clear the buffer and just hangs there.

    I realized that both of these problems were likely caused by the serial.flush() function not working properly. Apparently in Arduino 1.0 serial.flush() was repurposed.

    To regain the functionality replace, Serial.flush(); with while(Serial.available()>0)
    {
    Serial.read();
    }

  28. Posted February 28, 2013 at 6:16 am | Permalink

    Greate article. Keep posting such kind of info on your
    blog. Im really impressed by your blog.
    Hello there, You’ve performed a great job. I’ll definitely
    digg it and for my part suggest to my friends. I am sure they will be benefited from this website.

  29. Posted May 14, 2013 at 9:59 pm | Permalink

    Thanks for some other great post. The place else
    may just anyone get that type of information in such
    a perfect manner of writing? I’ve a presentation subsequent week, and I’m on the look for
    such info.

    Also visit my web-site: Unknown

  30. Posted May 15, 2013 at 4:20 pm | Permalink

    I am really grateful to the owner of this web site who has shared this wonderful
    paragraph at at this time.

  31. Posted May 19, 2013 at 12:01 pm | Permalink

    Hey, I think your website might be having browser compatibility issues.

    When I look at your blog in Safari, it looks fine but when
    opening in Internet Explorer, it has some overlapping.
    I just wanted to give you a quick heads up! Other then that,
    wonderful blog!

  32. Posted June 2, 2013 at 2:33 am | Permalink

    I am not sure where you’re getting your info, but great topic. I needs to spend some time learning much more or understanding more. Thanks for magnificent info I was looking for this information for my mission.

    Also visit my blog post; Terri

  33. Posted June 4, 2013 at 12:22 pm | Permalink

    Hey,

    With your code I still got a bunch of empty tag reads (isCodeValid would return true even if tag[] was empty). I also added null termination (”) after the tag to make it a bit easier to deal with, and integrated isCodeValid() into getRFIDTag() to make code a bit cleaner to use.

    #define VALIDATE_TAG 1 //should we validate tag?
    #define VALIDATE_LENGTH 200 //maximum reads b/w tag read and validate
    #define START_BYTE 0x0A
    #define STOP_BYTE 0x0D

    char tag[CODE_LEN+1] = “”;

    boolean isCodeValid();

    void enableRFID() {
    digitalWrite(RFID_ENABLE, LOW);
    }

    void disableRFID() {
    digitalWrite(RFID_ENABLE, HIGH);
    }

    /**
    * Blocking function, waits for and gets the RFID tag.
    */
    boolean getRFIDTag() {
    byte next_byte;

    if(Serial.available() <= 0) return false;

    if((next_byte = Serial.read()) == START_BYTE) {
    byte bytesread = 0;
    while(bytesread 0) { //wait for the next byte
    if((next_byte = Serial.read()) == STOP_BYTE) break;
    tag[bytesread++] = next_byte;
    tag[bytesread+1] = ”;
    }
    }

    boolean codeValid = isCodeValid();
    if(isCodeValid()) return true;
    else {
    clearCode();
    return false;
    }
    } else return false;
    }

    /**
    * Waits for the next incoming tag to see if it matches
    * the current tag.
    */
    boolean isCodeValid() {
    byte next_byte;
    int count = 0;
    while (Serial.available() VALIDATE_LENGTH) return false;
    }
    Serial.read(); //throw away extra STOP_BYTE
    if ((next_byte = Serial.read()) == START_BYTE) {
    byte bytes_read = 0;
    while (bytes_read
    0) { //wait for the next byte
    if ((next_byte = Serial.read()) == STOP_BYTE) break;
    if (tag[bytes_read++] != next_byte) return false;
    }
    }
    return true;
    }
    return false;
    }

    /**
    * Clears out the memory space for the tag to 0s.
    */
    void clearCode() {
    for(int i=0; i<CODE_LEN; i++) {
    tag[i] = 0;
    }
    }

  34. Posted June 7, 2013 at 4:27 pm | Permalink

    Heya i’m for the first time here. I found this board and I find It truly useful & it helped me out much. I hope to give something back and help others like you helped me.

    Feel free to surf to my website – Myrna

  35. Posted July 5, 2013 at 6:47 pm | Permalink

    Do you have any video of that? I’d care to find out more details.

    my web blog: %anchor_text%

  36. Posted November 16, 2013 at 7:08 pm | Permalink

    You’re so awesome! I don’t believe I’ve read anything like this
    before. So great to find another person with original thoughts on this topic.
    Really.. thanks for starting this up. This site is one thing that is required on the
    internet, someone with a little originality!

  37. Posted November 21, 2013 at 6:01 pm | Permalink

    hi i need help for a final project study which is based on RFID with microcontroller pic f MikroC …. and thai.hajjajnk you in advance

  38. Posted January 12, 2014 at 12:38 pm | Permalink

    Sweet blog! I found it while browsing on Yahoo News.

    Do you have any tips on how to get listed in Yahoo News?

    I’ve been trying for a while but I never seem to get there!

    Thanks

  39. Posted January 17, 2014 at 12:38 am | Permalink

    Going green is the new thing but is something here to stay,
    so why not get a head start with your light bulb of an idea.
    Light Emitting Diodes, more often pronounced as LED light bulbs, are small size, solid light bulbs that are highly energy efficient and are vastly replacing
    standard Incandescent bulbs. The capacity of circuits in a house can
    usually be determined by looking at the rating of circuit breakers
    or fuses used.

  40. Posted March 11, 2014 at 10:01 pm | Permalink

    It’s planting a seed that directs their thinking on this issue.
    Writing an employment verification letter for visa is no big deal given all
    the specifications mentioned above. The fact that a new nurse almost always has to
    start out on night shift means you would make even more.

  41. Posted March 12, 2014 at 2:21 am | Permalink

    The green-lighted projects begin casting these pilots early because they want the best
    actors – first. Basically that means virtually all
    our time is focused on that individual superstar.
    A tale, well told is certainly bound to attract movie lovers.

8 Trackbacks

  1. By links for 2010-02-14 on February 14, 2010 at 11:30 am

    [...] Parallax RFID Reader Arduino I'm working on project with this RFID reader. This article is a great starting point for anyone doing the same. (tags: howto hardware tutorials electronics code arduino projects parallax rfid) Share and Enjoy: [...]

  2. By RFID « Ian Hurley's Blog on April 23, 2010 at 7:52 am
  3. By Custom SL-1210 Cabinet: Part 3.1 on April 27, 2010 at 7:29 pm

    [...] with and there’s a lot of documentation on how to use it with Arduinos (including this great tutorial). The sticker tags were supposed to have an adhesive side but either I can’t figure it out or [...]

  4. [...]  Parallax RFID ReaderArduino [...]

  5. [...] mon code d’exemple je me suis servi de ce site : http://www.gumbolabs.org/2009/10/17/parallax-rfid-reader-arduino/ Pour faire une version newsoftserial plus [...]

  6. By new sites here « Bilnir on March 20, 2012 at 2:27 pm

    [...] just recently wrote an article at the Gumbo Labs blog on interfacing to the Parallax RFID reader. Here is the final code if you are only looking for [...]

  7. By Meta 2013 – Interface on November 29, 2012 at 12:49 pm
  8. By It’s over! Now what? | not {that} geeky on April 8, 2013 at 4:16 am

    [...] RFID to Arduino (Code) | Using RFID Parallax | [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">