IRremote.h retransmitting IR commands

I have two different TVs (TV1 & TV2), but I want to use the remote for TV1 to also control TV2. As such, I have used the IRremote library to create a quick conversion sketch that watches for signals from remote1 and outputs a corresponding IR code that TV2 can understand. So far I have only mapped the power, mute, and vol up/vol down buttons.

The sketch works fine for push & release actions (eg, I tap the volume up button on remote1 and TV2’s volume goes up one unit), however I can not get it to work for push and hold actions (eg, I push and hold the volume up button on remote1 and TV2’s volume does not change).

I’m sure I’m missing something obvious, but I’m not seeing it.

/*
 TVRemote
 Version: 0.1.0
 */

#include <IRremote.h>

IRsend irsend;
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

long unsigned int irCode;

void loop() {
  if (irrecv.decode(&results)) {
    irCode = results.value;
    Serial.print("Code received: ");
    Serial.println(irCode);
    
    if (irCode == 16191727)
    {
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(0x20DF40BF, 32); // Vol up
      }
      Serial.println("Vol up code sent");
    }
    else if (irCode == 16218757)
    {
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(0x20DFC03F, 32); // Vol down
      }
      Serial.println("Vol down code sent");
    }

    else if (irCode == 16235077)
    {
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(0x20DF906F, 32); // Mute
      } 
      Serial.println("Mute code sent");
    }

    else if (irCode == 16222327)
    {
      for (int i = 0; i < 2; i++) {
        irsend.sendNEC(0x20DF10EF, 32); // Power
      }
      Serial.println("Power code sent");
    }
    irrecv.enableIRIn();
    irrecv.resume(); // Receive the next value
  }
}

IR remotes do a "repeat code" for a held button. For the one I use (forget which protocol) it sends the button code then 0xFFFFFFFF as long as the button is held. Set up the IR receive example and see what is sent with a button held (the repeat code).

I thought that at first, but I cannot find a way to send the “repeat” command usnign the IRremote.h library. Even though the library shows NEC repeat commands as “FFFFFFFF”, this is a “fake” value to indicate a repeat. Sending a “irsend.sendNEC(0xFFFFFFFF, 32);” is not the same thing. How do I actually send a true NEC repeat command with the IRremote library?

Dang if I know. I haven’t used the IRsend. I am curious enough to look into it tomorrow though.

My Google searches for "irremote NEC repeat" have returned a bunch of results about detecting the repeat code when receiving NEC data, but nothing about sending a NEC repeat signal. If you find something, please do let me know.

On another front, I would think I should be able to just the button code over and over to emulate me pushing/releasing the remote button quickly. This however fails; I probably need to add some delay()s and tweak the timing....

I just found this. Maybe help on the timing. http://www.sbprojects.com/knowledge/ir/nec.php

There are at least 2 possible solutions:

  1. IRremote: just use the sendRAW function and provide the timings for the short repeat signal.
  2. Use IRLib which is a more recent rewrite of IRrermote and support the NEC repeat signal when you send FFFFFFFF.

If you need to find the timings google (sb-projects IR NEC)

...Hope that helps

After more testing, my problem seems to be two fold:

1) Both remotes send out a NEC repeat signal, so both the remote I am using and the arduino end up sending out IR data. With the normal commands, this isn't a problem as the TV ignores the IR commands from the remote and by the time the arduino starts transmitting, the remote has stopped transmitting. However, once the repeat commands start, the arduino and remote will both be transmitting the same repeat command at the same time, but slightly off-set. I'm thinking this is confusing the TV. I will ahve to figure out a way to rig up some IR shielding.

2) The way my sketch works is by detecting single commands at a time, and then broadcasting out a single command. I fear that by the time the sketch loops around again and reaches the logic to determine it needs to send out a repeat command, the time between the first command and the repeat has become too great. Not sure how to overcome this...

Just put a delay of circa 250 milliseconds in your sketch before sending out an IR signal. That should avoid any interference. If that doesnt work just increase the delay until it does.

I've played with delays, but I don't think a delay of any amount is going to help with interference since the physical remote is outputting a repeating signal.

If you waited for x ms after the last signal rxed from the remote before you start sending anthing from the Arduino, you should be able to avoid the issues you described.

Maybe you could upload your latest code....?

exactly

for everyone: following code worked for me with the IRLib from Github (GitHub - cyborg5/IRLib: An Arduino library for encoding and decoding infrared remote signals)

/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
 * Version 1.3   January 2014
 * Copyright 2014 by Chris Young http://cyborg5.com
 * Based on original example sketch for IRremote library 
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://www.righto.com/
 */
#include <IRLib.h>

IRsend My_Sender;

void setup()
{
  Serial.begin(57600);
}

void loop() {
  if (Serial.read() != -1) {
    My_Sender.send(NEC,0x1FE10EF, 38);
  for (int i=0;i<100;i++){
    delay(10);
    My_Sender.send(NEC,REPEAT, 38);
  }  }
}

Posting this, because i could not find a solution with Google…

For the Apple Alluminium Remote I captured the signal when holding the button, and the bits for the NEC REPEAT signal are at 0bit. After making the change, it worked. Maybe it can help.

#define NEC_REPEAT   0xFFFFFFFF

void appleRemoteSequence(unsigned long signal, boolean hold) {
 delay(20);
 irsend.sendNEC(signal, 32);
 if (hold) {
   for (int i=0; i<20; i++){
     delay(10);
     irsend.sendNEC(NEC_REPEAT, 0); // NEC REPEAT CODE
   }
 }
}