AVR/Arduino RFID Reader With UART Code in C





Introduction: 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

  • 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

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
  • 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(&apos;:&apos;);            }           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!



  • Epilog Challenge 9

    Epilog Challenge 9
  • Sew Warm Contest 2018

    Sew Warm Contest 2018
  • Gluten Free Challenge

    Gluten Free Challenge

We have a be nice policy.
Please be positive and constructive.




Hey, I want to know about UART & I2C rfid interfacing. Can you please help?

noob question.. i have AVR dragon would that some how work with Arduino RFID Reader (rc552 Module)??

What about rfids installed within your organism

i need to use tag rfid reader with an fpga and the midleware pc

Hello I need to use parallax RFID Reader Serial with WiFi
module esp8266 and LCD using pic16f877a. every time I run the circuit the RFID
doesn’t work

Very cool. So what types of RFID tags can it read? Security badges? product tags?

Hey Jeff!
This reader can interrogate any passive 125 kHz transponder tag, which is in the low frequency range, as far as RFID tags these days go. Industrial-strength RFID is often in the 13.56 MHz and 868/928MHz bands, although there are some microwave tags and readers in the ~3 and ~6 GHz range. With it's 10-byte ID, it offers 240 unique combinations.

So far, the only tags I've read are the one's I've purchased to put on my dog and cat (it's a long story, really) and the range of detection is underwhelming (~ 4cm although the claim is closer to 10cm) although increasing current can increase the antenna's inductance, up to a point. If I could find some RFID tags from some books I'd try those to see if they might work. I use a magnetic card to get into my lab, but my brother uses an RFID badge system, so maybe I'll snag his belt fob and see if I can read that. I'd be more excited if I could *write* to them as well as read them. That would open up some interesting possibilities next to my magnetic card reader... ;)

I have a reader writer module with active tag that operate at 2.45 GHz and has a track range up 50 meters

Indeed it would! Some legit, some not so much... ;)

I did draw up initial plans when I first got the RFID reader to install it, along with a couple of motors and an AVR MCU, into a hand scanner that I had lying about, but with the dismal range I think anything I wanted to scan would have to just about be laying on it. Ah, grand hopes and best intentions dashed on the rocks of sober reality. I have been thinking that I might still reincarnate that hand scanner into something, yet, since I have two ultrasonic transceivers that are just dying to go into a fresnel lens to do 360 degree sonar scans. I'll have to see about that...lol.

scanner and junk.jpgscanner robot.jpg