Learn to Translate IR Codes and Retransmit Using Arduino

[Dave Jones] from EEVBlog.com takes “Arduino fan boys” off the garden path getting down and dirty with different methods to capture, evaluate and retransmit IR remote control codes. Capturing and reproducing IR remote control codes is nothing new, however, [Dave] carves his own roads and steers us around some “traps for young players” along the way.

[Dave] needed a countdown timer that could remotely start and stop recording on his Cannon video camera, which he did with simplicity in a previous EEVBlog post using a commercial learning remote control unit. The fans demanded better so he delivered with this excellent tutorial capturing IR codes on his oscilloscope from an IR decoder (yellow trace) as well as using an IR photo transistor (blue trace) which showed the code inclusive of 38 KHz carrier frequency. Either capture method could easily be used to examine the transmitted code. The second lesson learned from the captured waveforms was the type of code modulation being used. [Dave’s] remote transmitted NEC (Japanese) pulse length encoding — which can be assertaind by referencing the Infrared Remote Control Techniques (PDF). Knowing the encoding methodology it was trivial to manually translate the bits for later use in an Arduino transmitter sketch. We find it amazing how simple [Dave] makes the process seem, even choosing to write his own sketch to reproduce and transmit the IR codes and carrier instead of taking the easy road looking for existing libraries.

A real gem of knowledge in the video was when it didn’t work! We get to follow along as [Dave] stumbles before using a Saleae Logic analyzer to see that his transmitter was off frequency even though the math in his sketch seemed correct. Realizing the digital write routine was causing a slowdown he fudged his math to make the needed frequency correction. Sure, he could have removed the performance glitch by writing some custom port control but logic dictates using the fastest and simplest solution when hacking a one-off solution.

[Dave’s] video and links to source code after the break.

Dave’s Arduino sketch

27 thoughts on “Learn to Translate IR Codes and Retransmit Using Arduino

  1. I recently did tests with the IR sensor of a broken dvd player. The frenquencies of the signals are below 44kHz, wich means you can use the microphone input of your computer and audacity to record the input. Adding an RC filter and a transistor amplifier improves the quality of the capture.

  2. I’m really gunna have to get this working!!
    My girlfriend finds the number of buttons on my Sony TV remote confusing!

    Even the laminated cheat sheet didn’t help!

    now to figure out how to get 56 buttons down to maybe 6…

    1. the problem may not be the remote. I suggest replacement of girlfriend immediately.
      Disease could spread to small children in the area.

    2. Ch+/-, Vol+/-, on&off, information
      Six buttons, this should be nice for elders.
      I suggest to you, as Sony is a very widespread brand, that maybe it has been recorder before and you don’t need to do this if you don’t want. It’s ok if it’s for learning.

  3. Yeah ran into this one too recently trying to get an arduino to interface with a particular serial protocol. It seems an arduino uno digitalWrite takes about 8ms which you have to factor into timing.

  4. //NOTE: digitalWrite takes about 3.5us to execute, so we need to factor that into the timing.

    WTF. Crappy abstraction layer turns a 2-cycle instruction into 3.5 microseconds.

    1. I wondered why I always hear folks complaining about digital I/O speed on the Arduino. Now I know.

      That is indeed crappy. I use a self-written abstraction layer on the PIC. My plain digital pin write function probably isn’t much faster. But I have an alternate method for faster, repeated accesses to any pin, that maintains abstraction.

      1) Create a FastPin structure.
      2) Call the FastPinInit function with the structure, desired pin, and other options. It does the requiring parameter checks and abstraction work, *once*, and fills out the structure with the required raw data for future accesses – port addresses, bit numbers, etc.
      3) Then call one of the FastPin inline functions, like FastPinWrite, with the structure and value. Execution time is 0.5us, worst-case.

      Why doesn’t the Arduino have an equivalent?

      1. I just make my own abstraction layer that actually makes sense, for instance in this case, I could add ‘led_ir_on()’ and ‘led_ir_off()’. Both functions would be defined inline and write directly to the hardware. If ported to different hardware, the functions would be rewritten to take advantage of the specific hardware capabilities. For instance, you could move the IR LED to a pin on a ’595 shift register, and still have the same abstraction. You couldn’t do that with the I/O pin library, or whatever Arduino uses.

    2. For a single port pin access, the pin mapping to a real port could be
      and should be done at compile time. Not sure why someone would use
      that level of abstraction to toggle a single pin.

      Atmel messed up the I/O ports arrangements such a way that getting a
      contiguous 8-bit port was painful, so some way of rearranging was
      necessary. Arduino choose a very painful abstraction.

      In my case I ditched the serial port and use port D as a 8-bit port.
      I was able to use my ATMega8 to emulate an ISA bus cycle to write to an
      I/O port on a 8255 a few times faster than 3.5us.

  5. Hmmm note there’s a bit of misinformation in that video, likely due to a cheap crappy piss poor implementation of the NEC protocol in the remote he’s using as an example.

    NEC remotes do NOT normally send the same signal over and over again. If you hold a button down you’ll get the full command once, and 108ms later you’ll get a single start bit with a shorter 2.25ms gap. This is the repeat code. Very easy to handle in code too since it’s shorter than the normal start bit.

    Altium has a good description of the protocol here:

    http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol

    1. According to the protocol, the 2nd address byte should be an inverse of the first, but that’s not the case either. First byte is 11000001 and second is 11000111.

    2. According to the JP1 remote program, there are multiple variations of
      NEC protocols. My TV’s NEC IR code is with the inverted code for 2nd
      byte.

  6. “We find it amazing how simple [Dave] makes the process seem, even choosing to write his own sketch to reproduce and transmit the IR codes and carrier instead of taking the easy road looking for existing libraries”

    He’s toggling a pin. It’s not exactly rocket surgery.

  7. Hi,
    Recently I’ve made something like this, but in my version you could decode any IR without oscilloscope (in theory …). It’s very, very primitive, but it works :), and you can connect it to raspberry pi by i2c.

    Here is description:

    http://morethanuser.blogspot.com/2013/05/ir-remote-decoding.html

    Source code:

    http://morethanuser.blogspot.com/2013/05/ir-remote-emulator-with-attiny45.html

    And working example:

    http://morethanuser.blogspot.com/2013/05/raspberry-pi-and-android-simple-remote.html

    Regards,
    Igor.

  8. This Dave Jones guy seems to like to put his face in every video, and it’s disturbing. He seems to be king narcissist of these lands…

    How many of his fans live in their mother’s basement?

    Methinks most of them ;)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s