Introduction: Cloning and Learning IR Remote With Arduino

A lot of arduino projects using IR have been described online. Most of them either log the IR codes and then hardcode them in a transmitter script. However, I have automated this learning in one setup. The setup has 7 functional buttons and 1 reset button. When a button is pressed (green LED on) the script checks whether it has already a nIR code assigned. If yes it transmits the code. If not, it waits for the IR receiver to obtain a new IR code. From that point on, that button has that functionality.

If you want to reassign all the buttons you can press the reset button (red LED on), all functionalities are erased. and you can re-assign all functionalities.

In other words, no need to copy-paste and hardcode those codes.

Step 1: LIBRARY

First things first, let's not waste time starting from scratch and look for a useful IR library. OPen up the library manager in the arduino software. Sketsh -> include library -> manage libraries. Type in IRremote and look for the library by Shirriff. There are A LOT of examples about this library online.

One important thing: on the library's github page there are some extra instructions: https://github.com/z3t0/Arduino-IRremote. It mentions:

Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors.

You have to look for this in your program file folders (windows).

Instead of deleting, I moved it to a ZIP so I can return it later if needed.

Step 2: HARDWARE

There are 8 buttons, in a typical configuration with pull-down resistor: GND-RESISTOR-BUTTON-Vcc with a connection to the arduino between the resistor and button. (I needed to extend mly wires, don't be confused by whats going on in G31-H36

The green and red LEDs are also connected with a default Arduino_PIN-RES-LED-GND configuration.

The IR LED (I used 3, it also works for 1, don't know why I have 3, not important...)

The IR receiver only needs three wires. One to Vcc, one to GND, one to Arduino_pin_3. To see what IR-pin is what, check the datasheet... or guess... .

Step 3: SOFTWARE

The arduino ino code is the following. You can remove the print statements but I like them to have some sense of what's going on. One thing you might have to change is the sendSamung method... since you might not need samsung. Changing this to another brand is pretty easy. Check the cpp files in the library: "...\Documents\Arduino\libraries\IRremote" You see all the brands there and if you open the cpp file, you can verify whether it has a send method.

/* MADE BY STECLA, BASED ON THE FOLLOWING LIBRARY EXAMPLE:
* IRremote: IRrecvDump - dump details of IR codes with IRrecv * An IR detector/demodulator must be connected to the input RECV_PIN. * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * http://arcfn.com * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) * LG added by Darryl Smith (based on the JVC protocol) */
#include <irremote.h></irremote.h>
/* 
*  Default is Arduino pin D11. 
*  You can change this to another available Arduino Pin.
*  Your IR receiver should be connected to the pin defined here
*/
int BUTTON_PIN[7] = {2,11,4,5,6,7,8};
int BUTTON_RESET_PIN = 9;
int IRTX_PIN = 3; //This has to be 3 because of the library.
int RECV_PIN = 13;
int LEDG_PIN = 10;
int LEDR_PIN = 12;
long buttonCode[7];
int buttonValue[8];
byte i;
int wantedpos;

bool waitForInput;
IRrecv irrecv(RECV_PIN);
IRsend irsend; decode_results results;
void setup()
{
  for (byte i = 0; i <7; i = i + 1) {
    pinMode(BUTTON_PIN[i],INPUT);
    buttonValue[i] = 0;
    buttonCode[i] = 0x00000000;
  }
  buttonValue[7] = 0;
  pinMode(BUTTON_RESET_PIN,INPUT);
  pinMode(LEDR_PIN,OUTPUT);
  pinMode(LEDG_PIN,OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
void loop() {
  digitalWrite(LEDG_PIN,LOW);
  digitalWrite(LEDR_PIN,LOW);
  //Serial.print("VALUE  =  ");
  for (byte i = 0; i <7; i = i + 1) {
    buttonValue[i] = digitalRead(BUTTON_PIN[i]);
  //  Serial.print(buttonValue[i]);
  }
  buttonValue[7] = digitalRead(BUTTON_RESET_PIN);
  //Serial.println(buttonValue[7]);
  
  if( buttonValue[7]){
    Serial.println("========>RESET<========");
      digitalWrite(LEDR_PIN,HIGH);
      for (byte i = 0; i <7; i = i + 1) {
        buttonCode[i] = 0;
      }
  }else{
    for (byte i = 0; i <7; i = i + 1) {
          if(buttonValue[i] != 0){
            Serial.print("BUTTON ");
            Serial.print(BUTTON_PIN[i]);
            Serial.print(" PRESSED, CURRENT CODE: ");
            Serial.println(buttonCode[i]);
            
            digitalWrite(LEDG_PIN,HIGH);
            if(buttonCode[i] !=0){
              Serial.print("Button has function, sending");
              Serial.println(buttonCode[i]);
//irsend.sendSAMSUNG(0xE0E0E01F, 32); irsend.sendSAMSUNG(buttonCode[i], 32); //delay(40); Serial.println("TRANSMITTED"); delay(50); digitalWrite(LEDG_PIN, LOW); }else{ Serial.println("Button has NO function, waiting"); waitForInput = true; while(waitForInput){ if (irrecv.decode(&results)) { Serial.print("Code : "); Serial.println(results.value, HEX);
for (int i=0; i<7; i++) { wantedpos = -1; if (results.value == buttonCode[i]) { wantedpos = i; break; } } Serial.print(wantedpos); if(wantedpos+1){ irrecv.resume(); // Receive the next value break; } //if (irrecv.decodeSAMSUNG(&results)) { buttonCode[i] = results.value; Serial.print("Code assigned to Button: "); Serial.println(buttonCode[i], HEX); irrecv.resume(); // Receive the next value Serial.print("Check if more result"); Serial.println(results.value, HEX); Serial.println(irrecv.decode(&results)); while(irrecv.decode(&results)){ Serial.print("erasing memory"); irrecv.resume(); // Receive the next value delay(50); } digitalWrite(LEDG_PIN, LOW); waitForInput = false; } } } } } } Serial.print("CODE = "); for (byte i = 0; i <7; i = i + 1) { Serial.print(buttonCode[i], HEX); Serial.print(" "); } Serial.println("-----------"); delay(500);
       
//  for (byte i = 2; i <= 8; i = i + 1) {
//    if(DigitalRead(BUTTON_PIN[i],INPUT);
//  }
//  if (irrecv.decode(&results)) {
//    Serial.println(results.value, HEX);
//    dump(&results);
//    irrecv.resume(); // Receive the next value
//  }
}

Step 4: Conclusion

Some steps to get started:

  • (If you don't have a samsung device you want to record/control, make sure to change the transmit method as described above)
  • Press a button. For now it has no functionality jet. (Press indicated by GREEN LED)
  • Take an IR remote, point it at the IR receiver and push a button. This function is assigned to that arduino button you have pressed in the previous step.
  • From this point on, when you press that arduino button, it will transmit that recorded functionality.
  • Repeat the previous steps for other buttons if you want to clone more behavior.
  • All the functionalities can be erased by pushing the RESET button. (Press indicated by RED LED)
  • enjoy!