AVR/Arduino RFID Reader With UART Code in C
Intro: 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.
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:
You could also connect your favorite LCD screen in lieu of sending tag data via RS232.
- 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
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:
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.
The RFID reader has 4 connections:
- Vcc
- ENABLE
- OUT
- Gnd
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 FormatThe 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:
These are the three primary steps.
Know when a tag has been submittedI 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
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:
Parse RS232 OutputThe 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.
Display Your TagIn 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.
RFID Reader Data FormatThe 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 submittedI 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.
Parse RS232 OutputThe 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 TagIn 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!
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!
26 Comments
Aishwaryat3 7 years ago
Hey, I want to know about UART & I2C rfid interfacing. Can you please help?
alichaud 7 years ago
noob question.. i have AVR dragon would that some how work with Arduino RFID Reader (rc552 Module)??
JerodC2 7 years ago
What about rfids installed within your organism
mohamednehmar 7 years ago
i need to use tag rfid reader with an fpga and the midleware pc
kareem.eliraky 8 years ago
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
jeff-o 14 years ago
nevdull 14 years ago
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... ;)
adnanp3 8 years ago
I have a reader writer module with active tag that operate at 2.45 GHz and has a track range up 50 meters
jeff-o 14 years ago
nevdull 14 years ago
nate4alpha 14 years ago
nevdull 14 years ago
scottyb4996 13 years ago
adnanp3 8 years ago
Hi canrobo also nee that code
candrobo 8 years ago
Did you find a way would love to do this project in the IDE
nevdull 8 years ago
Hi @candrobo,
The best way to get non-original-AVR-studio projects to load in AVR studio with intellisence and all I've found it easiest to use AVR studio IDE to create a blank Makefile project. I then unpack my source into that directory and add it all at once. From then on, you can add/edit/delete all your source in the IDE if you prefer that.
nevdull 13 years ago
adnanp3 8 years ago
Hi! nevdull i need arduino code for rfid based tracking system, please if you can provide reply me or sent me a link from where i can easily find it.
Thank you
candrobo 8 years ago
Where is the information from the RFID tag stored or displayed
nevdull 8 years ago
Stored: inside the RFID chip, possibly in a series of flip/flops or diode memory since it won't change.
Displayed: After I read the RFID card, I sent the RFID tag to the USART to display on the console. Look at the picture above and you can see my Serial console running and receiving RFID tag data.