Trying to re create IR signal from remote that sends out 2 different signals on a single button press

I have a Pioneer SBX-300 soundbar that has an IR remote. I want to emulate some of the IR signals used by the remote so i can programmatically control the soundbar.

Using the IRRemote library i have created the following code to read the IR signal coming from the remote:

#include <IRremote.h>

IRrecv ir(4);

void setup() {
    Serial.begin(115200);
    ir.enableIRIn();
}

void loop() {
    if (ir.decode()) {
        IRData decoded = ir.decodedIRData;
        String hex = String(decoded.decodedRawData, HEX);
        ir.resume();
        if (hex.equals("0")) return; // sometimes blank signals get picked up

        Serial.println("Hex code: " + hex);
        Serial.println("Address: " + String(decoded.address));
        Serial.println("Command: " + String(decoded.command));
        Serial.println("Extra: " + String(decoded.extra));
        Serial.println("Flags: " + String(decoded.flags));
        Serial.println("Protocol: " + String(decoded.protocol));
        Serial.println("NumBits: " + String(decoded.numberOfBits));
        Serial.println();

    }
}

Now when i press for example the power button once i get the following output:

Hex code: 5ea159a6
Address: 166
Command: 161
Extra: 0
Flags: 0
Protocol: 8
NumBits: 32

Hex code: 43bc50af
Address: 175
Command: 188
Extra: 0
Flags: 1
Protocol: 9
NumBits: 32

As you can see, there is 2 different IR signals being sent, each with a different code.

Using a different arduino, i was able to recreate this exact output to the console by using the following code:

#include <IRremote.h>

void setup() {
    IrSender.begin(53);
    IrSender.enableIROut(38);
}

void loop() {
    IrSender.sendNEC(166, 161, 0); //5ea159a6
    delay(7); // edit: 7ms seems to be the minimum delay needed or the receiver wont pick up 2 signals
    IrSender.sendNEC2(175, 188, 0); //43bc50af
    delay(1000);
}

this prints out the exact same result to the console as the remote does, but the soundbar doesnt turn on or off.

My only thought could be that the protocol used by my remote doesnt get picked up correctly by the IRRemote library. I know too little about IR stuff to know if this is the case and how i could go about "reading" and recreating the actual used protocol then.

What is the purpose of that delay?

You probably need to replicate the actual signal sent pretty closely, which may include some critical timing between the two code transmissions.

Sorry i forgot to explain, basically any less delay and it looks like the IRRemote library either cant detect or transmit 2 sequential signals. If i used less delay then either noting would appear in the serial console of the receiver or only the first one occasionally. Therefor i added the delay.

Edit:
i copied a wrong version of the code, i had it at 10ms first. but i did some experimenting and it seems the minimum delay needed is 7ms, else the second signal doesnt get picked up.
i use a leonardo as the receiver and mega as the sender, i hope this doesnt have a direct effect.

The way you are using the IRRemote library is probably not giving you a useful picture of the transmission from the remote.

You need to capture and examine the raw signal of a complete remote transmission. The library has an option to do that.

Right, i did some more experimenting and found out that the receiver code detects the 2 signals with a 90ms delay inbetween. some more testing and i cound out that that means i have to add a 21ms delay on the sending code and then the receiver receives with a 90ms delay, just like the remote.

using

long int last = millis();

void loop() {
    if (ir.decode()) {
        IRData decoded = ir.decodedIRData;
        String hex = String(decoded.decodedRawData, HEX);
        ir.resume();
        if (hex.equals("0")) return;
        long int now = millis();
        long int delay = now - last;
        Serial.println("delay: " + String(delay));
        last = now;

        ir.printIRResultRawFormatted(&Serial);
        Serial.println();

    }
}

i get the following outputs:

rawData[68]: 
 -25750
 +8500,-4200
 + 600,- 500 + 600,-1500 + 600,-1500 + 600,- 500
 + 600,- 450 + 600,-1550 + 600,- 450 + 600,-1550
 + 600,-1500 + 600,- 500 + 600,- 450 + 600,-1500
 + 600,-1550 + 600,- 450 + 600,-1550 + 600,- 450
 + 600,-1550 + 600,- 450 + 600,- 500 + 600,- 450
 + 600,- 450 + 600,-1550 + 600,- 450 + 600,-1550
 + 600,- 450 + 600,-1550 + 600,-1500 + 600,-1550
 + 600,-1500 + 600,- 500 + 600,-1500 + 600,- 450
 + 600
Sum: 64400

delay: 90
rawData[68]: 
 -25800
 +8550,-4200
 + 600,-1500 + 600,-1550 + 600,-1500 + 600,-1550
 + 600,- 450 + 600,-1500 + 600,- 500 + 600,-1500
 + 600,- 500 + 600,- 450 + 600,- 500 + 600,- 450
 + 600,-1500 + 650,- 450 + 600,-1500 + 650,- 450
 + 600,- 450 + 600,- 500 + 600,-1500 + 600,-1550
 + 600,-1500 + 650,-1500 + 600,- 450 + 600,-1550
 + 600,-1500 + 600,-1500 + 650,- 450 + 600,- 450
 + 600,- 500 + 600,- 450 + 600,-1550 + 600,- 450
 + 600
Sum: 64450

which i believe converts to the following sender code:

unsigned int rawData1[] = {
  -25750,
  8500, -4200,
  600, -500, 600, -1500, 600, -1500, 600, -500,
  600, -450, 600, -1550, 600, -450, 600, -1550,
  600, -1500, 600, -500, 600, -450, 600, -1500,
  600, -1550, 600, -450, 600, -1550, 600, -450,
  600, -1550, 600, -450, 600, -500, 600, -450,
  600, -450, 600, -1550, 600, -450, 600, -1550,
  600, -450, 600, -1550, 600, -1500, 600, -1550,
  600, -1500, 600, -500, 600, -1500, 600, -450,
  600
};
unsigned int rawDataLength1 = sizeof(rawData1) / sizeof(rawData1[0]);

unsigned int rawData2[] = {
  -25800,
  8550, -4200,
  600, -1500, 600, -1550, 600, -1500, 600, -1550,
  600, -450, 600, -1500, 600, -500, 600, -1500,
  600, -500, 600, -450, 600, -500, 600, -450,
  600, -1500, 650, -450, 600, -1500, 650, -450,
  600, -450, 600, -500, 600, -1500, 600, -1550,
  600, -1500, 650, -1500, 600, -450, 600, -1550,
  600, -1500, 600, -1500, 650, -450, 600, -450,
  600, -500, 600, -450, 600, -1550, 600, -450,
  600
};
unsigned int rawDataLength2 = sizeof(rawData2) / sizeof(rawData2[0]);

void loop() {
    IrSender.sendRaw(rawData1, rawDataLength1, 38);
    delay(21);
    IrSender.sendRaw(rawData2, rawDataLength2, 38);
    delay(1000);
}

But with this, it looks like the mega is not able to send it fast enough. it seems to take a couple seconds to send each raw data. if i understand it correctly, the numbers mean the delays, and they are quite large. it is the raw data it picked up so i dont know what im doing wrong here then.

Sorry, I have never tried sending two codes.

You may get a more accurate picture of the transmission by using a laptop running Audacity to capture the signal, as described in this tutorial for decoding RF remotes:
https://rayshobby.net/wordpress/reverse-engineer-wireless-temperature-humidity-rain-sensors-part-1/

Using

irReceiver.compensateAndPrintIRResultAsCArray(&Serial, true);

i got an output of the actual microseconds array to send. Turns out my conversion was completely wrong.

So now using the following sender code:

uint16_t rawData1[67] = {8530,4220, 530,520, 580,1570, 530,1570, 580,520, 530,520, 580,1570, 530,520, 580,1570, 530,1570, 580,520, 530,520, 530,1570, 580,1570, 530,520, 580,1570, 530,520, 580,1570, 530,520, 580,520, 530,520, 530,520, 580,1570, 530,520, 530,1620, 530,520, 530,1620, 530,1570, 530,1620, 530,1570, 530,570, 480,1620, 530,520, 530};
IrSender.sendRaw(rawData1, sizeof(rawData1) / sizeof(rawData1[0]), NEC_KHZ);

uint16_t rawData2[67] = {8480,4220, 530,1620, 530,1570, 530,1620, 530,1570, 530,570, 480,1620, 530,520, 530,1620, 530,520, 530,570, 530,520, 530,570, 480,1620, 530,520, 530,1620, 530,520, 530,570, 530,520, 530,1620, 530,1570, 530,1620, 530,1570, 530,570, 480,1620, 530,1620, 480,1620, 530,520, 530,570, 530,520, 530,570, 530,1570, 530,570, 480};
IrSender.sendRaw(rawData2, sizeof(rawData2) / sizeof(rawData2[0]), NEC_KHZ);

i finally got it to work and can now control my soundbar.
Turns out the delay wasnt even necessary.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.