BruteForce code finding in an RGB Infrared LEDstrip

irrgbledNeed:

  • Arduino.
  • IR Infrared RGB lightstrip
  • IR LED 940nm
  • resistor 560ohm

If you have one of those RGB LED strips that come with those standard 24 or 44 key transmitters and you need the IRcodes so you can send them from an Arduino to control your lightstrip, it is easy to use one of the IR libraries, such as that of Ken Shirrif and use the receive sketch to sniff the codes from the receiver. But what if you lost your transmitter or for some reason the receive sketch doesnt recognize it. Well, then there is another possibiliuty: BruteForce

As I understood these IR units usually work with the NEC protocol. I will not bore you with the sync bits and timing and the stopbits as we have the library to take care of that. The essence of the NEC protocol is a 32 bit pulse-train, in which the first byte (8bits) is the address, the second byte is the inverse address, the 3rd byte is the command and the 4th byte the inverse command. With inverse I mean that in binary form all the 1’s and 0’s are switched. So if a specific command would be “10101011” then the inverse is “01010100”. In the mean time I had come across an instructable (but cant find it anymore) of someone who wrote a program to generate codes for his IR controlled lamp). He generated his own 38kHz signal, something I didnt want to do, but it gave me the idea to not sniff my transmitter, but to scan the ledstrip bij sending possible codes to it. Now 32 bits seems like a lot of possible codes but it isnt. Remember how the NEC protocol was build: 1 address byte and 1 control byte. As I had come to understand the address byte didnt really matter (it does though), at most I would have to send 256 codes and single out the 24 (and hopefully more)

/* ********************************
This code quickly checks what codes will work with an IR RGB LEDstrip.
Adapt the delay for a quick scan or for precise jot down of the  code and its effect
02 november 2016
by DIY_bloke
********************************/ 

unsigned long command = 0;
#include  //Ken Shirriff's IRremote.h
IRsend irsend;

byte  al, ar, cl, cr;// the address and command byte and their inverse
unsigned int a, c;// the complete address and command byte
unsigned long totaal = 0L;// the 32 byte long to send to plug into the NEC protocol

void setup() {
  Serial.begin(9600);
  Serial.println("Arduino Ready");
}

void loop() {
  for (al = 0; al < 255; al++)   //we start with address 0
  {
Serial.println(al);
    for (cl = 0x0; cl < 255; cl++) // and with command 0. We first loop through the commands     {       doen(al, cl);        totaal = combineint(c, a);        Serial.print("Address> ");
       Serial.print(al,DEC);
       Serial.print(" Command> ");
       Serial.print(cl,DEC);
       Serial.print("> ");
       //Serial.print(c);
       Serial.print(" Total ");
       Serial.println(totaal,HEX);

      irsend.sendNEC(totaal, 32);
      delay(100); // Optional
    }
  }
}
//makes a long from two integers
unsigned long combineint (unsigned int rechts, unsigned long links)
{
  unsigned long value2 = 0L;
  value2 = links << 16;
  value2 = value2 | (rechts);
  return value2;
}
unsigned int doen(byte ag, byte cg)
{
  ar = ag ^ 0xFF;
  cr = cg ^ 0xFF;
  a = 256 * ag + ar;
  c = cg << 8 | cr;
}

int Combine(byte b1, byte b2)
{
  int combined = b1 << 8 | b2;
  return combined;
}

The program is fairly simple. It defines byte variables for the address and the command It inverts the address and the command so then there are 4 bytes.

It first combines the address bytes and the command bytes each to 1 integer and then it combines the address integer and the command integer to a long variable. Actually this proved to be the hardest part as I encountered some wrong values as I overlooked some variables that needed to be unsigned (Thanks Yoh there for putting me on track again).

Once those 4 bytes are a 32 bit Long, that is fed into the NEC protocol of the IRremote library. The address loops from 0 to 255 and once that is done the address byte increases with 1 and it starts allover again, so there are 256² =65536 possibilities to go through to find 24 codes.

Now obviously that would be a worst case scenario. But even then that can be rather quick. So once you have attached an IR LED to pin 3 (either through a resistor or a decent driver) power up your RGB strip (bij plugging it in the grid) and use your remote to switch it ON. The program will eventually find the ON code, but it would be a pity if that was the last code because then you have missed the activity of the LED strip. There is a delay in the code that you begin to set for 50msec. then start the code. The program then starts going through all commands and address possibilities. Now suppose the 24 codes would all be huddled together in the last 25 spaces of the 65536 possibilities. then it would take you 65512 *50msec= 55min to get to your codes.

That may seem long, but you dont have to do watch. The only thing you need to do is once you see your RGB ledstrip change color, check the serial monitor to see what address range you are at. Then stop the program, change the outer (address) loop to start from that address and set the delay to say 1 second and then note what code causes what effect. Now maybe you are 1 or 2 positions off, but if you know just whereabout it is just try sending the ones around it. I was lucky, ALL my codes where on address page 1 and then it took me about 5 minutes to find them all.

Also, remember that when the IR LED on your arduino is spitting out codes every 50ms your remote wont be able to do much anymore, so dont be surprised if it suddenly seems to ‘not work’ anymore. Cover the IR LED on the arduino and you will see your remote come alive again

Just one remark on IR LED’s
In Ken’s library discussion, he uses a 1 k resistor to directly drive an IR LED from pin 3 of the Arduino. That is definitely possible. However, it will not reach far. IR LEDś can easily be fed with 100mA as they only get small pulses. Obviously an arduino pin is not suitable for that.
a simple transistor driver for 5 Volt, with a series resistor of 33 ohm will usually do nicely. Be sure to check it for your specific situation.

Advertisements