RFID cards are commonly used for access control and bus/train tickets. They are convenient because no direct contact is required to transfer information to and from the card. The card itself is powered by the RFID reader, so there is no battery to change.
For my experiments, I'm using a HID ISOProx card. These cards are the simplest of all RFID cards as they only stores a single serial number and uses no encryption. The carrier frequency is 125KHz.
The first step is to see if I can make a very simple reader. I know the RFID cards is powered by the magnetic field emitted by the RFID reader. The RFID tags transfers information back to the reader by loading the magnetic field, which cause the RFID reader to sense the change in load.
The most common design for RFID reader is to use a series resonate circuit. This consists of a single inductor and a capacitor excited by a low impedance voltage source. If the Q of the circuit is high enough, the voltage at the sampling point will exceed that of the supplied voltage. When the RFID sends a one by loading the magnetic field, this causes the Q of the circuit to drop. The result is a in small change in voltage at the sampling point.
I created a simple reader by finding a coil in my junk pile and a pile of capacitors. Using a function
generator as the signal source and oscilloscope attached at the sampling point, I can turn the
frequency on the function generator until I find the resonant point of the circuit. I continue to swap the capacitor in this circuit to find the resonant frequency I'm looking for. This
frequency is equal to:
For some reason, I confused my self and started the design with 150kHz in mind instead of 125kHz. The RFID tags responds just fine at this higher frequency, so I kept the design as is since I'm too lazy to go back and redesign the entire circuit.
With this simple setup, I manage to see that the RFID tag changes the loading either 4 or 5 carrier
frequency cycle. Since the signal should be AC with no DC signal, I assume the transmitted data
is at a frequency of 150kHz / 8 = 18.75kHz or 150kHz / 10 = 15kHz. This is the point I found some
really useful website that contain some nice information on RFIDs.
The tag seems to encode the data using FSK. The two frequencies are used to represent a 1 and a 0.
With these information in hand, I go ahead and start designing my own antenna inductor. Since I'm
still stuck with the idea of using 150kHz carrier frequency, I did the calculation and figured out
that I need 160uH of inductance with 10nF of capacitor. I use the following equation to estimate
the number of turns I need for the coil:
Where x, y is the length and width of the coil, h is the height and b is the thickness of the conducting part of the coil. I use x=y=6cm, h=1cm and b=0.3cm. The number turns out to be 34. I wrap the coil on a paper box I found, which is how I extracted the x and y. The finished coil is extracted and secured with tape.
To fine tune the resonant frequency of the entire system, I decided to just play with the capacitance. Using the function generator to sweep for the peak output observed with the scope, I played with the size of the capacitor until the peak response of the resonant circuit is at 150kHz. The capacitor that did the trick is 0.056uF. Unless my capacitor has a larger capacitance than it's marking, the coil I made must have a inductance higher than 160uH.
The next stage is to design the analog circuit. I use the trusty TL062 as my OPAMP of choice (Since I got a pile of these little OPAMP). The frequency involved in this project is quite low, so the low frequency performance of this OPAMP should not be an issue. Since I'm always lazy to put a complex circuit together, I elected to use the simplest design I can come up with. So the idea is to use a simple diode detector. The detected voltage goes through the first OP amp configured as a inverting amplifier with low pass frequency response. This will remove bulk of the carrier frequency. The next stage of the analog circuit is to extract the FSK signal. The simplest circuit I come up with is a resonant band pass circuit with a center frequency around 17kHz. This costs me one OPAMP only. The circuit is designed with SPICE, which the plot of the frequency response is shown at the end of the page.
The output of the bandpass signal is than feed directly into the PIC microprocessor. The processor I choose for this project is the good old trusty PIC16F628A. With an onchip comparator, I can feed the output from the OPAMP directly into the PIC and extract the digital signal.
The decoding of the FSK signal is done in software, which is really nice since there is no increase to BOM.
To decode the FSK signal, I implemented a subroutine that uses TMR0 to track the time past between the changes detected on the output of the onchip comparator. No interrupt is used, instead, the routine keeps looping until a change in state is detected. The loop that does the detection takes about three CPU cycle to run through, thus, depending on when the change occurred, there is an maximum error of 3 cycles.
Anyone who knows about the PIC hardware might ask why don't I use the onchip compare capture module. Unfortunately, I used the PWM module to generate the 150KHz carrier signal. The capture hardware shares resource with the PWM module, so only one function can be activated at a time.
To get a picture of how the FSK signal looks like after being digitized, I add a debug mode where
it will capture the number of CPU cycle taken between each change in incoming signal. Due to the
limitation of the onchip memory, only 80+64 data points is captured. This is not long enough to
decode the data, but is sufficient to paint a picture of how the signal looks like. Putting the
signal though the Open Office Calc to generate the following plot:
Debug mode output, right after the Duty cycle counter:
In this plot, the number on the Y axes is the time taken(in CPU cycles) between each change of state on the incoming signal. I decided 85 is a fairly good number to decide if the incoming data is a zero or a one. Later on, I decided to change the decoding routine to count the time taken between each rising edge in the signal (Since the signal has zero DC component, and this will save me more memory by recoding 1 bit of data instead of 2). Thus, the constant used in the PIC firmware end up using 170 (2 x 85).
The decoded sequence of data looks like:
0000000000000000000000001111111111111111000001111110000001111100000011111000000111111 ... ... 111111000001111110000001111100000011111111110000000000001111111111100000011111000000000000 ... 0000001111110000001111111111000000111111000000000000000000000000111111111111111100000You can see the data starts with a lot of zeros, following a quite a number of ones than the actual data. The entire sequence continue to repeat.
I know the signal is encoded with Manchester coding, so from the signal, I can make the following conclusion:
1. The signal starts with a sequence of zero larger than 20 zeros 2. The second sequence is always a string of ones lasting for at least 15 bits 3. Each bit lasts 10 to 12 zeros or ones 3. The bit is a zero if there is no change in signal state during the bit timeA quick picture can be drawn:
111111000001111110000001111100000011111111110000000000001111111111100000011111000000000000 -----------|-----------|----------|_________|___________|__________|----------|___________ 1 1 1 0 0 0 1 0With these rules in mind, I added the function to decode the data.
As a summary of how the entire system looks like, I put together this summary diagram:
Overall block diagram:
Currently, I set the Vcc to 10V, +5V is extracted from Vcc using a simple 78L05 voltage regulator. The Vref is set to half of logic voltage supply at 2.5V, this is accomplished using a simple resistor divider consists of two 4.7k resistor. Source Code:
Revision 1 May 1st, 2007 - Initial release
Revision 2 May 5st, 2007 - Revision 2
Auto start, triggered with pin PB7 set to high
Beeper support, output on pin 4
Full automatic card detect, use command 6
Go back to Main Page