Sunday, April 18, 2010

Hacking a USB Infrared receiver

Our living room Hi-Fi setup needs a MP3 player that is always available, easy to use and, first and foremost, allows us to import all the CDs that we have easily and without effort. I've always wanted to do that using our FreeBSD based home server, but none of the ripping solutions really worked the way I wanted and triggered my desire to hack them to my liking. Finally, I gave in and pulled out the aging and unused PowerBook of my wife. After all, iTunes matches my requirements easily, and as I can treat is as piece of Stereo equipment, I'm willing to put my dislike for Apple Computers to the side.

The problem with the PowerBook is that it does not have an IR receiver. We have a Logitech Harmony Remote 515 that we use to control the rest of our entertainment stuff, and we'd like to control the MP3 player with it, too. I could not find a cheap, ready-to-go solution easily, so I decided to throw together something myself using a Teensy and a Vishay TSOP1836 IR receiver module that I found on a surplus board that I found in a box on my shelf.

The goal was to create an IR receiver that acts as a USB keyboard. The key codes that are sent should be useable to set up some global keyboard shortcuts in MacOS X that would control iTunes to our liking.


The TSOP1836 IR receiver module does the IR carrier decoding and interfaces easily with the AVR using one input port. I hooked up my Logicport logic analyzer (excellent product, I write this as a satisfied customer) to the output of the IR receiver and tried a few remotes that I had to see whether the 36 kHz that that the receiver assumes as the carrier frequency would be common. I was lucky, both the remote of our Onkyo Amp and the remote control that came with the Altium Nanoboard 3000 transmitted at that carrier frequency, and both of them used the NEC protocol.

Teensy is a microcontroller board based on an ATMEL AT90USB162 AVR chip. It comes in a DIL24 form factor, so it is easy to integrate into breadboards. A neat thing about it is the flashing utility that looks good, works very well and is unintrusive. The compile/upload/test cycle with the Teensy loader is very short.


I have used LUFA as USB stack on Teensy in the past to implement a adapter for Symbolics keyboards, and I decided to use it again. I was pleased to find that LUFA has made great progress since I last used it. There are more examples, the class drivers have been separated from the demo code, and the cheapish task scheduler is not longer used by the examples that I used.

I tried to make the USB implementation of the adapter offer two end points: A keyboard endpoint that sends the translated key codes when remote keys are pressed, and a serial or CDC endpoint that would be used to configure the adapter in order to make it possible to configure it to whatever remote is available. Unfortunately, I found that MacOS X does not accept devices with multiple endpoints as standard serial/CDC device, so I abandoned the idea of configurability. Instead, I made the adapter work with the Altium remote and a statically compiled translation table.

To find out the codes that the remote sends, I wrote a version of the adapter that acts as a serial device. Using that information, I set up the translation table in the HID keyboard version of the firmware.

When I tried setting up some global keyboard shortcuts for iTunes, I learned that iTunes does not really support global short cut keys, presumably to "protect the user". Using a the free SizzlingKeys utility, I was able to achieve what I wanted, though.

The source code for the two Teensy firmwares is available in my github repository.