Introduction: IRK! Infrared Remote Controlled USB Keyboard Without Keys

IRK! is a USB keyboard, without keys, that you can operate by simply using your LEARNING infrared remote control.

I created it to allow me to control my MythTV home theater PC with my LEARNING infrared remote control instead of having to use a real USB keyboard - but it will work with any system (Linux, Windows, or whatever) that you can plug a USB keyboard into, and also other home theater systems like XBMC and MediaPortal.

Many people use LIRC on Linux to control MythTV, but my solution does not require you to edit any complicated configuration files and does not need any special device drivers or software to be installed. However, you do need to build it!

IRK! is an open-hardware project that I created on SourceForge. Contributors and bug reports are welcome.

I've put a 2-minute video on YouTube showing how it works.


The feature set so far includes:

  • Teaches your LEARNING remote control IR codes
  • Lets you map IR codes to USB keystrokes - for example, Shift+Enter
  • Sends the USB keystroke to your PC when you press a button on your remote
  • Can send power off, sleep, and wake codes to your PC
  • IRK! devices can have one of 256 addresses - so you can have multiple IRK!'s
  • Handles broadcasts - so multiple IRK!'s can respond to a single remote button
  • Supports USB Consumer Device functions (e.g. Mute, Volume Up, etc)
  • Has a programmable LCD backlight delay (and ON/OFF commands)
  • Can be built using either Through Hole Technology (THT) or Surface Mount Technology (SMT)

IRK! is an evolving project. Please check out irk-usb on SourceForge for the latest enhancements.

Step 1: Prerequisites

This project is for reasonably advanced electronic nuts...but if you stick with it anyone can make it.

Through Hole Technology (THT) versionIf you choose to build the Through Hole Technology (THT) version, then you will be making a Printed Circuit Board (PCB) or at least a matrix board, soldering electronic components onto it, and then programming a PIC micro-controller, so you'll need:

  • PCB making equipment. I use inkjet transparencies, an ordinary fluorescent desk lamp as a UV source, and Kinsten positive-acting presensitised board, and ferric chloride etchant.
  • A good soldering iron with a fine tip. I soldered everything on both the THT and SMT boards with a Hakko T18-B 1 mm ball tip.
  • A micro-controller programmer able to program a Microchip PIC18F2550 micro-controller, such as a Pickit2 or you can make your own (search for "pic programmer" on Instructables).

Surface Mount Technology (SMT) versionIf you choose to build the Surface Mount Technology (SMT) version, then you'll need:

  • A PCB manufacturer to make a double-sided PCB. I used a company called ITEAD who have very reasonable rates and manufacture very high quality boards. All the Gerber files are available on SourceForge. You just need to zip them up and email them to the manufacturer, pay your money and wait.
  • To be able to solder small Surface Mount Devices (SMDs) to the PCB. That is not as hard as it seems as the design uses only relatively large SMD parts. There are plenty of tutorials on the Internet showing how to handle SMDs. A Hakko T18-B 1 mm ball tip (or similar) is fine - even for the ICs. Use plenty of "no clean" flux.
  • A micro-controller programmer able to program a Microchip PIC18F25K50 micro-controller, such as Mikroelektronika's mikroProg for PIC. Unfortunately the PIC18F25K50 is not supported by Pickit2 and even Pickit3 seems to lack support (well, I couldn't get it to work, so I bought a mikroProg which seems to be better anyway).

And in case it doesn't work for you first time, you may find it helpful to have:

  • A good logic analyser like Logic (works on Windows or Linux)
  • A USB trace capture program like USBTrace or USBlyzer (for Windows) or Wireshark (free on Linux). On Linux, make sure you're using the libpcap 1.1 (packet capture library) or later.

Step 2: Circuit Diagram

The circuit (see pdf attachments below) can be divided into a number of functional groups.

Infrared Receiver Interface
The infrared receiver consists of the TSOP4838 IR receiver module. Its job is to convert 38 kHz modulated IR signals from your remote control into digital ones and zeroes. The receiver will output a logical one (0V) when the remote is transmitting a 38 kHz signal, and will output a logical zero (+5V) during periods of silence.

Infrared Transmitter Interface
The transmitter consists of a PN2222A transistor (but any general purpose NPN transistor will work) which drives a series of three Infrared Light Emitting Diodes (IR LEDs). Driving three IR LEDs is done to boost the transmitting power. Learning remotes are designed to accept signals from remote controls in close proximity and remotes are designed to produce an intense IR signal. Consequently, IRK! must produce a fairly intense IR signal in order for the learning remote to be able to "see" it during the learning process.

LCD Interface
The Liquid Crystal Display is a 2x16 (2 lines at 16 characters per line) unit compatible with the Hitachi HD44780 4-bit defacto standard. You can use a 4x16, or a 4x20 display if you like as long as it is HD44780-compatible. These are available on eBay at very reasonable prices.

USB Interface
The USB interface is provided by the USB module built into the PIC18F2550 microcontroller. It is managed programmatically by the USB library provided with the MikroC Pro C Compiler.

Activity LED Interface
Hardly an interface as such - a simple LED and a current-limiting resistor - but if you use a high intensity (8000 mcd) green LED then I've found that you can make the resistor an insanely high value - like about 18 kΩ - and the LED is still bright! That means that the driving current is only 100 μA. If you use the original 470Ω resistor specified in the circuit diagram then you could end up being startled by the brightness.

Power Interface (experimental)
The circuit diagram shows how to power the IRK! unit using the standby voltage (Vsb) output from your PC's power supply. However, this has not been tested. You can leave the connection to Vsb out and IRK! will still work - but if you power down your system, you will not be able to power it up using your remote control. Just walk over to your PC and turn it on the old fashioned way!

Step 3: Parts

The list of parts depends on whether you are building the Through Hole Technology (THT) version or the Surface Mount Technology (SMT) version.

Through Hole Technology (THT) versionAll parts are "through hole" (i.e. they have leads) with the exception of a single surface mount device (SMD) - a 100nF bypass capacitor.

The links below are just the places I got my parts from - they're not recommendations, but rather just a convenience for some who might not have particular bits and pieces.

Major Parts

2 x 4.7 μF Tag Tantalum capacitor (polarised)
2 x 22 pF Ceramic capacitor
1 x 220 nF Tag Tantalum capacitor (polarised)
1 x 100 nF Ceramic capacitor (SMD 1206 sized package)

1 x Female header 16-pin SIL (for the LCD)
1 x Male header 2x4-pin (for the PWR/RST leads)
1 x Male header 1x6-pin (for the ICSP)
1 x Male header 2x5-pin (for the USB cable)
1 x Male header 1x2-pin (for the Standby voltage lead)

3 x 1N5817-B Schottky barrier diode (D041 package)

Integrated Circuits
1 x PIC18F2550 Microchip 18F2550 microcontroller (28-pin DIP)
1 x TSOP4838 IR Receiver and Demodulator

Liquid Crystal Display
1 x HD44780-compatible LCD Display (16x2) with backlight

Light Emitting Diodes
1 x General purpose 5 mm LED (any color)
3 x TSAL7400 Infrared LED (940 nm)

1 x PN2222A General purpose NPN Transistor (TO92 package) (or equivalent e.g. BC548)
2 x 2N7000 General purpose N-Channel MOSFET (TO92 package)
1 x BC557B General purpose PNP Transistor (TO92 package) (or equivalent e.g. PN2907)

1 x 100 kΩ 1/4 Watt Resistor
1 x 100 Ω 1/4 Watt Resistor
1 x 470 Ω 1/4 Watt Resistor
1 x 22 Ω 1/4 Watt Resistor
1 x 4.7 kΩ 1/4 Watt Resistor
2 x 10k Ω 1/4 Watt Resistor
1 x 4.7 kΩ 1/4 Watt Resistor
1 x 10 kΩ 1/4 Watt Resistor

7 x Tactile micro-switches SPST Normally Open momentary action (Omron B3F series or similar)

Variable Resistors
1 x 10 kΩ Variable trimmer resistor (Bourns 3362 series or similar)

1 x 8 MHz Crystal (HC49/S package)

Miscellaneous Parts

- Female rectangular plugs (Harwin M20-106 series) for connecting reset/power switches to the motherboard (you can usually harvest these from an old PC)
- A 5.25" drive bay box/panel (or a standalone box) to house the assembled PCB
- Miscellaneous mounting hardware (nuts, bolts, spacers etc)

Circuit Board Making Supplies

- Kinsten double-sided PCB (preferably fibreglass)
- Kinsten DP50 developer
- Ferric Chloride etchant (or whatever you normally use)

Surface Mount Technology (SMT) versionThe surface mount parts list as exported by Eagle CAD is:

Part Value       Device           Package     Description          
C3   100nF       C-EUC0805        C0805       CERAMIC CAPACITOR
C4   100nF       C-EUC0805        C0805       CERAMIC CAPACITOR
C5   100nF       C-EUC0805        C0805       CERAMIC CAPACITOR
C6   100nF       C-EUC0805        C0805       CERAMIC CAPACITOR
D1   SS14        SS14             SMA-DIODE   SS14 Schottky Diode
D2   SS14        SS14             SMA-DIODE   SS14 Schottky Diode
D3   SS14        SS14             SMA-DIODE   SS14 Schottky Diode
IC1  PIC18F25K50 PIC18F25K50SO28W SO28W       PIC Microcontroller
IC2  MAX4066ESD  MAX4066ESD       SO14        Quad Bilateral Analog Switch
JP2  ICSP        PINHD-1X6        1X06        PIN HEADER
JP3  USB         PINHD-2X5        2X05        PIN HEADER
JP5  SWITCHES    PINHD-1X8        1X08        PIN HEADER
LCD1 HD44780     HD44780          LCD_16X2    Generic HD44780 16x2 LCD
LED1 ACTIVITY    LED5MM           LED5MM      LED (any color)
LED2 TSAL4700    LED5MM           LED5MM      IR LED
LED3             LED5MM           LED5MM      IR LED
LED4             LED5MM           LED5MM      IR LED
Q1   MMBT2222A   MMBT2222A        SOT23       2N2222 General Purpose NPN Transistor
Q2   MMBT3906    MMBT3906SOT23    SOT23       2N3906 General Purpose PNP Transistor
R1   100k        R-US_M1206       M1206       RESISTOR
R2   100         R-US_M1206       M1206       RESISTOR
R3   470         R-US_M1206       M1206       RESISTOR
R4   22          R-US_M1206       M1206       RESISTOR
R5   4.7k        R-US_M1206       M1206       RESISTOR
R8   4.7k        R-US_M1206       M1206       RESISTOR
R9   10k         R-US_M1206       M1206       RESISTOR
S1   DOWN        C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S2   UP          C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S3   OK          C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S4   SHIFT       C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S5   ALT         C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S6   CTL         C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
S7   TEACH       C&K-PTS525-SM10  PTH525-SM10 Momentary Switch
U1   TSOP4838    TSOP4838         TSOP18XX    IR Receiver and Demodulator
VR1  10k         TRIMPOT3303W     3303W       Trimmer Potentiometer

Step 4: Assembly

Through Hole Technology (THT) version
This is how I built the Through Hole Technology version

  • Make a double-sided fibre glass PCB (see front- and back- PDF files below). There are several ways to do this. The way I do it is to print the front and back PDF files onto inkjet transparencies using the highest quality level. It doesn't matter whether you print mirrored or not because you can always flip the transparency. Line the transparencies up and tape along one edge to keep them aligned. Cut some Kinsten positive resist PCB to size and peel off the protective layers. Insert the PCB between the two transparencies, carefully line up the transparency to the PCB, and clamp the lot between two pieces of glass using pegs or whatever. Now that the protective layers have been peeled off, the photo-sensitive coating on the PCB is now exposed to light, so try to keep it out of any unintentional UV light sources (e.g. the sun, fluorescent lights, arc welders etc). Use an ordinary fluorescent desk lamp to expose each side for 10 minutes at a distance of about 5 cm. Develop with DP-50 developer until the tracks are clearly seen. Then etch using ferric chloride.
  • Drill all the small (0.8 mm) holes first, then the larger holes (1 mm) for the headers, then the largest (3 mm) for the 4 x 2.5 mm LCD mounting bolts.
  • Solder all components onto the PCB starting with the lowest-profile parts. For example, the SMD bypass capacitor is a good place to start, then resistors, capacitors, crystal, trimmer resistor, IC socket, headers and LCD socket.
  • Tantalum capacitors are polarised. This means you have to make sure they are inserted the right way around. The lead closest to the painted "stripe" is the positive (+) lead. Note that this is the opposite part labeling convention to diodes, where the "stripe" indicates the negative (-) side (aka cathode).
  • Leave the IR transmitting LEDs until later as you will have a better idea how long you will have to make their leads then. Also leave the IR receiver module until later as it will be connected to the PCB with fly leads and a female plug.
  • Make sure you don't mount the crystal flush to the PCB otherwise it will come into contact with some of the PCB tracks. You could insert a plastic spacer but it's easier just to keep a 1-2 mm air gap between the crystal and the PCB.
  • For the PCB layout, I've cheated on some vias by using some legs of wired parts as vias. I'll never do that again - it's not worth the trouble! You have to remember to solder both sides of the board for these parts. In particular, if you miss the middle pin of the IR receiver module, then none of the buttons will work as they won't be connected to ground!
  • After soldering each part, use your multimeter to check connections. For example, after you solder the SMD bypass capacitor, check that it is not shorted and that it still reads 100 nF. It's best to fix soldering problems as you go rather than after the unit is fully built.
  • I built my unit behind a Lian Li aluminium 5.25" drive bay panel and connecting it to an internal motherboard USB header using a cable liberated from a broken USB card reader. It's probably easier to modify one of these drive bay drawers though.
  • The IR receiver module deserves special attention. I glued mine to the 5.25" front panel using Araldite two-part epoxy. The IR receiver is connected to the PCB via a miniature female plug - the type used to connect speakers etc to a PCB socket. You solder three leads to the PCB and on the other end of the leads you have a miniature female plug. You push the plug onto the legs of the IR receiver module.
  • Wire up the switches using rainbow cable. There is one wire per switch which has to go to the corresponding connection point near the micro-controller. The circuit diagram and board layout shows these connection points. For example, the Teach button connection point is marked with a "T".
  • Plug the LCD display into a 16-pin SIP socket and bolt it to the PCB using plastic spacers. You may have to cut the spacers to the correct height. An easy way to make sure they all have the same height is to buy threaded plastic spacers, then bolt them onto a piece of spare timber, then use a drop saw to cut them all at once.
  • Make a pair of L-shaped aluminium brackets and bolt them to the edges of the PCB. These will become the mounting points with which you will later attach the PCB to the 5.25" drive bay panel.
  • Mark out the front panel holes, LCD window and IR window by using the PCB layout as a template. To do that, print it on an inkjet transparency, tape the transparency to the 5.25" drive bay panel and drill though it. Use a nibbler to cut the LCD and IR windows in the panel, then file the inside edges until they are straight. Use a tiny piece of wet-and-dry sandpaper to smooth the edges further if you wish.
  • For the push buttons, don't drill the holes just yet. Instead, glue a 12 mm thick piece of wood (pine is good) behind the front panel using Araldite (see picture below). The wood will act as a guide for the push-button rods. Once the Araldite has set, drill a hole for each push button through the front panel and completely through the wood behind it too. I used a piece 3/16" clear acrylic rod for each push-button and drilled a 13/64" (5.2 mm) hole for each. The 3/16" is 4.8 mm in theory, but when I measured the rod it was 5.0 mm, so a 0.1 mm gap is all that you need between the rod and the hole.
  • Now is a good time to make the front panel artwork. See "How to Make the Front Panel Artwork" below. You can leave it until later like I did, but it's more troublesome.
  • The acrylic rod used for the push buttons can be cut by scoring it at the required length using a craft knife and snapping it with your fingers. You may have to try a few times until you get a decent edge. Even so, the edge will be translucent (i.e. not clear) and not necessarily square so you will need to sand it down first with P180 glass paper to get a square end. If you want to make the ends transparent you will need to do some extra work. Sand first with Grade P2000, then 15μ 3M Microfinishing Film 468L, then 5μ, then 0.5μ - each time make sure the paper is resting on a sheet of flat glass. This stuff is so fine you wouldn't think would be abrasive at all, but you will find that the ends will become transparent after you use the 0.5μ paper. It's probably not worth it really...translucent is ok.
  • Insert the acrylic rods until they touch the top of each microswitch. To stop them from falling out again, use some rings of heat shrink tubing to hold them in place. To do that, get some 5 mm heat shrink tube, and cut one 3-4 mm ring for each rod. Thread each ring onto some spare 3/16" rod, use a hair dryer (or whatever) to shrink them onto the rod. When they have cooled, push them all off the rod, insert the push button rods into their positions and thread the pre-shrunk rings onto each rod to hold them in place. A pair of good tweezers makes this a lot easier. A dob of glue may be necessary to ensure that the rings don't slip. Don't try to shrink the tubing directly onto your acrylic rods...the heat may deform the rods so that they won't slide properly.
  • For the IR transmitter window, cut a piece of Infrared-transparent acrylic to size and glue it behind the IR transmitter window on the front panel. This stuff is incredibly hard to buy, so I ended up hacking a piece out of an old IR remote control. It's the dark red plastic that hides the internals but still allows infrared light to pass through it.
  • For the activity LED I already had a clear acrylic light guide that I'd harvested from some dead electronics. I drilled and filed a 2 mm x 5 mm slot in the front panel and epoxied the light guide behind it. If you use a light guide then the LED lead length is not critical. Alternatively, you could panel mount the LED with a plastic LED clip and have the LED leads plug into a socket on the PCB. Alignment of the PCB to the panel becomes finicky though.
  • Finally, put the PCB into the front panel so that the LCD is positioned squarely in the front panel's LCD window and use masking tape to temporarily hold it in that position. Now drill one (or two if you prefer) holes in each side so that the holes go through both the 5.25" drive bay panel wings and the PCB side brackets. Remove the masking tape and then bolt the side brackets to the 5.25" drive bay panel wings. Use flat-headed bolts if you have them. Don't forget to plug the IR receiver up.

How to Make the Front Panel Artwork

  • I'd recommend doing this step before you have mounted any component on the front panel (that is, the IR transmitter LED, the IR receiver window filter, and the activity LED), but after you have cut/drilled all the holes.
  • This is my second attempt at this. Using Inkjet Waterslide decal paper was a complete failure! Waterslide decals just don't stick to aluminium very well. Instead, get some sheets of Clear Inkjet Adhesive Shipping Labels (for example, Avery 8665), print the words/design that you want to appear on the front panel using any program that you're comfortable with. Microsoft Visio worked for me.
  • Cut out the rectangle that contains all the words/graphics. Then spray it with a few light coats of clear gloss acrylic paint.
  • After the acrylic has dried (maybe 20 minutes), peel the backing away, line it up with the front panel, and roll it into place (so you don't get bubbles).
  • Trim around the outside edges with scissors leaving a 5 mm border (or more). Use a craft knife to cut the front panel cutouts - again leaving a 5 mm border.
  • Cut diagonally towards the corner of each cutout and tuck the flaps under so that they wrap around and stick to the back of the panel. Similarly, chamfer the corners of the outside edge so that the flaps can stick to the sides without overlapping. This sounds complicated but it is really obvious once you start!
  • Next, use a craft knife to cut out the front panel button holes. There is no advice here except to be as neat as possible - cutting 5 mm circles in plastic is not easy.

Tip for Soldering Hand-made Vias

With a double-sided PCB sometimes the tracks on one side of the board need to be connected to tracks on the other side. This is called a "via". Manufactured boards have plated-through holes for that purpose (that is manufacturing magic of which I know nothing). For hand-made boards you can either solder, on both sides, a piece of single-core wire through the via hole - or you can do this...which I think is easier:

If you have an IC socket in your spare parts box which has machined sockets (not spring sockets), then just use your wire-cutters to cut off the pins so that you have a set of "goblet" shaped pins (usually a bit mangled on the top, but it doesn't matter). Wedge a "goblet" into each via hole - they'll hold themselves in place - then solder them on each side!

Don't Forget to Set The LCD Contrast

When you power it up for the first time, don't forget to set the LCD contrast by adjusting the 10 kΩ variable trimmer resistor. Once you have done this you will not need to readjust it. Failure to to this may cause you to think that the LCD display is not working.

Experimental Power/Reset Switch Control Connections

If you decide to implement the experimental power/reset switch functions then you will need to connect IRK!'s PWR and RST pins in parallel with your PC's Power and Reset switches. This is pretty easy because the Power and Reset switch cables on most PCs connect to a header on the motherboard. What you have to do is redirect these cables to IRK!'s header pins, and then make up another pair of cables and connect them between IRK! and your motherboard PWR and RST header pins. The connectors that you should use on the ends of each cable are Harwin M20-1060200 2.54 mm pitch rectangular housings with Harwin M20-1180046 female crimp contacts crimped to the end of each wire. You can usually harvest these from an old PC.

Note that polarity is important when using 2N7000 FETs! This is not intuitive because although a switch does not have polarity, the circuit on your PC's motherboard that senses the switch action has a ground pin and a sense pin. The sense pin will be kept weakly high (above ground) by your motherboard. Pressing the power button, for example, will short the PWR+ sense pin to ground (the PWR- pin), causing your motherboard to begin the power up cycle. But the 2N7000 FETs that IRK! has in parallel with the switches each have a reverse diode built into them, so if you connect the cables the wrong way around it would be the same as constantly pressing the power and/or reset buttons! Not good.

Surface Mount Technology (SMT) versionThe construction for the SMT version is much the same as the THT version. However, a few things are worth noting:

  • Hand soldering small SMT devices is much easier if you can somehow hold the device in place leaving both hands free to work the soldering iron. I'd suggest making a Do-It-Yourself SMD clamp as shown in the picture above. The idea is to let gravity hold the device in place while you solder it. The general process is, apply plenty of "no clean" flux to the pads, position the part with tweezers, hold it in place with the DIY clamp, apply a tiny dot of solder to the soldering iron tip (let the core flux burn off), solder one end of the part, apply more "no clean" flux, add another tiny dot of solder to the tip, solder other end, remove clamp, flush area with isopropyl alcohol, soak up excess alcohol with a lint-free wipe. You don't normally apply solder to the tip of the iron and then apply it to the work (certainly not for through-hole soldering) - but I think it works better for surface mount devices.
  • The 2N7000 FETs have been replaced by a single 4066 CMOS Quad Bilateral Analog Switch integrated circuit. The 4066 has a much more "switch-like" behaviour so polarity becomes irrelevant. Just make sure you don't try to switch more than 25 mA of current. The 4066 is not a power switch.

Step 5: Program

To program the firmware into your IRK unit:

  • Download the hex file from SourceForge.The IRK.hex file in the /tht directory is for a PIC18F2550. The IRK.hex file in the /smt directory is for a PIC18F25K50.
  • Attach your programmer to the programming header pins on the IRK! circuit board (see picture below).
  • Use your PIC programmer to load the hex file into the PIC micro-controller.

For those interested in programming, the source code (of IRK! version 2) on SourceForge is split into two components:

  • IRK.c - The main logic which handles infrared transmission, reception, front panel button actions, LCD display, activity LED and communication using USB to the computer.
  • USBdsc.c - The USB Human Interface Device (HID) descriptor information which describes the IRK device to the computer when it is plugged in.

Step 6: How It Works


The basic idea is that there is a one-to-one mapping between pressing a button on your remote control and a key combination sent to your PC. IRK! simply teaches your learning remote a code that represents a particular key combination. Once you have programmed that code onto one of your remote buttons, pressing that button will transmit the code back to IRK! which will, of course, recognise it then send it to the PC as a USB keystroke.

Because IRK! generated the IR code, it can't possibly not recognise it - so IRK! does not need to support a zillion different IR remote control models!

USB Keystrokes

USB keystrokes are sent to the PC using codes defined in the USB Human Interface Device (HID) Usage Tables specification. That specification defines, for example, that code 0x04 means the letter "a". For a keyboard device, like IRK!, additional "modifier" codes can be sent to the PC to indicate whether the GUI (aka Windows key, Apple key, Super key), Control, Alt and Shift keys are also "pressed". For example, to send an uppercase "a", IRK! sends 0x02 (meaning Shift is pressed) and 0x04 (meaning "a" is pressed). The computer interprets that sequence as meaning uppercase "A". Immediately after sending that sequence, IRK! will send a "null" sequence of 0x00 and 0x00 to indicate that no key or key modifiers are currently being pressed. This is required by the USB protocol otherwise the PC will think you are holding down the Shift and "A" keys until it receives the next USB key code.

So, you can see that IRK! only has to be able to "teach" a learning remote control a sequence of 0x02 followed by 0x04 to represent the letter "A". When the user presses that button on the remote, IRK! will receive it using its infrared receiver and then send the 0x02 0x04 sequence to the PC which will be interpreted as the user pressing Shift+A on a USB keyboard.

Infrared Command Format

IRK! only recognises infrared signals that are addressed to a particular IRK! unit. To achieve this, an address byte is also sent/received on the infrared path. Each infrared command is a sequence of six (6) bytes as follows:

AA, AA', UX, UX', YY, YY'


AA is the address byte from 0x00 to 0xFF
AA' is the inverted address byte (all the ones converted to zeroes and vice versa)
UX is the usage page (U = 0x0 to 0xF) and, for the Keyboard usage, modifier nybble X (Control, Alt, Shift)
UX' is the inverted UX byte
YY is the command byte (for Keyboard usage, the USB key code)
YY' is the inverted command byte

The reason for transmitting an inverted copy of each byte is to reduce the chance that interference has caused an invalid command to be received. For example, you wouldn't want your request to "play this recording" to be interpreted as "delete this recording" just because a fly interrupted the infrared signal path in that instant!

To validate each command as it is received, IRK! checks that AA (inverted) equals AA', and that UX (inverted) equals UX', and that YY (inverted) equals YY', and that either AA equals this IRK!'s device address or AA equals 0xFF (the broadcast address). If all of the above is true, then IRK! can be fairly sure that it is a valid command and will act upon it.

Infrared Transmission Technique

IRK! uses Pulse Width Modulation (PWM) to encode the series of 1's and 0's that constitute each command. You could reprogram the microcontroller to use a different technique such as Manchester Encoding but PWM works just fine. For example, the USB '1' key when encoded using PWM looks like the image above.

Whenever the signal is "low", an IR burst of pulses at 38 kHz is being transmitted. Conversely, when the signal is "high" it represents a period of silence.

There is a leading burst for 1000 μs then silence for 600 μs (in versions of IRK! prior to 2.04, it was 9400 μs and 4500 μs respectively). This leading burst was required by older infrared receiver modules to "train" their Automatic Gain Control (AGC) circuits so that they could determine what a normal signal level was. Today's IR receivers don't usually have this requirement, but your learning remote may be old so IRK! still supports it.

Thereafter, a '1' is encoded as a short burst followed by a long silence, and a '0' is encoded as a short burst followed by a short silence.

Broadcast Address

An address byte of 0xFF is recognised by all IRK! devices that you may have built. So it is possible for a single remote control to send a command to ALL IRK! devices simultaneously.

System Control Commands

IRK! also supports the USB-defined "System Control" commands called "Sleep", "Wake" and "Power Off". Some USB keyboards have keys for these functions, but they are not intrinsically keyboard functions. Any suitably programmed USB device, such as IRK!, can send USB System Control commands to your PC to request it to go into "Sleep" mode, for example. The following is a summary of the results of the System Control commands on my PC (your mileage may vary):

Power Off = CPU off, Disk off, Monitor off, USB off
Sleep = CPU on, Disk off, Monitor off, USB on
Wake = Does not work!
Power Switch Pressed = CPU off, Disk off, Monitor off, USB on

Consumer Device Commands

IRK! supports the USB-defined "Consumer Device" commands such as "Mute", "Vol+", "Vol-", "Calculator", "Browser Home", You can use these commands to control your Media Player (play/pause, stop, skip back, skip forward etc) or start applications (Calculator, Browser, Media Player etc).

For a complete list of the Consumer Device commands that you can use, just download the USB Human Interface Device Usage Tables document. That sounds complicated, but the specification is not that hard to read. Specifically, look at Table 17 "Consumer Usage Page". It does not matter that IRK! does not display the names of all these commands as you scroll through them, you can still ask IRK! to send them to your USB host (e.g. Linux, Windows, MythTV etc) - and the USB host should execute the corresponding function.

Power Switch and Reset Switch Commands (experimental)

Astute readers will have noticed that there is a problem with trying to get IRK! to "Power On" your PC - because not all PCs supply power to USB devices all the time when the system power is off and IRK! depends on power being provided by the USB interface of the system it is connected to.

A way around this is to power the IRK! circuitry from the "Standby" voltage (Vsb) from the PC power supply. Vsb on older computers supplies +5V at around 10 mA even though you have powered your PC off. More recent ATX power supplies can deliver Vsb at 2A. This means that, if powered from Vsb, IRK! can stay awake listening for IR commands as long as the PC is plugged into the wall power outlet. The IRK! circuit caters for pressing the Power and Reset buttons on your PC, but you will have to somehow tap into the Vsb output from your PC's power supply to get it to work. I don't know of any motherboards that have a readily accessible header pin for Vsb. This means that if you want this function, then you may have to physically break the Vsb wire from the PC power supply. The Vsb wire should be the purple wire.

Note that powering IRK! from Vsb has not been tested at the moment, but should work in principle. The Power Switch and Reset Switch functions do work as long as IRK! is powered from USB though.

Step 7: Usage

Using IRK! is easy...all you need to do is:

  • Understand the LCD display format of IRK!
  • Use IRK! to program your learning remote with each keystroke you want to use
  • Use your remote to ask IRK! to send keystrokes to your computer

Understanding The LCD Display Format

The LCD display shows information in the following format for the Keyboard usage:

0x modifiers
yy command


0 = The usage code meaning Keyboard
x = The key modifier bits in hexadecimal (e.g. 7 )
modifiers = A textual explanation of the key modifier bits (e.g. CTL ALT SHIFT)
yy = The USB key code in hex (e.g. 2A is Backspace)
command = A textual explanation of the command (e.g. Enter)

...and in the following format for the other usages (Consumer Device, System Control):

uy usage
yy command


u = The usage code in hex (1 = System Control, 2 = Consumer Device, F = IRK local function)
usage = A textual explanation of the usage code (e.g. Consumer Dev)
yyy = The command code in hex split over two lines (ranging from 000 to FFF, so only 4096 commands are possible)
command = A textual explanation of the command (e.g. Mute)

The following usages (i.e. the "u" in the above) are currently supported:

0 = Keyboard (Enter, etc)
1 = System Control (Power on, sleep, wake etc)
2 = Consumer Device (Mute, Vol+, Vol-, etc)
F = Local IRK! function

Programming Your Learning Remote

  1. Connect IRK! to an internal USB header on PC's motherboard. If you have chosen to build IRK! with a standard USB A-B cable, then just plug it into a normal external USB port.
  2. Wait for IRK! to indicate "USB Ready" on its LCD display. The activity LED will flicker while IRK! is trying to establish USB communications with your PC.
  3. Using IRK!'s UP, DOWN, CTL, ALT and SHIFT buttons, select a key combination that you want to send to your PC - for example, Ctrl+Home. The CTL, ALT and SHIFT buttons toggle between "pressed" and "not pressed" each time you press them. The CTL button, when pressed for more than 1 second, toggles the GUI indicator. TIP: Press and hold the UP or DOWN buttons to cycle through the available keystrokes quickly.
  4. Press IRK!'s OK button to send the key combination to your PC to test that it works.
  5. Set your learning remote to "Learn" mode and select a button to be programmed on your remote.
  6. Press IRK!'s TEACH button to transmit an IR code representing that key combination to your learning remote.
  7. Set your learning remote to "Normal" mode and press the newly programmed button on your remote.
  8. Watch as IRK! sends that key combination to your PC. IRK! will flash the activity LED each time it recognises a keystroke and it will display the last keystroke received on its LCD display.
  9. Rinse, and repeat from step 3 as many times as you need!

To select a usage other than Keyboard (e.g. Consumer Device):

  1. Press and hold the SHIFT button for more than 1 second until "Select Usage" is displayed on the LCD
  2. Press the UP or DOWN buttons until the desired usage is displayed (e.g. Consumer Dev)
  3. Press OK to use functions in that usage
  4. Press the UP or DOWN buttons until the desired function is displayed (e.g. Mute)
  5. Press OK to send the function to your PC to determine if it supports that particular function.
  6. If the PC responds as expected, press TEACH to program that function onto a button on your learning remote control.

Using Your Remote

This is the same as using any remote. Press a button and IRK! will respond to commands addressed to it. The most recent command actioned will be displayed on the LCD. If the Activity LED on the front panel flashes, then IRK! has recognised the command and has passed it onto the PC. If nothing happens after that then that's the fault of the PC. If the Activity LED does NOT flash, then IRK! has not recognised the IR code programmed onto that button - your IR remote might have a flat battery, or the maybe the code wasn't programmed accurately, or maybe you're standing too far away from the IRK! device.

Setting The IRK! Device Address

By default, IRK! will power up using a device address of 0xAA. If you build more than one IRK! unit, and want to address them individually, then you will have to set a unique address on each one. An IRK! device address can be in the range 0x00 to 0xFE (0xFF is the broadcast address to which all IRK! devices will respond). To do this:

  1. Press the UP/DOWN buttons until the command "00 Set Address" appears on the LCD display.
  2. Press OK to enter "Set Address" mode.
  3. Press the UP/DOWN button until the desired address is displayed in the mm field.
  4. Press OK to save the new address and exit "Set Address" mode.

From then onwards, that IRK! device will remember the new address in its on-board non-volatile memory (EEPROM). If you have taught your learning remote control any commands using the old address, then you may need to re-program it from the IRK! with the new address.

System Control Commands

The following three commands correspond to the USB System Control commands:

    • 02 01 Power Off - This will place your PC into system power state S5 (completely powered off)
    • 02 02 Sleep - This will place your PC into system power state S3 (suspend to RAM)
    • 02 03 Wake - This will wake your PC from S3 and return it to state S0 (powered on)

    Experimental Power Control Commands

    For the Through Hole Technology (THT) version of IRK!, the following (non-USB, local to IRK!) commands are experimental (i.e. not fully tested) and may need the IRK! device to be powered from your PCs standby voltage (Vsb):

    • FF 01 Power Switch - This is equivalent to pressing the POWER button on your PC. The action taken depends on how you have configured your PC
    • FF 02 Reset Switch - This is equivalent to pressing the RESET button on your PC. Use this with the same amount of caution that you normally apply when using the real RESET button on your PC! You have been warned.

    For the Surface Mount Technology (SMT) version of IRK!, this list of commands has been extended and control the operation of the 4066 CMOS Quad Bilateral Analog Switch:

    • F0 01 Power Switch - The two header pins marked PWR will become low impedance for about 250 ms. Note: this is not meant to switch large currents. The 4066 quad analog switch can pass an absolute maximum of only +/- 25 mA.
    • F0 02 Reset Switch - The two header pins marked RST will become low impedance for about 250 ms.
    • F0 03 Init USB - Causes the unit to re-register itself as a USB device. It is almost the equivalent of unplugging and replugging the device into a USB port.
    • F0 07 Debug on - Displays debug information on the LCD when an IR code is received
    • F0 08 Debug off - Returns the unit to Normal mode (displays no debug information on the LCD)
    • F0 09 Auxiliary Switch - The two header pins marked AUX will become low impedance for about 250 ms.
    • F0 0A Power Switch On - The two header pins marked PWR will become low impedance until a subsequent Power Switch Off command is received.
    • F0 0B Reset Switch On - The two header pins marked RST will become low impedance until a subsequent Power Switch Off command is received.
    • F0 0C Auxiliary Switch On - The two header pins marked AUX will become low impedance until a subsequent Power Switch Off command is received.
    • F0 0D Power Switch Off - The two header pins marked PWR will become high impedance.
    • F0 0E Reset Switch Off - The two header pins marked RST will become high impedance.
    • F0 0F Auxiliary Switch Off - The two header pins marked AUX will become high impedance.

    Note that although the header pins are labelled PWR, RST and AUX you can use them for any function that would normally use a low current (< 25 mA) Single Pole Single Throw (SPST) momentary action push button switch.

    USB Contest

    Participated in the
    USB Contest