First of all we will need a way to capture those infrared signal coming from our remotes, the easiest way (and cheapest) is to build a small receiver with a photo-diode. (on the sides you see the electric diagram and my test bench)
Now that we built our receiver we can test if it’s working like it should. I used Audacity (a Linux audio multifunctional tool) to analyze the signal coming from the photodiode. The results:
Now we have a signal composed by some waves, great, let’s try to explain how CIR (Consumer infrared) works.
First of all, quite each brand has his own solution, so we can’t really generalize the discussion. Anyway the most used is the RC5 from Philips. As you can remember, the lesser the frequency the the fair signal can get. The modulation (how you encode your data on the wave) used by fast every brand is called Amplitude-Shift Keying (ASK).
Each frame is composed by:
- 2 start bits which are used by the AGC (Automatic Gain Controller) from the receiver (TV)
- 1 toggle bit which varies every time a button is pressed
- 5 bits which represents the device address
- 6 bits with the command
Now that we have a minimal understanding of the ground let’s try code something with this. First of all we have to access our audio mic line (where we connected our fancy IR receiver) and prepare a buffer that our system will fill up with sampled data. Fortunately Linux provide a simple way to capture data from your soundcard.
Next we need a simple algorithm to discriminate the length of the peaks we read from the photodiode:
The results are shown in the picture. Each peak is measured to see how long is it and was that the shortest peaks (shrinked) have a length of around 900 us and the long peak a length of about 1.8 ms.
A simple proof of this values is done by comparing the graph (gnuplot) generated on the raw sampled data and the program result. If we compare the peak type (long/short) and the peak length we will see a “perfect” match.
Now we have do identify and differentiate the remote’s command (which button pressed).
A simple way to do this is using some bitwise operator. Let’s say that if the peak is longer than 1 ms we insert a one (bit) into our command (8 bit uchar), if shorter we insert a zero (bit).
If you take a look in the code above you will see that there is no length check when shifting and inserting new bit into command. therefore the algorithm will take only the last 8 peaks into the command (the other will be “overwritten”).
Trying the program will results in a series of command number that are associated to remote buttons. In the screenshot is shown the result of pressing two different buttons: channel – (CMD: 194), and volume + (CMD: 57) from a Philips remote.
The algorithm needs of course some more improvements since as you see the commands some time are wrong (0, 98, 25).
Now that we have a list of commands associated with buttons we could move the mouse respectfully with the remote you’re using:
Maybe it comes handy sometime to draw the signal direct into the console output, for this reason I’ve created a simple ascii graph function to display my buffer (sampled data) content.