everhack Stuff I've been messing with, or just thinking about.


AVR RFID Reader, part 6 – Successful Reads!


Even after reading up on Manchester encoding from a number of sources, and reading Beth Scott's reader code & comments, I still just couldn't quite understand how to do the decoding.

My biggest problem with the reader code from part 5 was that I was only detecting the lengths of the LOW periods, but not the HIGH periods, so I was only getting half the bits.

Secondly, after a hint from a RFID reader IC datasheet (http://www.125khz-rfid-reader.com/how-the-driver-works/how-the-driver-functions), I realized I also didn't have to muck about with detecting both rising and falling edges as various other literature indicated.

"Using a clever detection method the driver only needs to detect each rising edge to determine the preceeding bit states, reducing the interrupt burden on the main application. Also only detecting each rising edge removes issues of dealing with non perfect high and low widths within each cycle – being radio they are often not perfectly 50/50, but the overall bit frequency will be relatively accurate."

At this point, I was logging the timer value for each rising edge to the serial port so I can get a look at what exactly was being received. Just as a picture tells a thousand words this text file pointed me towards what to do next.

Here's a piece of the log where I've manually annotated the lows and highs to indicate short or long lows and highs. (0 is a short low, 00 is a long low, 000 is a "triple low," which occurs only in the tag header. 1s indicate the length of the highs similarly).

Basically, the lows are easy, they're always around 900-1000 'ticks' for a short, and around 1500-1600 for a long. A triple long low is around 2500.

The highs are a little trickier. Since the carrier is pulsed, we get a rising edge every time the carriers rises above the threshold value. These show up in the log as multiple entries around 150 ticks in duration. A "short high" gives about 4, a "long high" is about 8, and a "triple long high" (seen right after the leading 000) gives about 14 of them.

180:2585 000
194:153 111
195:919 0
199:152 1
200:1065 0
204:154 1
235:1671 00

One additional tricky part was figuring how to detect the end of a "high" period, since the event trigger only gives rising edges, meaning I don't know the High is done before I reach the end of the Low period immediately after. To solve this, I added an Overflow interrupt handler to my input capture timer, set to a length of 200. This ensures that the overflow interrupt will always fire as soon as "no more rising edges" are detected in a sequence.

A problem I'd been having all along at home had been viewing the received signal on my analog non-storage oscilloscope due to the inability to "pause" the display, or accurately trigger on the beginning of the tag signal.

However, this was solved once I was accurately able to detect the "3T low 3T high" tag header in my code. I enabled a second debug pin and toggle it on and off each time I detect that sequence. This now finally allows me to accurately view the received manchester bits on my scope.

I still didn't quite get the idea of reconstructing the data clock, but after finding this forum comment and having a long chat with Danny at the hackerspace, I finally had my decoding approach:


Basically, two things you need to do are to:
A) accurately determine where the message begins. Looking at the data, I realized there was a repeating 3T low followed by a 3T high. Since Manchester encoding forbids any high or low longer than 2T, this was clearly our header signal. Thus, the first rising edge after our 3T high marks the beginning of the actual data stream.
B) decode the 0s and 1s into the original data bits. In my case, the expanded representation of the "shorts" as 1 digit, and "longs" as two digits effectively reconstructs our clock signal, and lets us decode the stream by simply interpreting every received "01" as a data "0", and every "10" as a data "1".

Finally once you have the actual data bits, you have to convert them back to the card values, which for HID means the first 20 bits contain the "Manufacturer Code" (always constant), then 8 bits of "site code", and finally 16 bits of 'card code' and a trailing parity bit.

This is where the code stands right now. I can read both my badges pretty reliably, but the threshold voltage is still manually adjusted which limits the read distance to a very narrow range.

Next steps, I want to:
- implement a dynamic threshold voltage via PWM,
- display the decoded digits via LCD, or at least flash a LED on successful read.
- start spoofing the digits
- design a PCB and begin to package this thing

Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.