IR Receiver receives incorrect NEC Code

Hi,

I'm working on a project where I've got 2 arduinos, one connected to an IR transmitter and one connected to an IR receiver (both from the same pack purchased off Amazon).

I am trying to have one arduino output different hexadecimal codes which causes the other arduino to output different colours on a connected LED.

I've got the transmitter arduino code working which outputs different hexadecimal codes when different MIDI notes are received which I can verify works as it changes the colours on an LED strip that has an IR receiver built in.

The part that is not working is the code I've written for the receiver arduino. I've set it to output the received hexadecimal code to the serial monitor but it seems to output random codes with little consistency. I've tried using a random IR remote I had lying around and the issue still occurs.

I'd appreciate an help with debugging my code.

Transmitter code (working)

#include <IRremote.h>
#include <MIDI.h>

#define IR_PIN 2

IRsend irsend;

MIDI_CREATE_DEFAULT_INSTANCE();

void CheeseOnToast(byte channel, byte key, byte vel){
  switch (key){
    case 60: red();
      break;
    case 61: green();
      break;
    case 62: blue();
      break;
    case 63: white();
      break;
    case 59: ON();
      break;
    case 58: OFF();
      break;
  }

}

void ToastOnTheFloor(){ 
}

void setup() {
  Serial.begin(9600);
  irsend.begin(IR_PIN);
  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandleNoteOn(CheeseOnToast);
  MIDI.setHandleNoteOff(ToastOnTheFloor);
}

void loop() {
  MIDI.read();
}
  
void red(){
      irsend.sendNEC(0x00FF1AE5, 32);
}

void green(){
      irsend.sendNEC(0x00FF9A65, 32);
}

void blue(){
      irsend.sendNEC(0x00FFA25D, 32);
}

void white(){
      irsend.sendNEC(0x00FF22DD, 32);
}

void ON(){
      irsend.sendNEC(0x00FF827D, 32);
}

void OFF(){
      irsend.sendNEC(0x00FF02FD, 32);
}

Receiver code (not working)

#include <IRremote.h>

#define IR_PIN 2

IRrecv irrecv(IR_PIN);
decode_results results;

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

void loop() {
  if (irrecv.decode(&results)) {
    if (results.decode_type == NEC && results.bits == 32) {
      // Print the received NEC 32-bit hexadecimal code
      Serial.print("Received NEC code: 0x");
      Serial.println((unsigned long)results.value, HEX);
    }
    
    irrecv.resume(); // Receive the next value
  }
}

IR Transmitter and Receiver: https://www.amazon.co.uk/Digital-Receiver-Transmitter-Electronic-Building/dp/B08ZMPMJ1J/ref=sr_1_4?keywords=ir%2Btransmitter%2Band%2Breceiver&qid=1686159673&sprefix=ir%2Btran%2Caps%2C97&sr=8-4&th=1

It might be the IRremote.h you have (there are many) wants the above line to look like this:

  if (irrecv.decode()) {

I've tried change the code to have that line but the problem still occurs.

If I include the line if (results.decode_type == NEC && results.bits == 32) { then the serial monitor shows nothing which implies the signal received is not NEC 32 bit even though that is what I am sending from the other arduino.

If I remove that line of code, when using the line if (irrecv.decode()) { the serial monitor outputs Received NEC code: 0x0 for every IR signal received. Before, when using the line if (irrecv.decode(&results)) { the serial monitor would show random hex codes that were not consistent.

  1. Tell us your Arduino board model (you just said "2 arduinos", but which one? UNO?) and what IR library and version you're using (e.g. the one by "Armin Joachimsmeyer" version 4.0.0).
  2. Have you ever tried to run one of the example sketches, like "ReceiveDump", to read the response it gives when you press some keys of that remote? If not, do it now and show us the results. If you did it, show us the results.
  3. I can't see anything wrong in the code (except I'd remove the "&& results.bits == 32" additional condition), so it seems to be some kinda hardware issue, but the previous "ReceiveDump" test will tell us.

The arduinos are both arduino UNOs. The IR library is IRremote by Armin Joachimsmeyer Version 4.1.2

I've run the "ReceiveDump" code and sent the IR signals in the order 0x00FF1AE5 (red), 0x00FF9A65 (green), 0x00FFA25D (blue), 0x00FF22DD (white)

This is what was in the serial monitor:

Protocol=NEC Address=0x0 Command=0x58 Raw-Data=0xA758FF00 32 bits LSB first

Send with: IrSender.sendNEC(0x0, 0x58, <numberOfRepeats>);

Raw result in internal ticks (50 us) - with leading gap
rawData[68]: 
 -65535
 +180,-87
 +13,- 9 +14,- 9 +13,- 9 +14,- 9
 +14,- 9 +14,- 8 +14,- 9 +13,-10
 +13,-32 +13,-31 +14,-32 +12,-32
 +13,-32 +14,-30 +14,-32 +13,-32
 +12,-10 +13,- 9 +14,- 9 +14,-31
 +14,-31 +13,-10 +13,-32 +12,-10
 +14,-30 +14,-31 +14,-31 +14,- 9
 +13,- 9 +14,-31 +14,- 9 +14,-31
 +14
Sum: 1360
Raw result in microseconds - with leading gap
rawData[68]: 
 -3276750
 +9000,-4350
 + 650,- 450 + 700,- 450 + 650,- 450 + 700,- 450
 + 700,- 450 + 700,- 400 + 700,- 450 + 650,- 500
 + 650,-1600 + 650,-1550 + 700,-1600 + 600,-1600
 + 650,-1600 + 700,-1500 + 700,-1600 + 650,-1600
 + 600,- 500 + 650,- 450 + 700,- 450 + 700,-1550
 + 700,-1550 + 650,- 500 + 650,-1600 + 600,- 500
 + 700,-1500 + 700,-1550 + 700,-1550 + 700,- 450
 + 650,- 450 + 700,-1550 + 700,- 450 + 700,-1550
 + 700
Sum: 68000

Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[67] = {180,87, 13,9, 14,9, 13,9, 14,9, 14,9, 14,8, 14,9, 13,10, 13,32, 13,31, 14,32, 12,32, 13,32, 14,30, 14,32, 13,32, 12,10, 13,9, 14,9, 14,31, 14,31, 13,10, 13,32, 12,10, 14,30, 14,31, 14,31, 14,9, 13,9, 14,31, 14,9, 14,31, 14};  // Protocol=NEC Address=0x0 Command=0x58 Raw-Data=0xA758FF00 32 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[67] = {8980,4370, 630,470, 680,470, 630,470, 680,470, 680,470, 680,420, 680,470, 630,520, 630,1620, 630,1570, 680,1620, 580,1620, 630,1620, 680,1520, 680,1620, 630,1620, 580,520, 630,470, 680,470, 680,1570, 680,1570, 630,520, 630,1620, 580,520, 680,1520, 680,1570, 680,1570, 680,470, 630,470, 680,1570, 680,470, 680,1570, 680};  // Protocol=NEC Address=0x0 Command=0x58 Raw-Data=0xA758FF00 32 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x58;
uint32_t rawData = 0xA758FF00;

Pronto Hex as string
char prontoData[] = "0000 006D 0022 0000 015B 00A7 001A 0011 001C 0011 001A 0011 001C 0011 001C 0011 001C 000F 001C 0011 001A 0012 001A 003D 001A 003B 001C 003D 0018 003D 001A 003D 001C 0039 001C 003D 001A 003D 0018 0012 001A 0011 001C 0011 001C 003B 001C 003B 001A 0012 001A 003D 0018 0012 001C 0039 001C 003B 001C 003B 001C 0011 001A 0011 001C 003B 001C 0011 001C 003B 001C 06C3 ";


Protocol=NEC Address=0x0 Command=0x59 Raw-Data=0xA659FF00 32 bits LSB first

Send with: IrSender.sendNEC(0x0, 0x59, <numberOfRepeats>);

Raw result in internal ticks (50 us) - with leading gap
rawData[68]: 
 -35438
 +180,-87
 +14,- 9 +13,-10 +13,- 9 +14,- 9
 +14,- 8 +14,-10 +12,-10 +13,- 9
 +14,-32 +13,-31 +14,-31 +13,-32
 +13,-31 +14,-31 +14,-32 +13,-32
 +13,-31 +13,- 9 +14,- 9 +14,-31
 +14,-31 +14,- 8 +14,-32 +13,- 9
 +13,- 9 +14,-31 +14,-31 +14,- 9
 +13,- 9 +14,-31 +14,- 9 +13,-31
 +14
Sum: 1360
Raw result in microseconds - with leading gap
rawData[68]: 
 -1771900
 +9000,-4350
 + 700,- 450 + 650,- 500 + 650,- 450 + 700,- 450
 + 700,- 400 + 700,- 500 + 600,- 500 + 650,- 450
 + 700,-1600 + 650,-1550 + 700,-1550 + 650,-1600
 + 650,-1550 + 700,-1550 + 700,-1600 + 650,-1600
 + 650,-1550 + 650,- 450 + 700,- 450 + 700,-1550
 + 700,-1550 + 700,- 400 + 700,-1600 + 650,- 450
 + 650,- 450 + 700,-1550 + 700,-1550 + 700,- 450
 + 650,- 450 + 700,-1550 + 700,- 450 + 650,-1550
 + 700
Sum: 68000

Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[67] = {180,87, 14,9, 13,10, 13,9, 14,9, 14,8, 14,10, 12,10, 13,9, 14,32, 13,31, 14,31, 13,32, 13,31, 14,31, 14,32, 13,32, 13,31, 13,9, 14,9, 14,31, 14,31, 14,8, 14,32, 13,9, 13,9, 14,31, 14,31, 14,9, 13,9, 14,31, 14,9, 13,31, 14};  // Protocol=NEC Address=0x0 Command=0x59 Raw-Data=0xA659FF00 32 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[67] = {8980,4370, 680,470, 630,520, 630,470, 680,470, 680,420, 680,520, 580,520, 630,470, 680,1620, 630,1570, 680,1570, 630,1620, 630,1570, 680,1570, 680,1620, 630,1620, 630,1570, 630,470, 680,470, 680,1570, 680,1570, 680,420, 680,1620, 630,470, 630,470, 680,1570, 680,1570, 680,470, 630,470, 680,1570, 680,470, 630,1570, 680};  // Protocol=NEC Address=0x0 Command=0x59 Raw-Data=0xA659FF00 32 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x59;
uint32_t rawData = 0xA659FF00;

Pronto Hex as string
char prontoData[] = "0000 006D 0022 0000 015B 00A7 001C 0011 001A 0012 001A 0011 001C 0011 001C 000F 001C 0012 0018 0012 001A 0011 001C 003D 001A 003B 001C 003B 001A 003D 001A 003B 001C 003B 001C 003D 001A 003D 001A 003B 001A 0011 001C 0011 001C 003B 001C 003B 001C 000F 001C 003D 001A 0011 001A 0011 001C 003B 001C 003B 001C 0011 001A 0011 001C 003B 001C 0011 001A 003B 001C 06C3 ";


Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first

Send with: IrSender.sendNEC(0x0, 0x45, <numberOfRepeats>);

Raw result in internal ticks (50 us) - with leading gap
rawData[68]: 
 -28413
 +180,-87
 +13,-10 +13,- 9 +14,- 9 +13,- 9
 +15,- 8 +15,- 8 +14,- 9 +13,- 9
 +14,-31 +13,-32 +14,-31 +14,-31
 +14,-30 +15,-30 +14,-31 +15,-30
 +13,-32 +13,- 9 +14,-31 +14,- 9
 +13,- 9 +14,- 9 +13,-32 +14,- 8
 +14,- 9 +14,-31 +13,-10 +13,-32
 +13,-31 +14,-31 +13,-10 +13,-31
 +14
Sum: 1360
Raw result in microseconds - with leading gap
rawData[68]: 
 -1420650
 +9000,-4350
 + 650,- 500 + 650,- 450 + 700,- 450 + 650,- 450
 + 750,- 400 + 750,- 400 + 700,- 450 + 650,- 450
 + 700,-1550 + 650,-1600 + 700,-1550 + 700,-1550
 + 700,-1500 + 750,-1500 + 700,-1550 + 750,-1500
 + 650,-1600 + 650,- 450 + 700,-1550 + 700,- 450
 + 650,- 450 + 700,- 450 + 650,-1600 + 700,- 400
 + 700,- 450 + 700,-1550 + 650,- 500 + 650,-1600
 + 650,-1550 + 700,-1550 + 650,- 500 + 650,-1550
 + 700
Sum: 68000

Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[67] = {180,87, 13,10, 13,9, 14,9, 13,9, 15,8, 15,8, 14,9, 13,9, 14,31, 13,32, 14,31, 14,31, 14,30, 15,30, 14,31, 15,30, 13,32, 13,9, 14,31, 14,9, 13,9, 14,9, 13,32, 14,8, 14,9, 14,31, 13,10, 13,32, 13,31, 14,31, 13,10, 13,31, 14};  // Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[67] = {8980,4370, 630,520, 630,470, 680,470, 630,470, 730,420, 730,420, 680,470, 630,470, 680,1570, 630,1620, 680,1570, 680,1570, 680,1520, 730,1520, 680,1570, 730,1520, 630,1620, 630,470, 680,1570, 680,470, 630,470, 680,470, 630,1620, 680,420, 680,470, 680,1570, 630,520, 630,1620, 630,1570, 680,1570, 630,520, 630,1570, 680};  // Protocol=NEC Address=0x0 Command=0x45 Raw-Data=0xBA45FF00 32 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x45;
uint32_t rawData = 0xBA45FF00;

Pronto Hex as string
char prontoData[] = "0000 006D 0022 0000 015B 00A7 001A 0012 001A 0011 001C 0011 001A 0011 001E 000F 001E 000F 001C 0011 001A 0011 001C 003B 001A 003D 001C 003B 001C 003B 001C 0039 001E 0039 001C 003B 001E 0039 001A 003D 001A 0011 001C 003B 001C 0011 001A 0011 001C 0011 001A 003D 001C 000F 001C 0011 001C 003B 001A 0012 001A 003D 001A 003B 001C 003B 001A 0012 001A 003B 001C 06C3 ";


Protocol=NEC Address=0x0 Command=0x44 Raw-Data=0xBB44FF00 32 bits LSB first

Send with: IrSender.sendNEC(0x0, 0x44, <numberOfRepeats>);

Raw result in internal ticks (50 us) - with leading gap
rawData[68]: 
 -33182
 +181,-87
 +13,- 9 +13,- 9 +13,-10 +14,- 9
 +13,- 9 +14,- 9 +14,- 9 +14,- 8
 +14,-31 +14,-31 +14,-31 +13,-32
 +14,-30 +14,-31 +14,-31 +13,-32
 +13,- 9 +14,- 9 +14,-32 +12,-10
 +14,- 8 +14,- 9 +13,-32 +14,- 9
 +13,-32 +13,-31 +13,- 9 +13,-32
 +14,-31 +14,-31 +14,- 9 +14,-31
 +13
Sum: 1360
Raw result in microseconds - with leading gap
rawData[68]: 
 -1659100
 +9050,-4350
 + 650,- 450 + 650,- 450 + 650,- 500 + 700,- 450
 + 650,- 450 + 700,- 450 + 700,- 450 + 700,- 400
 + 700,-1550 + 700,-1550 + 700,-1550 + 650,-1600
 + 700,-1500 + 700,-1550 + 700,-1550 + 650,-1600
 + 650,- 450 + 700,- 450 + 700,-1600 + 600,- 500
 + 700,- 400 + 700,- 450 + 650,-1600 + 700,- 450
 + 650,-1600 + 650,-1550 + 650,- 450 + 650,-1600
 + 700,-1550 + 700,-1550 + 700,- 450 + 700,-1550
 + 650
Sum: 68000

Result as internal 8bit ticks (50 us) array - compensated with MARK_EXCESS_MICROS=20
uint8_t rawTicks[67] = {181,87, 13,9, 13,9, 13,10, 14,9, 13,9, 14,9, 14,9, 14,8, 14,31, 14,31, 14,31, 13,32, 14,30, 14,31, 14,31, 13,32, 13,9, 14,9, 14,32, 12,10, 14,8, 14,9, 13,32, 14,9, 13,32, 13,31, 13,9, 13,32, 14,31, 14,31, 14,9, 14,31, 13};  // Protocol=NEC Address=0x0 Command=0x44 Raw-Data=0xBB44FF00 32 bits LSB first

Result as microseconds array - compensated with MARK_EXCESS_MICROS=20
uint16_t rawData[67] = {9030,4370, 630,470, 630,470, 630,520, 680,470, 630,470, 680,470, 680,470, 680,420, 680,1570, 680,1570, 680,1570, 630,1620, 680,1520, 680,1570, 680,1570, 630,1620, 630,470, 680,470, 680,1620, 580,520, 680,420, 680,470, 630,1620, 680,470, 630,1620, 630,1570, 630,470, 630,1620, 680,1570, 680,1570, 680,470, 680,1570, 630};  // Protocol=NEC Address=0x0 Command=0x44 Raw-Data=0xBB44FF00 32 bits LSB first

uint16_t address = 0x0;
uint16_t command = 0x44;
uint32_t rawData = 0xBB44FF00;

Pronto Hex as string
char prontoData[] = "0000 006D 0022 0000 015D 00A7 001A 0011 001A 0011 001A 0012 001C 0011 001A 0011 001C 0011 001C 0011 001C 000F 001C 003B 001C 003B 001C 003B 001A 003D 001C 0039 001C 003B 001C 003B 001A 003D 001A 0011 001C 0011 001C 003D 0018 0012 001C 000F 001C 0011 001A 003D 001C 0011 001A 003D 001A 003B 001A 0011 001A 003D 001C 003B 001C 003B 001C 0011 001C 003B 001A 06C3 ";

I've tested other IR receivers and the issue seems to be the same and I doubt it would be the arduino UNO at fault either.

The ReceiveDump output doesn't seem to show "inconsistend" codes, even if the raw data seems to be different from what you send, thus apparently there's no hardware issue . If the codes sent are in turn red, green blue, white, the corresponding commands are 0x58, 0x59, 0x45 and 0x44 respectively, so try this code and tell me what happens:

#include <IRremote.h>

#define IR_PIN 2

IRrecv irrecv(IR_PIN);

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

void loop() {
  if (irrecv.decode()) {
    if (irrecv.decodedIRData.protocol == NEC) {
      
      // Dump (DEBUG ONLY)
      Serial.print("address="); Serial.print(irrecv.decodedIRData.address); Serial.print(" ; ");
      Serial.print("command="); Serial.print(irrecv.decodedIRData.command); Serial.print("=");
      
      if (irrecv.decodedIRData.address == 0) {
        switch (irrecv.decodedIRData.command) {
          case 0x58:
            Serial.println("RED");
            // Do something
            break;
          case 0x59:
            Serial.println("GREEN");
            // Do something
            break;
          case 0x45:
            Serial.println("BLUE");
            // Do something
            break;
          case 0x44:
            Serial.println("WHITE");
            // Do something
            break;
          default:
            Serial.println("-?-");
            // Ignore?
            break;
        }
      }
    }    
    irrecv.resume(); // Receive the next value
  }
}

EDIT: corrected the "results" and "IrReceiver" wrong variables

It's not compiling, 'results' was not declared in this scope

You're right, just replace "IrReceiver" and "results" with "irrecv" and try again (sorry but I'm not at home right now so I can't test the code...).

That works. The code displays the correct colours when they are pressed. I guess I just have to use different hex codes and then test which commands they receive using the ReceiveDump code as I can't see how they are linked otherwise? Thanks for your help.

I'm also having issues when my phone screen is on which seems to set off the IR receiver and not allow any other IR codes to be received. A bit annoying but I guess I'll just have to make sure my phone screen is off to use the IR receiver.

Are there any IR transmitters that will work over a distance of 10 meters or more as that is what would be ideal for my use case? I've not been able to find anything readily available online.

Honestly? I don't know. Maybe something to do with the NEC protocol, anyway if you use the exact same library from the sender too, I think you could try using the same data, or address=0x0 and command=0x58 for "red" for instance, like "irsend.sendNEC(0x0, 0x58);" instead of "irsend.sendNEC(0x00FF1AE5, 32);" and see if it works.

Sorry, never had to do with such transmitters.

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