Saturday September 23 2017

Hacking and Controlling NEC-IR Devices

In this tutorial you will learn how to ascertain the protocol of most NEC-IR devices, and then use an Arduino to replicate signals and thus control said device(s).

There are a lot of devices like this: TV/DVD/etc Remote Controllers, a whole whack of toys (if your toy uses IR, it likely uses NEC-IR), and even cameras.

So for this tutorial I will go through hacking two different toys: one with discrete buttons (Inchworm), and one with ‘throttle-sticks’ (S107).  Covering those covers any type of controller I know (what’s different than buttons and sticks right?).

Here is a quick video of the final result (only really a proof of concept).

 

********************************
********** Quick  Links ***********
********************************

IRToy Arduino Code
(to control either, or both, the Inchworm and the S107 Helicopter via Serial CMDs)

IRToy GUI Processing Code
(Very basic code to send the Serial CMDs)

IR Recorder Arduino Code
(to capture IR signals)

 

 

****************************************************
***************  Recording and Hacking  ****************
****************************************************

NEC-IR is pretty easy to record, the value zero and one are differentiated by the duration of a standard pulse pattern.

For example, say the pulse frequency is 38KHz (most stuff is), and the pulse duration is 300us (micro-seconds). Then Zero could be a 38KHz pulse ON for 300us and then OFF for 300us, and the One could be a 38KHz (frequency never changes between zero and one, it is more like a constant) pulse ON for 300us and then OFF for 600us.  So by being off for 600us as opposed to just 300us, we know that means ONE.

The other part to NEC-IR is the concept of a header and footer (lots of communication protocols use these to align to the data; makes for a more robust design).  So there will be a header pulse ON for 2-4ms (milli seconds), followed by OFF for likely a shorter length.  The footer will be the opposite,  ON for a shorter time and then OFF for 2-4ms (I normally just say off for 65ms, that way you can just send CMDs constantly).

 

I took some code from here and augmented it for my setup and also to capture windows  (that link also has more info on NEC-IR).

Here is my RecorderCode and a pic of my dead easy setup:

 

You can buy IR detectors almost anywhere nowadays, but here’s one that seems good (I used a: GP1UM26XK00F).  Also, you may want to note that I used a 40KHz receiver to detect 38KHz signals, they are so close, the only thing that might happen is attenuation (so if you use a freq != to the LED, just be sure they are close [~10cm] , maximizing signal amplitude).

My code assumes PIN2=Vout, PIN3=GND, and PIN4=VCC (also seen in the above pic).

I setup the code to capture a window when armed, so once you program your Arduino and startup the serial monitor (Shift+Ctrl+M), all you have to do is send: ‘Arm_’   to arm it,  and ‘clc_’ to clear (actually the _ can be any non-alpha character).

Once the thing is armed it will say so and spit out some GARBAGE data, next you push the button.

 

The easy way (that might mess up) is just push the button.

The more accurate way is to gather LOTS of data, so when pushing the button, cover the transmitting LED with your hand before pushing, and use your hand like a shutter on a camera. ‘Expose’ until you see the phrase “Ring Buffer Looped”, that means you filled up the memory (and likely caught the entire frame).

 

Recording the Inchworm toy:

So for this toy, the output for the ‘up’ button was:

Ready to be Armed! 
Armed! 

                  (Here's the garbage data you ignore)
Received: (TimeON     TimeOFF)usec 
400 100 
300 100 
                  ... more lines
260 100 
220 100 
260 0 

                  (Now I push the button)
Ring Buffer Looped 
Ring Buffer Looped 
Ring Buffer Looped 
Ring Buffer Looped
Ring Buffer Looped

Received: (TimeON 	TimeOFF)usec
260 360
420 500
460 480
               ... more numbers, and then a pattern seems to emerge
2040 380
2040 860
460 1440
480 480
480 480
460 500
460 500
480 480
480 1420
480 1420
480 1420
480 1420
480 42604
2040 380
2040 860
480 1420
480 480
480 480
480 480
480 480
480 480
480 1420
480 1440
460 1440
460 1440
460 42604
2040 380
2040 860
480 1420
480 480
480 480
480 480
480 480
480 480
480 1420
480 1420
480 1440
460 1440
460 42604
2040 380
2040 860
460 1440
460 500
460 500
460 500
460 500
480 480
460 1440
480 1420
480 1420
480 1420
480 42584
and more numbers..
The window is very large.

 

So if you look closely, you can see the most common pattern is:

2000 400   header  (note that you will need to add 2ms, so it's really: 4000 400)
2000 800   header
400 1400   1
400 500    0
400 500    0
400 500    0
400 500    0
400 500    0
400 1400   1
400 1400   1
400 1400   1
400 1400   1
400 big#   footer

And that’s the code (1000001111)!

(For sending, skip ahead to the next section)

 

Recoding the S107 Helicopter:

This is different because we know that there are a whole range of CMDs that can be sent.  So we change our thinking from finding single codes to finding WHERE the numbers are in the code.

So when you record, be sure to have the joy sticks at max positions (and again with them at min), collecting until the buffer fills.  And again, be sure to cover the transmitting LEDs before releasing/setting the joy stick (otw you will send all the commands in-between or after).

After looking over a few recordings, covering all controls at max and at min (took me quite a few runs), you should notice that there’s clearly 4 8-bit values with a header and footer making:

4ms ON,  2ms OFF (header),  4×8 bit values with One (300us ON, 600us OFF) and Zero (300us ON, 300us OFF), and a footer of: 360us ON, 65ms OFF.

The 4 8-bit values are (in time):

first: Yaw Adjust (0->127, with 63–>zero adjust)

second: Throttle (0->126,  and the MSB is the Channel, in case you have two S107s)

third: Pitch (0->127, with 63–>zero pitch)

forth: Yaw (0->127, with 63–>centred yaw)

All the complete details are found in the Arduino Code for the IRToy.

 

 

****************************************************
********************  Controlling  *********************
****************************************************

I whipped up some code for controlling the two toys above, so you have a reference and something to plug and chug.

Note the Arduino Code has the option of burst or not (the difference is burst means flash pins 8-11 instead of just flashing 8), burst is on by default (because if you don’t use the output pin, no current flows, so you’re not wasting anything).

 

Arduino IRToy Code, Processing GUI IRToy Code (Very basic, mostly just does the serial for you)