gather this information for each key (0-9) on the
remote that I wanted to emulate. There are 53 delays
to measure for each of the 10 digits which sounds like
a great deal of work. All you have to do, though, is
bump the mouse over from one delay to the next and
record that value (provided by the Saleae program) in
a spreadsheet. It can easily be done in less than an
hour, and you could probably get the timings for all
the other keys on the remote (useful if you want to
change volume, mute, etc.) in a similar amount of
time.
The spreadsheet (Figure 7) made the analysis
easy. First, I could see that each button press
consisted of three subgroups of pulses, separated by
81. 7 µs. While the first subgroup was different from
the second for a particular number, the second and
third subgroups were identical. By the time I had data
for two or three channels, I had figured out that there
were only two numbers in each subgroup that
changed from channel to channel. Really, instead of
gathering 53 10 or 530 delays, I would only need
six for each digit.
To make analysis easier, I decided to highlight the
rows containing the channel-to-channel differences (red),
as well as the medium (blue) and long (green) delays.
This general process will work for any IR device you can
connect to the logic analyzer. Some may use a different
encoding — where the delays are not the significant
elements — but the principle is the same: Look at what
your remote is saying, and then you can program the
Arduino to parrot it back on command.
The pattern for channel-to-channel differences was a
little harder to spot. If you move across the columns
through each red row, you will notice that the delays get
either longer or shorter by 140 microseconds from one
channel to the next. For example, in row 12 we start out
with a delay of 2.85 ms for channel 0, then 2. 71 ms for
channel 1, 2. 57 ms for channel 2, etc. In row 16, our
starting delay is 772 µs for channel 0, then 909 µs for
channel 1, 1.05 ms for channel 2, etc.
The pattern is reasonably simple, except for the
third and fifth set of channel-specific delays (identical to
each other; found in rows 30 and 48). In this row, after
the numbers have dropped by 140 µs per channel down
to 772 µs for channel 7 they jump back up to 2.85 ms
and 2. 71 ms for channels 8 and 9, respectively. Perhaps
delays of 632 µs and 492 µs are too short to be reliable.
Rather than write an algorithm for this, I took the
easy way out and just defined a few arrays to hold all of
the timing data. The program (Figure 8) begins by
preparing a pin (I chose number 10 for no particular
reason) for output, setting it low, and waiting for a
second. This is because the Arduino kept initially setting
the state of the pin high after being declared an output
FIGURE 7. Part of the spreadsheet containing inter-pulse delay times
for all numbers from 0 through 9.
pin, and we need to start with the pin in the low state.
The main loop calls the tx (transmit) function once
with an argument of 2, waits 0.4 seconds, and calls tx
again with an argument of 7. This changes the channel
to 27, and the main loop then goes into an infinite wait
state. The tx function does all of the real work. It’s just
reading in a number from the “batch” array to see how
long to wait between calls of the “pulse” function,
which is what actually sends the eight high/low signals.
The batch array is useful because so much of what has
to be sent for a 2 is identical to what has to be sent for
a 7 or any other number. These constant numbers are
given in the batch array in microseconds.
The only exceptions are for channel-specific data
and for the long 81 ms delay, since delayMicroseconds
won’t work with a number greater than 16383. If the tx
routine encounters a 0, it automatically waits for 81 ms.
The other arrays referencing the three possible unique
delays for a channel are channel1, channel2, and
channel3. If the tx routine encounters a -1, - 2, or - 3, it
reads the correct channel-specific delay from the
corresponding array.
Notice that — at the microsecond level — the speed
of the Arduino itself becomes important. With just the
stated delays, things weren’t working. The pulse function
delays to leave the pin high and low are 3 µs and 13 µs
rather than 8 µs and 18 µs due to the time spent
executing the instructions. The nested if/then/else loop
in the tx function takes significantly longer, so the delay
times are all reduced by 25 µs. Checking the Arduino’s
output with the logic analyzer confirmed that these
February 2012 35