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 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.
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.