AVR/Arduino RFID Reader with UART Code in C

RFID is the craze, found everywhere – from inventory systems to badge ID systems. If you’ve ever been to a department store and walked through those metal-detector-looking things at the entrace/exit points, then you’ve seen RFID.
There are several places to find good information on setting up RFID, and this instructable focuses on installing the Parallax RFID reader (Serial TTL) on an AVR, with emphasis on the C code needed to read the serial input.
The code is in C and doesn’t use any external libraries. In fact, it speaks 2400 baud directly without the use of a UART by synchronizing to the RFID reader’s baud rate and reading the digital pin that it’s connected to. Excited? Me too.

Step 1 Get the Goods:

You’ll need the following list of parts:

    • RFID Reader (Parallax #28140 $39.99)
    • RFID tag ( Parallax #32397 $0.99)
    • AVR or Arduino clone (if you use a stock AVR, you’ll also need a max232, 5 x 1uF capacitors, and a DE9 connector)
    • Solderless breadboard

Optional

  • 4 position header
  • Wire

(and the max232 etc for communication of the tag information)
You could also connect your favorite LCD screen in lieu of sending tag data via RS232.

Step 2: Connect the parts

connect parts
The hardware side of things is pretty easy. Instead of plonking my RFID reader directly into my breadboard I opted to make a quick cable so I could move the RFID reader around a little bit better. For that, I just cut off 4 positions from a female socket header strip I had lying about and soldered on three wires. Electrical tape completed the ghetto connector.
The RFID reader has 4 connections:

    • Vcc
    • ENABLE
    • OUT
    • Gnd

As you probably guessed it, connect Vcc to +5V and Gnd to ground. Because the RFID reader consumes so much power, you can bang the ENABLE pin to turn it off and on at various intervals. I simply chose to keep it on. Because it’s inverted, you pull it LOW to activate it. Alternatively, you can connect it to ground. I connected it to PIND3 to give me options of enabling/disabling if I decided to. The OUT pin is where the reader sends its serial data after it reads a tag. I connected it to PIND2.
Note, in the Parallax Universe, red means go. That is, a green LED means the unit is inactive and idle, while a red LED means the unit is active. *shrug* Go figure.

Step 3: Write the Code

To read the data from the RFID reader, you have to know when a tag has been submitted, pull the data off of the serial port, then send it somewhere.

RFID Reader Data Format

The Parallax RFID reader sends data at a fixed, glacial pace of 2400 baud. An RFID tag is 10 bytes. In order to allow for error detection/correction, since the reader could be set off from random noise, the 10-byte RFID is bounded by a start and stop sentinel. The start sentinel is line feed (0x0A) and the stop sentinel is carriage return (0x0D). It looks like this:
[Start Sentinel |Byte 1|Byte 2|Byte 3|Byte 4|Byte 5|Byte 6|Byte 7|Byte 8|Byte 9|Byte 10| Stop Sentinel]
These are the three primary steps.

Know when a tag has been submitted

I used a Pin Change Interrupt on the AVR that notifies the firmware that a change has occurred on a monitored pin. Configuring the AVR for this is easy and requires setting the flag, telling the MCU which pin you want to monitor, and setting the global interrupt bit.
Configure PCINT
BSET(PCICR,PCIE2); // pin change interrupt control register pcie2 BSET(PCMSK2,PCINT18); // enable pin change interrupt for PCINT18 (PD2) BSET(SREG,7); // Set SREG I-bit
Write your interrupt service routine
You want to keep your ISR short so in my interrupt vector I read the entire byte, bit by bit, and store the byte in a global volatile character array. I do the following at each interrupt:

  • Check to ensure I’m on a start bit
  • Center the timing onto the middle pulse at 2400 baud (the speed of the RFID reader)
  • Skip the start bit and pause to the middle of the next bit
  • Read each bit into an unsigned integer
  • When I’ve got 8 bits, put the byte into a character array
  • When I’ve collected 12 bytes, let the MCU know the tag has been read for error detection.

I modified SoftSerial code from Mikal Hart who modified code from David Mellis for the experimentally determined delays in the serial routines.

Parse RS232 Output

The PCINT routine contains the code for reading the RS232 output from the RFID reader.
When I’ve gotten 12 bytes (10-byte RFID plus sentinels) I set bDataReady to 1 and let the main loop process the data and display it.
// this is the interrupt handlerISR(PCINT2_vect){ if (BCHK(PIND,RFID_IN)) // Start bit goes low return; uint8_t bit = 0; TunedDelay(CENTER_DELAY); // Center on start bit for (uint8_t x = 0; x < 8; x++) { TunedDelay(INTRABIT_DELAY); // skip a bit, brother... if (BCHK(PIND,RFID_IN)) BSET(bit,x); else BCLR(bit,x); } TunedDelay(INTRABIT_DELAY); // skip stop bit RFID_tag[rxIdx] = bit; ++rxIdx; if (rxIdx == 12) bDataReady = 1;}

Display Your Tag

In the main(), during the for(ever) loop, I check to see if bDataReady has been set, signalling that the entire RFID structure has been sent. I then check to see if it’s a valid tag (ie start and stop characters are 0x0A and 0x0D, respectively), and if so, I send it out my RS232 connection.
for (;;){ if (bDataReady) {#ifdef __DEBUG__ USART_tx_S("Start byte: "); USART_tx_S(itoa(RFID_tag[0],&ibuff[0],16)); ibuff[0] = 0; ibuff[1] = 0; USART_tx_S("\nStop byte: "); USART_tx_S(itoa(RFID_tag[11],&ibuff[0],16));#endif if ( ValidTag() ) { USART_tx_S("\nRFID Tag: "); for(uint8_t x = 1; x < 11; x++) { USART_tx_S(itoa(RFID_tag[x],ibuff,16)); if (x != 10) USART_tx(':'); } USART_tx_S("\n"); } rxIdx = 0; bDataReady = 0; }}

Step 4: Code and Farewell

This page contains a zip file with the relevant code. It was written in AVR Studio 4.16. If you use programmer’s notepad, eclipse, or vi (or something else) you’ll need to copy a trusted Makefile into the directory and add these files to the source line.
Also note, the timing for the serial reading section is based on a 16MHz MCU. If you are running at a different clock frequency, you will need to experimentally determine the tuned delays to center on the baud rate pulses.
I hope this instructable helped you in some way. If you have any suggestions on how it could be improved don’t hesitate to let me know!
For more details, click: AVR/Arduino RFID Reader with UART Code in C


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top