This time we’re hurtling through the layers of technology that make a graphics tablet (pen tablet) work, from operating systems politics to electromagnetic induction. I’ll be looking closely at two tablets, the Wacom Intuos Pro and Huion H610PRO, and going into a full teardown on the Huion.
Way back in 2008, I posted a writeup about using an AVR microcontroller as an RFID tag. Since then, it’s been great to see many people pick up this code and build their own DIY RFID tags.
In my original project, I was just interested in using an AVR as a way of emulating any tag protocol I wanted, even proprietary protocols like the HID cards that are so common for door entry. But a general purpose microcontroller really lends itself to making even more interesting tags. For example, imagine an action figure that has different poses which trigger microswitches that can be read by the AVR. It could report a different RFID code depending on which pose the action figure is in. This kind of very low-power physical computing is really interesting to me.
Trammell Hudson recently took a big step in this direction, in the name of creating a “multipass” card which could stay in his pocket and pretend to be any number of other cards. His original idea didn’t quite work out, due to limitations in the HID readers. But along the way, he created an optimized version of the AVRFID firmware which uses much less flash memory, and he ported it to C so that it can be more easily extended and modified.
He made this posible by very carefully choosing the instructions in the inner loops, creating a state machine that just barely fits within the available clock cycles:
One issue with programming HID Prox compatible cards is that the AVR’s RCALL and RET instructions are quite slow — 3 and 4 clocks respectively — so making a function call and returning from it requires seven clocks and would cause errors in the RF waveform. To get around this, Beth expanded all of the code inline to produce a single function that bit-bangs the coil loading with NOP‘s between each cycle. The 20-bit manufacturer ID (0x01002), 8-bit faciity code and 16-bit unique ID, all Manchester encoded, required 80 instructions per bit for a total of 3700 instructions out of the Tiny85′s maximum of 4096. Supporting 34-bit cards would not be possible with this design, much less multiple card IDs!
While RCALL/RET are out of the question, I noticed that IJMP is only 2 clocks. This means that the CPU can do an indirect jump to the value in the 16-bit Z register in enough time to be ready for the next FSK cycle. If we know where to go, that is… The LPM instruction takes three cycles to read a byte from flash into a register, which just barely fits during the idle time during a FSK baseband one. Loading the Z register for LPM takes at least two clocks (since it is really the two 8-bit registers r31:r30), which means the pgm_read_word() macro in avr/progmem.h won’t work. While the rest of the firmware is in mostly normal C, I resorted to writing assembly to interleave the coil toggling with the operations to determine the next output state and make the appropriate jump. If you want to follow along, the source for the RFID firmware is available in rfid/avrfid2.c.
His post covers a lot of ground, including how to connect an off-the-shelf HID card reader to a computer, and how to repeatedly program the AVR using a Bus Pirate.
This is just a messy first prototype, but I recently tried making an AVRFID tag on a substrate of duct tape. The first attempt involved:
- An upside-down strip of duct tape, as the base for everything else to stick atop
- 100 turns of AWG 40 magnet wire around a ~66mm diameter form, which I then haphazardly squished against the tape
- An ATtiny85 µC in the SOIC-8 package, programmed with the latest AVRFID firmware
- SMT 0.1 µF capacitor across the power pins
- SMT 1 nF capacitor in parallel with the coil, for tuning it to approximately 125 kHz
- Sealed with clear packing tape on the opposite side
It’s ugly, and I really want to try this experiment over again with a smaller IC package, like TSSOP-8. But the card works very well, and the read range is practically indistinguishable from a mass-produced RFID card. I tested this one using an official HID ProxPoint reader.
I’ve been busy, but once I have time to perfect this technique I’m hoping to write some instructions, as it’s a pretty quick and easy way to make a DIY RFID tag that’s actually in a convenient form-factor.
Experiments in RFID, continued…
Last time, I posted an ultra-simple “from scratch” RFID reader, which uses no application-specific components: just a Propeller microcontroller and a few passive components. This time, I tried the opposite: building an RFID tag using no application-specific parts.
Well, my solution is full of dirty tricks, but the results aren’t half bad. I used an Atmel AVR microcontroller (the ATtiny85) and a coil. That’s it. You can optionally add a couple of capacitors to improve performance with some types of coils, but with this method it’s possible to build a working RFID tag just by soldering a small inductor to an AVR chip:
The above prototype emulates an EM4102-style tag- a very popular style of low-frequency RFID tag which stores a 40-bit unique ID. I can read my bogus ID value (0x12345678AB) using Parallax’s RFID reader. Below is another prototype, with a larger coil and a couple of capacitors for added range and stability. It is programmed to emulate a HID prox card, a simple FSK-modulated tag with a 44-bit payload. I can read this card successfully with my garage door opener. This one is a little large to conveniently carry around, but a smaller AVR package should help.
So, the shiny electrical tape is beautiful, but how does this thing even work? The power pins on the microcontroller aren’t even connected!
As I said, this makes use of several dirty tricks:
- The coil actually powers the AVR through two of its I/O pins. Nearly every chip out there has clamping diodes on its I/O pins, which prevent voltages on that pin from rising above the chip’s supply voltage or sinking below ground. These diodes are useful for arresting static discharge.When you first hold the RFID tag up to a reader, the chip has no power- the supply voltage is zero. When the coil starts to pick up power from the RFID reader, these two I/O pins are presented with a sine wave, a few volts in amplitude. Anywhere that sine wave exceeds the supply voltage, some energy is diverted from the coil to the chip’s supply rails, via the clamping diode. The end result is that the chip is powered, and the coil’s sine wave is truncated. The top and bottom of the sine have been chopped off, and it looks a lot more like a square wave now.
- Power filtering using the AVR’s die capacitance. In the smaller prototype, there is no power filtering capacitor at all. In fact, the power is filtered by the internal capacitance of the power planes in the AVR’s silicon die. This isn’t much, but it makes the power supply stable enough that we can execute code even though the supply is pulsing at 125 kHz.
- Very low voltage operation. This particular ATtiny85 chip is specified for operation at voltages as low as 2.5v. The extended voltage range version (I didn’t have any of these handy) is specified down to 1.8v. But I’m running these AVRs at barely over 1 volt. At these voltages, the normal AVR clock oscillators don’t work- but I can get away with this because of the next hack…
- The coil is the AVR’s clock source. The inductor isn’t just hooked up to any I/O pin: it’s actually connected to the AVR’s clock input. Remember the square-ish wave we’re left with after the clamping diodes suck away some power? That waveform is now our clock input. The microcontroller is executing code at 125 kHz, in lockstep with the RFID reader’s carrier wave.
- Firmware? What firmware? At such low speeds, the chip’s firmware looks less like a program, and more like a sequence of I/O operations to perform in sync with each carrier clock cycle. There aren’t a lot of cycles to spare. In the EM4102 protocol, you could potentially do some useful work with the 32 clock cycles you have between each bit. With the HID protocol, though, you need to output an FSK edge as often as once every 4 clock cycles. As a result, the firmware on the RFID tag is extremely dumb. The “source code” is really just a set of fancy assembler macros which convert an RFID tag code into a long sequence of I/O instructions.
The fact that this thing works at all is quite a testament to the robust design of the AVR. The latest AVRFID source is in Subversion, as usual.
Today I finished a major update to my software-only RFID decoder for the Propeller microcontroller, and I finally installed my prototype in the garage. Now I can open the garage door with my RFID badge from work, while I’m on foot or on my bike 🙂
I’ll post some pictures once there’s some sunlight. (Edit: Took some pictures this morning)
That’s a Propeller microcontroller board with a few resistors and capacitors on it. Just add a coil of wire, and you have an RFID reader. Here’s a picture of it scanning my corporate ID badge, and displaying the badge’s 512 bits of content on a portable TV screen:
If you’re into that sort of thing, I wrote a forum post with technical details and pretty oscilloscope screenshots.
Update: The forum link went dead for a while when Parallax switched to a different forum server. I’ve updated the link, but just in case.. A copy of the post is included below.
I’ve been interested in building an RFID reader for a crazy project a friend of mine is working on (automated beer dispensing system 😉 and it was an excuse to do some analog tinkering, so I had a go at building an RFID reader with the Propeller. Why not use Parallax’s fine RFID reader accessory? I wanted to be able to read any off-the-shelf card, including common proximity ID badges.
I just got it working. I’d love to be proved wrong, but as far as I know this is the world’s simplest RFID reader design:
Edit: All capacitances are in picofarads. C1 and C3 should be 1000 pF, not 1000 nF. Likewise, C2 is 2200 pF.
Yep.. just a propeller and a few passive components. To understand this circuit, it’s helpful to know how RFID works first. Here’s the 10-second RFID primer for those who aren’t already familiar with it:
RFID tags work via magnetic fields, like a transformer. A coil in the reader generates a magnetic carrier wave, which is picked up by a coil in the tag or card. This carrier wave powers the card, and provides it with a clock reference. To send data, the card varies the amount of current it draws from the reader’s field, attenuating the carrier wave slightly. This attenuation is usually used to send some kind of modulated signal. The card I’ve been testing with uses a 125 kHz carrier wave, and FSK (Frequency Shift Keyed) modulation. Zeroes and ones are attenuation waveforms with different frequencies.
So, step one: generating a carrier wave with the propeller. I use a counter, naturally, and I generate a differential-drive signal on two pins. This gives me 125 kHz at about 6.6V peak-to-peak. I use an LC tank tuned near 125 kHz to amplify this and shape it into a sine wave. Here’s my carrier wave, measured at the junction between L1 and C1. Note the scale- it’s about 20 volts peak-to-peak! (Also notice that my tuning isn’t quite perfect. Sadness and despair!)
When you bring a proximity card near the reader coil, you can see the attenuation waveform overlaying the carrier wave. This is at the same voltage scale, measured at the same point, but I zoomed out on the X axis so you can see the pattern clearly:
To detect this signal, I use D1, C2, and R1 as a peak detector and low-pass filter, to remove the majority of the high-voltage carrier wave. This is then AC coupled via C3. At this point, the left side of C3 has a “floating” low-voltage waveform that I can position anywhere I want, by changing the bias on C3.
To generate this bias voltage, I use CTRB in DUTY mode. I’ll explain why I call this pin “threshold” later. R4 and C4 are a low-pass filter give me an analog output voltage from CTRB. This signal is usually DC- it’s used for calibration.
R3 “pulls” the floating waveform toward the analog value output by CTRB. Now I take advantage of the Propeller’s Vdd/2 input threshold, and use the “input” pin as a comparator. (R2 is just to limit high-frequency noise.) Now I can use the CTRB voltage to adjust the detection threshold- how much attenuation causes “input” to read 0 vs 1.
Now I have a digital signal, but it’s still really noisy. I use an assembly-language cog to reject as much noise as possible, and time the resulting FSK pulses. This image shows the analog signal at the junction between R2 and C3, along with the digital pulse detector’s output. The amount of time between pulses signifies a “1” or “0” bit. In this case, the detection threshold is at 9 carrier wave cycles. Less than 9, it’s a 0. More than 9, it’s a 1 bit.
End result: I can display the 512 bits of data from my corporate proximity badge. Neat.
I’d include more details on the actual data I’ve captured and the protocol, but so far I’ve only been able to test this with a couple ID badges from the office and I’d rather not share those bits 😉 I have a Parallax RFID starter kit on order, so I’ll let you know if I can read any of those tags successfully.
Source code is attached, but be warned it’s hugely messy.
Update: The latest code and schematics are now have a home in the Object Exchange: http://obex.parallax.com/object/549.