Arduino IR receiver not decoding after button press

Hello everyone,

I'm using a arduino MEGA2560 board provided by Elegoo in their starter kit. I've set up a piezo buzzer and an IR receiver, and i programmed it to play a melody when the "1" button is pressed on the remote. It does play, but only once. afterwards, all signals from the remote are received as noise, with protocol printing as "UNKNOWN". I have no idea why it does this, and it only does this with buttons im programmed to do something with the buzzer. If its any other button, it prints what its called can some other values, and gets ready to receive the next signal. I'm also not using soldering connections, and i dont know how much of a problem that poses, since im brand new to this.

heres my code.

#define DECODE_NEC
#include "IRremote.h"
#include "pitches.h"

int melody[] = { /* Final fantasy victory fanfare notes*/
  NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_GS4, NOTE_B4, NOTE_C5, NOTE_B4, NOTE_C5
};
int noteDurations[] = { /* Duration of each note to be used in calculation during melody*/
  8, 8, 8, 4, 4, 4, 4, 8, 2
};

void setup() {
  Serial.begin(9600);
  Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
  IrReceiver.begin(11, true);
}

void loop() {
  if (IrReceiver.decode())
  {
    Serial.println(IrReceiver.decodedIRData.command, HEX);
    IrReceiver.printIRResultShort(&Serial);
    switch (IrReceiver.decodedIRData.command) {
      case 0x45: Serial.println("POWER"); break;
      case 0x46: Serial.println("FUNC/STOP"); break;
      case 0x47: Serial.println("VOL+"); break;
      case 0x44: Serial.println("FAST BACK"); break;
      case 0x40: Serial.println("PAUSE"); break;
      case 0x43: Serial.println("FAST FORWARD"); break;
      case 0x7: Serial.println("DOWN"); break;
      case 0x15: Serial.println("VOL-"); break;
      case 0x9: Serial.println("UP"); break;
      case 0x19: Serial.println("EQ"); break;
      case 0xD: Serial.println("ST/REPT"); break;
      case 0x16:
        Serial.println("0");
        tone(8, 500, 1000); // to test if the code for the melody was the problem
        break;
      case 0xC:
        for (int thisNote = 0; thisNote < 9; thisNote++) { // the code for the melody itself
          int noteDuration = 1000 / noteDurations[thisNote];
          tone(8, melody[thisNote], noteDuration);
          int pauseBetweenNotes = noteDuration * 1.30;
          delay(pauseBetweenNotes);
          noTone(8);
        };
        Serial.println("1");
        break;
      case 0x18: Serial.println("2"); break;
      case 0x5E: Serial.println("3"); break;
      case 0x8: Serial.println("4"); break;
      case 0x1C: Serial.println("5"); break;
      case 0x5A: Serial.println("6"); break;
      case 0x42: Serial.println("7"); break;
      case 0x52: Serial.println("8"); break;
      case 0x54: Serial.println("9"); break;
      /*case 0xFFFFFFFF: Serial.println(" REPEAT"); break;*/
      default: Serial.println(" other button   ");
    }
    if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
      Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
      // We have an unknown protocol here, print more info
      IrReceiver.printIRResultRawFormatted(&Serial, true);
    }
    IrReceiver.resume(); // receive the next value
    delay(50);  // to prevent repeat values
  }
}

Here is the input when i press the button to play the melody

C
Protocol=NEC Address=0x0 Command=0xC Raw-Data=0xF30CFF00 32 bits LSB first
1

here is the code it gives when i press it again after the melody

0
Protocol=UNKNOWN 14 bits (incl. gap and start) received
 other button   
Received noise or an unknown (or not yet enabled) protocol
rawData[28]: 
 -893200
 + 450,- 300
 + 300,- 200 +  50,-  50 +  50,-  50 +  50,- 400
 +  50,-  50 + 150,- 200 + 250,- 250 + 100,-  50
 +  50,-  50 +  50,-  50 +  50,- 100 +  50,-1900
 + 500
Sum: 5800

heres my circuit

After i press any button it gives relatively the same result, but the values are always different. it doesnt go back to normal until i reset the board. im using the IRremote library by shirriff, z3t0, and ArminJo. pitches.h just defines some values for the notes.

*** UPDATE ***

I found an ugly way to make it work, by resetting it every time the melody is played, however i wanted an indicator to known when it was done resetting, so i set it to play a short tone when it came on. However it gives the same error codes just after it plays the tone, so im almost positive its either the passive buzzer or the tone function thats causing the problem. just not sure exactly why or how

Rather than trying to find a match to the received signal, print the received value. See if that value repeats. I find the IR sensor has maybe 50% accuracy. Breadboards can rust. Pins can not make good connection. Signals can bounce. Batteries can be weak.

1 Like

What happens when you try the example sketch that comes with the IR library ?

Make sure the IR remote has fresh batteries.

1 Like

you can't create vars in a switch

case 0xC:
        for (**int** thisNote = 0; thisNote < 9; thisNote++) { // the code for the melody itself
          **int** noteDuration = 1000 / noteDurations[thisNote];
          tone(8, melody[thisNote], noteDuration);
          **int** pauseBetweenNotes = noteDuration * 1.30;
          delay(pauseBetweenNotes);
          noTone(8);
        };

declare the ** vars OUTSIDE the SWITCH.

I chased this one for days ...

1 Like

Nothing wrong w/hardware I'll bet.

1 Like

I moved the declarations outside of the switch just after the melody and note durations arrays.

int melody[] = { /* Final fantasy victory fanfare notes*/
                 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_GS4, NOTE_B4, NOTE_C5, NOTE_B4, NOTE_C5
};
int noteDurations[] = { /* Duration of each note to be used in calculation during melody*/
                        8, 8, 8, 4, 4, 4, 4, 8, 2
};

int Reset = 4;

int thisNote = 0;
int noteDuration = 1000 / noteDurations[thisNote];
int pauseBetweenNotes = noteDuration * 1.30;

I removed the "int" before the variables in the for loop, but it still gives the same error where its receiving noise after the first button press.

(I did find a trashy way to fix my problem, by making the arduino reset each time it plays the melody so that it doesn't start receiving noise. thats why pin 4 is set the reset)

IR remote definitely has fresh batteries, i just got the think with a battery tab in the starter kit a couple of days ago.

Pulled the "simple receiver" example sketch and changed only what i needed to change to make it play the tone, and it has basically the same problem.

//#define DECODE_DENON        // Includes Sharp
//#define DECODE_JVC
//#define DECODE_KASEIKYO
//#define DECODE_PANASONIC    // the same as DECODE_KASEIKYO
//#define DECODE_LG
#define DECODE_NEC          // Includes Apple and Onkyo
//#define DECODE_SAMSUNG
//#define DECODE_SONY
//#define DECODE_RC5
//#define DECODE_RC6

//#define DECODE_BOSEWAVE
//#define DECODE_LEGO_PF
//#define DECODE_MAGIQUEST
//#define DECODE_WHYNTER

//#define DECODE_DISTANCE     // universal decoder for pulse distance protocols
//#define DECODE_HASH         // special decoder for all protocols

//#define DEBUG               // Activate this for lots of lovely debug output from the decoders.

#include <Arduino.h>

#include "PinDefinitionsAndMore.h" // Define macros for input and output pin etc.
#include <IRremote.hpp>

#include "pitches.h"

int melody[] = { /* Final fantasy victory fanfare notes*/
                 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_GS4, NOTE_B4, NOTE_C5, NOTE_B4, NOTE_C5
};
int noteDurations[] = { /* Duration of each note to be used in calculation during melody*/
                        8, 8, 8, 4, 4, 4, 4, 8, 2
};

int thisNote = 0;
int noteDuration = 1000 / noteDurations[thisNote];
int pauseBetweenNotes = noteDuration * 1.30;

void setup() {
    Serial.begin(9600);
    // Just to know which program is running on my Arduino
    Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));

    // Start the receiver and if not 3. parameter specified, take LED_BUILTIN pin from the internal boards definition as default feedback LED
    IrReceiver.begin(11, ENABLE_LED_FEEDBACK);

    Serial.print(F("Ready to receive IR signals of protocols: "));
    printActiveIRProtocols(&Serial);
    Serial.println(F("at pin " STR(IR_RECEIVE_PIN)));
}

void loop() {
    /*
     * Check if received data is available and if yes, try to decode it.
     * Decoded result is in the IrReceiver.decodedIRData structure.
     *
     * E.g. command is in IrReceiver.decodedIRData.command
     * address is in command is in IrReceiver.decodedIRData.address
     * and up to 32 bit raw data in IrReceiver.decodedIRData.decodedRawData
     */
    if (IrReceiver.decode()) {

        // Print a short summary of received data
        IrReceiver.printIRResultShort(&Serial);
        IrReceiver.printIRSendUsage(&Serial);
        if (IrReceiver.decodedIRData.protocol == UNKNOWN) {
            Serial.println(F("Received noise or an unknown (or not yet enabled) protocol"));
            // We have an unknown protocol here, print more info
            IrReceiver.printIRResultRawFormatted(&Serial, true);
        }
        Serial.println();

        /*
         * !!!Important!!! Enable receiving of the next value,
         * since receiving has stopped after the end of the current received data packet.
         */
        IrReceiver.resume(); // Enable receiving of the next value

        /*
         * Finally, check the received data and perform actions according to the received command
         */
        if (IrReceiver.decodedIRData.command == 0xC) {
            for (thisNote = 0; thisNote < 9; thisNote++) {  // the code for the melody itself
          noteDuration = 1000 / noteDurations[thisNote];
          tone(8, melody[thisNote], noteDuration);
          pauseBetweenNotes = noteDuration * 1.30;
          delay(pauseBetweenNotes);
          noTone(8);
        };
        } else if (IrReceiver.decodedIRData.command == 0x11) {
            // do something else
        } else {
          Serial.println("Something else happened...");
        }
    }
}

Heres what the error codes came up with

Using library version 3.9.0
Ready to receive IR signals of protocols: NEC/NEC2/Onkyo/Apple, at pin 2
Protocol=NEC Address=0x0 Command=0xC Raw-Data=0xF30CFF00 32 bits LSB first
Send with: IrSender.sendNEC(0x0, 0xC, <numberOfRepeats>);

Protocol=UNKNOWN 17 bits (incl. gap and start) received
Received noise or an unknown (or not yet enabled) protocol
rawData[34]: 
 -583450
 + 450,- 200
 +  50,- 200 + 250,- 300 +  50,-  50 +  50,-  50
 +  50,-  50 +  50,- 100 +  50,-  50 + 150,- 350
 + 100,-  50 +  50,-  50 +  50,- 200 +  50,-  50
 +  50,-  50 +  50,-2050 + 450,- 100 +  50
Sum: 5900

Something else happened...

And that was after pressing the button once, it played the melody, and then started receiving noise again. Could it have something to do with the "tone" function? That's the common denominator that seems to cause this issue.

I'm still new enough to this that I'm not sure where to go from here on this. I thought i had the values printed, so if not, how do I print the values and not the signal? And what exactly is the difference? I tried to figure it out on my own but my searches weren't quite pulling up anything consistent.

I have been using AVRs for years and IR decode really only works as a demonstration. Once you add real application code, accurate decoding become iffy. Years ago, I finally decided to move IR decoding to a dedicated Atmega328P-PU on breadboard. That worked reliably.

Breadboards are not perfect and DuPont jumpers are cheap and often not a "good" connection. just assume you will have issues with these cheap kits. By-the-way, Elegoo is "clone" hardware, I personally only use Official hardware for development. Additionally, investing in a quality solderless breadboard is recommended, but they are not cheap:
Guide To Solderless Breadboards - ProtoSupplies

Insert a couple lines inside the void loop()... if(...) .... the first line is just text to show the second line's data, the second line is the value that was returned/decoded
Serial.println("IrReceiver.decode()");
Serial.println(IrReceiver.decode());

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