IRLib2 RAW data comapre

Hi,

I'm struggling with the idea of being able verify if a certain key on the remote is pressed. The remote I have sends a non-standard IR signal, leaving raw data as the only option. I can receive the raw string values and send them as it is and this works perfectly. However, how to know if a certain key is pressed, so an associated action can be formulated. The rawRecv example prints a string value to the terminal. Is there a way to compare or convert this to some unique number so it can be checked to identify a specific keypress.

Following is the output from the terminal for reference:

Do a cut-and-paste of the following lines into the 
designated location in rawSend.ino

#define RAW_DATA_LEN 68
uint16_t rawData[RAW_DATA_LEN]={
	8798, 4570, 490, 710, 434, 710, 414, 734, 
	430, 714, 410, 738, 430, 714, 434, 710, 
	434, 1782, 410, 1802, 414, 1806, 410, 1806, 
	410, 1802, 410, 1806, 410, 1830, 386, 1806, 
	410, 734, 410, 734, 414, 1802, 438, 710, 
	410, 738, 406, 734, 438, 710, 410, 734, 
	434, 710, 438, 1778, 414, 730, 434, 1786, 
	410, 1802, 434, 1782, 414, 1802, 410, 1802, 
	438, 1778, 410, 1000};

Any help is appreciated.

yes you need to compare the bytes your received with the bytes you expect.

you could use memcmp() to compare two arrays

are you using this code ?

if so, you could try this (typed here, fully untested)

#include <IRLibRecvPCI.h>

const byte IRReceivePin = 2;
const size_t RAW_DATA_LEN = 68;
uint16_t rawData[RAW_DATA_LEN] = {
  8798, 4570, 490, 710, 434, 710, 414, 734,
  430, 714, 410, 738, 430, 714, 434, 710,
  434, 1782, 410, 1802, 414, 1806, 410, 1806,
  410, 1802, 410, 1806, 410, 1830, 386, 1806,
  410, 734, 410, 734, 414, 1802, 438, 710,
  410, 738, 406, 734, 438, 710, 410, 734,
  434, 710, 438, 1778, 414, 730, 434, 1786,
  410, 1802, 434, 1782, 414, 1802, 410, 1802,
  438, 1778, 410, 1000
};

IRrecvPCI myReceiver(IRReceivePin);


void setup() {
  Serial.begin(115200);
  myReceiver.enableIRIn(); // Start the receiver
  Serial.println(F("Ready to receive IR signals"));
}

void loop() {
  if (myReceiver.getResults()) {
    if (recvGlobal.recvLength == RAW_DATA_LEN) {
      // size is correct, let's check the bytes
      if (memcmp(recvGlobal.recvBuffer, rawData, sizeof rawData) == 0) {
        Serial.println("GOT A MATCH");
      } else {
        Serial.println("SAME SIZE BUT NO MATCH");
      }
    } else {
      Serial.println("NOT EXPECTED SIZE");
    }
    myReceiver.enableIRIn();      //Restart receiver
  }
}

Thanks a lot for the quick reply.
Yes, I'm using the same code as you have linked.

The code you have provide allowed me to compare the length of the code. The size is same, however there is no match. I believe this can be attributed to the remote in question. I later took a closer and realized that the code the remote sends is different for the same key. There are numbers that repeat, but with slight variations. Please have a look below:

uint16_t rawData[RAW_DATA_LEN]={
	362, 334, 134, 314, 130, 646, 150, 634, 
	150, 462, 150, 798, 146, 294, 154, 298, 
	150, 298, 146, 302, 146, 630, 134, 482, 
	146, 630, 150, 298, 150, 298, 146, 798, 
	134, 314, 134, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 334, 114, 334, 110, 670, 110, 670, 
	110, 502, 110, 838, 110, 338, 110, 334, 
	110, 338, 110, 670, 110, 670, 110, 502, 
	110, 670, 110, 334, 114, 334, 110, 838, 
	110, 338, 106, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 110, 338, 106, 670, 114, 670, 
	106, 506, 110, 838, 110, 334, 114, 334, 
	110, 330, 114, 338, 110, 670, 110, 502, 
	110, 670, 114, 334, 110, 338, 106, 842, 
	106, 334, 114, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 110, 334, 114, 666, 110, 670, 
	110, 506, 110, 838, 106, 334, 114, 334, 
	110, 338, 110, 670, 110, 670, 114, 498, 
	110, 670, 114, 334, 110, 334, 114, 838, 
	106, 338, 110, 1000};

I have tried three sensors for this purpose. 38Khz (TSSP4P38), 56Khz (TSSP4056) and 40Khz (TSOP34840). The values with 38Khz sensor are most consistent and also they're the ones that work when the raw data is sent through the IR LED. So I believe the IR transmitter works at 38Khz.

Are the values different because of the frequency of the IR receiver? Should I try 36Khz IR receiver too? I do not have the component, so that has to be ordered.

The typical frequency of an IR signal from a remote control is usually around 38 kHz so you should stick to such a receiver.


OK I'm not surprised.

The raw data in your case represents the pulse lengths (in microseconds) and the gaps between pulses that form the IR signal

For instance, if the raw data looks like this:

This means:

  • 8798: The length of the initial pulse (signal start).
  • 4570: The gap after the first pulse.
  • 490, 710, 434, etc.: Subsequent pulse and gap lengths.

When capturing raw data from a non-standard IR remote, you might see variability in these lengths due to factors like distance, angle, and environmental interference so it's not surprising you see variability and that a plain compare won't be able to cut it.

May be a simple "tolerance" factor would do

#include <IRLibRecvPCI.h>

const byte IRReceivePin = 2;
const size_t RAW_DATA_LEN = 68;
uint16_t rawData[RAW_DATA_LEN] = {
  8798, 4570, 490, 710, 434, 710, 414, 734,
  430, 714, 410, 738, 430, 714, 434, 710,
  434, 1782, 410, 1802, 414, 1806, 410, 1806,
  410, 1802, 410, 1806, 410, 1830, 386, 1806,
  410, 734, 410, 734, 414, 1802, 438, 710,
  410, 738, 406, 734, 438, 710, 410, 734,
  434, 710, 438, 1778, 414, 730, 434, 1786,
  410, 1802, 434, 1782, 414, 1802, 410, 1802,
  438, 1778, 410, 1000
};
const uint16_t toleranceFactor = 50;  // Set a tolerance of 50 microseconds

IRrecvPCI myReceiver(IRReceivePin);


bool isMatch(const uint16_t* a, const uint16_t* b, size_t length) {
  for (size_t i = 0; i < length; i++) {
    if (abs((int32_t)a[i] - (int32_t)b[i]) > TOLERANCE) 
      return false;
    }
  }
  return true;
}

void loop() {
  if (myReceiver.getResults()) {
    if (recvGlobal.recvLength == RAW_DATA_LEN) {
      // size is correct, let's check the bytes with tolerance
      if (isMatch(recvGlobal.recvBuffer, rawData, RAW_DATA_LEN)) {
        Serial.println("GOT A MATCH");
      } else {
        Serial.println("SAME SIZE BUT NO MATCH");
      }
    } else {
      Serial.println("NOT EXPECTED SIZE");
    }
    myReceiver.enableIRIn();      // Restart receiver
  }
}

if it does not work, then it would be helpful to see 10 or 15 raw data recording, to see how much they differ and if 50µs is not enough of a tolerance. If you look at the IRRemote library, the author wrote

And believe me, if you send a 525 µs signal, your receiver will output something between around 400 and 700 µs!

may be you need to take a % of the value instead of a fixed tolerance...

Conversely, if you encounter too many false positives, reducing the tolerance might help.

Thanks again for the quick reply. I tried the code you have suggested, although it seems like it should work with different tolerance values, however, the signal sent by the remote is deviating too much. Here's the code again that I tried:

#include <IRLibRecvPCI.h>

const byte IRReceivePin = 2;
#define RAW_DATA_LEN 26
uint16_t rawData[RAW_DATA_LEN]={
	394, 750, 86, 694, 90, 690, 86, 530, 
	86, 858, 118, 774, 86, 1142, 86, 694, 
	86, 526, 86, 694, 90, 762, 186, 802, 
	118, 1000};
const uint16_t toleranceFactor = 50;  // Set a toleranceFactor of 50 microseconds

IRrecvPCI myReceiver(IRReceivePin);


bool isMatch(const uint16_t* a, const uint16_t* b, size_t length) {
  for (size_t i = 0; i < length; i++) {
    if (abs((int32_t)a[i] - (int32_t)b[i]) > toleranceFactor)
      return false;
  }
  return true;
}

void setup() {
  Serial.begin(115200);
  myReceiver.enableIRIn();  // Start the receiver
  Serial.println(F("Ready to receive IR signals"));
}

void loop() {
  if (myReceiver.getResults()) {
    if (recvGlobal.recvLength == RAW_DATA_LEN) {
      // size is correct, let's check the bytes with toleranceFactor
      if (isMatch(recvGlobal.recvBuffer, rawData, RAW_DATA_LEN)) {
        Serial.println("GOT A MATCH");
      } else {
        Serial.println("SAME SIZE BUT NO MATCH");
      }
    } else {
      Serial.println("NOT EXPECTED SIZE");
    }
    myReceiver.enableIRIn();  // Restart receiver
  }
}

I still receive a match for the size, but not for the signal itself.

This doesn't look like valid signal anymore...
Try to receive in dark room to see if you have light interferences
You have to get rid of those short pulses here and there

Valid signal, even with high tolerances can be decoded:

8798, 4570, 490, 710, 434, 710, 414, 734,
  430, 714, 410, 738, 430, 714, 434, 710,
  434, 1782, 410, 1802, 414, 1806, 410, 1806,
  410, 1802, 410, 1806, 410, 1830, 386, 1806,

This for example has headers an then 000000011111111

Thank you for the reply. I have taken recent samples of the signal. These correspond to the same key . The remote is in direct line of sight placed 2 meters away from the sensor. The samples show a similar deviation. I also checked the batteries, (both show 1.45v).

#define RAW_DATA_LEN 36
uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 110, 338, 110, 666, 114, 670, 
	110, 502, 114, 834, 110, 338, 110, 338, 
	106, 334, 114, 670, 110, 670, 110, 502, 
	110, 674, 106, 338, 110, 338, 110, 834, 
	114, 334, 110, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	358, 338, 110, 334, 114, 670, 126, 650, 
	134, 482, 126, 818, 134, 314, 110, 334, 
	114, 334, 110, 666, 134, 650, 110, 502, 
	110, 670, 130, 314, 114, 334, 110, 838, 
	130, 318, 106, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 334, 114, 334, 110, 670, 130, 650, 
	110, 502, 130, 814, 134, 314, 110, 338, 
	110, 334, 110, 670, 130, 654, 126, 486, 
	130, 646, 114, 334, 110, 334, 110, 838, 
	130, 318, 110, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 110, 330, 114, 670, 114, 666, 
	114, 502, 110, 838, 110, 338, 106, 334, 
	114, 334, 114, 338, 106, 670, 114, 502, 
	106, 674, 106, 338, 110, 338, 110, 834, 
	114, 334, 110, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	358, 338, 130, 318, 110, 670, 126, 650, 
	134, 482, 130, 818, 130, 310, 114, 338, 
	110, 338, 106, 334, 114, 670, 126, 482, 
	134, 650, 110, 334, 114, 334, 106, 838, 
	134, 314, 110, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 130, 318, 106, 670, 130, 650, 
	130, 482, 134, 814, 130, 310, 118, 334, 
	110, 334, 114, 334, 110, 670, 130, 486, 
	130, 646, 134, 314, 110, 334, 110, 838, 
	130, 314, 114, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 338, 110, 338, 110, 666, 114, 670, 
	110, 502, 110, 838, 110, 334, 114, 330, 
	114, 334, 114, 670, 110, 670, 110, 506, 
	106, 670, 114, 330, 114, 334, 114, 838, 
	110, 334, 110, 1000};

uint16_t rawData[RAW_DATA_LEN]={
	362, 334, 110, 338, 110, 666, 134, 650, 
	126, 486, 130, 818, 130, 314, 114, 326, 
	114, 334, 114, 338, 110, 670, 130, 482, 
	130, 650, 130, 318, 110, 334, 110, 838, 
	130, 314, 114, 1000};

Any of these samples will work perfectly when transmitted through the RawSend example. So, I believe the samples are captured properly. The only requirement is to verify if a certain key is pressed.

Much better!
header 350,350, then the code. But there is not a clear 1/0 timing pattern like on the example I "decoded". You have 330, 500,650 and 830
You could find "manually" the bits that changes between different buttons and compare only those on your code.
If you didn't try arduino ir-remote yet give it a try, maybe it can decode it. It's nice library anyway, very well documented also.

the values are very different than the ones you shared initially

const size_t RAW_DATA_LEN = 68;
uint16_t rawData[RAW_DATA_LEN] = {
  8798, 4570, 490, 710, 434, 710, 414, 734,
  430, 714, 410, 738, 430, 714, 434, 710,
  434, 1782, 410, 1802, 414, 1806, 410, 1806,
  410, 1802, 410, 1806, 410, 1830, 386, 1806,
  410, 734, 410, 734, 414, 1802, 438, 710,
  410, 738, 406, 734, 438, 710, 410, 734,
  434, 710, 438, 1778, 414, 730, 434, 1786,
  410, 1802, 434, 1782, 414, 1802, 410, 1802,
  438, 1778, 410, 1000
};

may be instead of taking a fixed 50µs tolerance , take a 20% bracket (10% below, 10% above)

Yes, it is my mistake, I was trying many remotes (literally all I have at hand) to see the cause of this erratic behaviour. In that moment I copied the sample from a different remote.

The samples posted from my second post onward are from the remote in question.

Thanks for the post, I'm not sure if this is in my capacity. I see almost all values vary at some point in time in one sample or another. Not sure which value signify a certain key.

As discussed, usually the values represent timing data for pulses and gaps. Since the arduino does not have a perfect clock and the emission might vary somewhat due to environmental interference, it's normal to see different numbers in the raw data.

I have tried the suggested library, just to see if there was a chance that might work. Here is the out put from IRemote library example ReceiveDump:

uint16_t rawData[35] = {480,220, 230,220, 180,570, 230,570, 180,420, 180,770, 180,270, 180,270, 180,220, 230,220, 180,620, 180,420, 180,570, 230,220, 180,270, 180,770, 180,270, 180};  // Protocol=UNKNOWN Hash=0xD0065CE1 18 bits (incl. gap and start) received


Pronto Hex as string
char prontoData[] = "0000 006D 0012 0000 0014 0007 000A 0007 0008 0014 000A 0014 0008 000F 0008 001C 0008 0009 0008 0009 0008 0007 000A 0007 0008 0016 0008 000F 0008 0014 000A 0007 0008 0009 0008 001C 0008 0009 0008 06C3 ";


Protocol=UNKNOWN Hash=0xD0065CE1 18 bits (incl. gap and start) received
Received noise or an unknown (or not yet enabled) protocol


Raw result in internal ticks (50 us) - with leading gap
rawData[36]: 
 -1777
 + 9,- 5
 + 4,- 5 + 4,-11 + 4,-12 + 4,- 8
 + 4,-14 + 5,- 4 + 5,- 4 + 4,- 5
 + 4,- 5 + 4,-11 + 4,- 8 + 5,-11
 + 4,- 5 + 4,- 5 + 4,-14 + 5,- 4
 + 4
Sum: 212
Raw result in microseconds - with leading gap
rawData[36]: 
 -88850
 + 450,- 250
 + 200,- 250 + 200,- 550 + 200,- 600 + 200,- 400
 + 200,- 700 + 250,- 200 + 250,- 200 + 200,- 250
 + 200,- 250 + 200,- 550 + 200,- 400 + 250,- 550
 + 200,- 250 + 200,- 250 + 200,- 700 + 250,- 200
 + 200
Sum: 10600

Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[35] = {9,5, 4,5, 4,11, 4,12, 4,8, 4,14, 5,4, 5,4, 4,5, 4,5, 4,11, 4,8, 5,11, 4,5, 4,5, 4,14, 5,4, 4};  // Protocol=UNKNOWN Hash=0xD0065CE1 18 bits (incl. gap and start) received

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[35] = {430,270, 180,270, 180,570, 180,620, 180,420, 180,720, 230,220, 230,220, 180,270, 180,270, 180,570, 180,420, 230,570, 180,270, 180,270, 180,720, 230,220, 180};  // Protocol=UNKNOWN Hash=0xD0065CE1 18 bits (incl. gap and start) received


Pronto Hex as string
char prontoData[] = "0000 006D 0012 0000 0012 0009 0008 0009 0008 0014 0008 0016 0008 000F 0008 001A 000A 0007 000A 0007 0008 0009 0008 0009 0008 0014 0008 000F 000A 0014 0008 0009 0008 0009 0008 001A 000A 0007 0008 06C3 ";


try the output with receive_demo as well

Ok, here's the output from ReceiveDemo. I noticed something different here. Below is a sample from one random key:

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -3276750
 + 450,- 250
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 300 + 150,- 250
 + 200,- 600 + 150,- 600 + 150,- 450 + 200,- 600
 + 150,- 300 + 150,- 250 + 200,- 750 + 150,- 450
 + 200
Sum: 11100

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88850
 + 400,- 300
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 250 + 200,- 250 + 200,- 250
 + 150,- 650 + 150,- 600 + 150,- 450 + 150,- 650
 + 150,- 250 + 200,- 250 + 150,- 800 + 150,- 450
 + 150
Sum: 11050

and here is the sample from the key in question from the remote:

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -3276750
 + 400,- 250
 + 150,- 300 + 150,- 650 + 150,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 300 + 150,- 250
 + 200,- 250 + 200,- 600 + 150,- 450 + 150,- 600
 + 200,- 250 + 150,- 300 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88850
 + 400,- 300
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 250 + 200,- 250
 + 150,- 300 + 150,- 600 + 200,- 450 + 150,- 600
 + 150,- 300 + 150,- 300 + 150,- 750 + 200,- 250
 + 150
Sum: 10550

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88900
 + 400,- 300
 + 150,- 250 + 200,- 600 + 150,- 600 + 200,- 450
 + 150,- 750 + 200,- 250 + 150,- 300 + 150,- 300
 + 150,- 300 + 150,- 600 + 150,- 450 + 150,- 650
 + 150,- 250 + 200,- 250 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

There are distinct three sections in the latter sample. Except this key, all other keys have two sections. So, maybe if we can just identify this behaviour and isolate it, the key in question can be identified from the rest (because others have two sets of code.

Sorry, I don't have all the samples you have, can you highlight it?

No issues. I do not know how to highlight, so I'm trying to make it make it look distinct.
All samples are taken with single momentary key press. If there is a repeat, that is from the remote.

The key in question transmits this type of code. There are always three distinct sections as you can see below:

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -3276750
 + 400,- 250
 + 150,- 300 + 150,- 650 + 150,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 300 + 150,- 250
 + 200,- 250 + 200,- 600 + 150,- 450 + 150,- 600
 + 200,- 250 + 150,- 300 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88850
 + 400,- 300
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 250 + 200,- 250
 + 150,- 300 + 150,- 600 + 200,- 450 + 150,- 600
 + 150,- 300 + 150,- 300 + 150,- 750 + 200,- 250
 + 150
Sum: 10550

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88900
 + 400,- 300
 + 150,- 250 + 200,- 600 + 150,- 600 + 200,- 450
 + 150,- 750 + 200,- 250 + 150,- 300 + 150,- 300
 + 150,- 300 + 150,- 600 + 150,- 450 + 150,- 650
 + 150,- 250 + 200,- 250 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

All other keys on the remote, transmit this type of code. Please note there are only two sections.

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -3276750
 + 450,- 250
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 300 + 150,- 250
 + 200,- 600 + 150,- 600 + 150,- 450 + 200,- 600
 + 150,- 300 + 150,- 250 + 200,- 750 + 150,- 450
 + 200
Sum: 11100

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88850
 + 400,- 300
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 250 + 200,- 250 + 200,- 250
 + 150,- 650 + 150,- 600 + 150,- 450 + 150,- 650
 + 150,- 250 + 200,- 250 + 150,- 800 + 150,- 450
 + 150
Sum: 11050

I don't follow you, maybe I'm tired... You mean that 650 vs 300?

-88850

  • 400,- 300
  • 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
  • 150,- 800 + 150,- 250 + 200,- 250 + 200,- 250
  • 150,- 650 + 150,- 600 + 150,- 450 + 150,- 650
  • 150,- 250 + 200,- 250 + 150,- 800 + 150,- 450
  • 150
    Sum: 11050

Oh. No, not the numbers. When the key I want to be able to recognize, is pressed:

-3276750
 + 400,- 250
 + 150,- 300 + 150,- 650 + 150,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 300 + 150,- 250
 + 200,- 250 + 200,- 600 + 150,- 450 + 150,- 600
 + 200,- 250 + 150,- 300 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

and

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88850
 + 400,- 300
 + 150,- 300 + 150,- 600 + 200,- 600 + 150,- 450
 + 150,- 800 + 150,- 300 + 150,- 250 + 200,- 250
 + 150,- 300 + 150,- 600 + 200,- 450 + 150,- 600
 + 150,- 300 + 150,- 300 + 150,- 750 + 200,- 250
 + 150
Sum: 10550

and this

Received noise or an unknown (or not yet enabled) protocol
rawData[36]: 
 -88900
 + 400,- 300
 + 150,- 250 + 200,- 600 + 150,- 600 + 200,- 450
 + 150,- 750 + 200,- 250 + 150,- 300 + 150,- 300
 + 150,- 300 + 150,- 600 + 150,- 450 + 150,- 650
 + 150,- 250 + 200,- 250 + 150,- 800 + 150,- 300
 + 150
Sum: 10550

Appear together in the output. I have only pressed the key once. I was expecting a single output.

So you mean it's sent 3 times instead of 2.
I don't know if that's reliable way of picking a code, maybe longer button push gives different results. It's typical to send signal twice.

What about that ~650 vs ~300 I highlighted, is it constant difference?
Play with your remote until you have good solid flag to use.