Unexpected behavior

Hi, I'm working on a simple project that blinks an LED when it receives a signal from an IR remote control.

The idea is to blink the green light with the Volume Up command from the remote and the red light using the Volume Down button.

I have built a test rig using an UNO, a TSOP2836 IR sensor, 2 optocouplers (NEC PS2501-1), 2 220Ohm resistors and 2 LEDs. Please see attached diagram.

Default state of the LEDs is off.

The behavior I expect is that when I press the one of the buttons ONCE, the corresponding LED should light for 100ms ONCE and then go back to being OFF. The behavior I get is: when I press one of the buttons ONCE the corresponding LED lights up but STAYS ON.

I have opened the serial monitor to take a look and it looks as if once you press a button it starts spamming that IR code without stopping.

Thanks for taking the time to help out!

Here's my sketch. I am using the IRremote library from shirriff GitHub - Arduino-IRremote/Arduino-IRremote: Infrared remote library for Arduino: send and receive infrared signals with multiple protocols

#include <IRremote.h>

const int pinD = 2;     // pin for Volume DOWN
const int pinU = 4;     // pin for Volume UP
int IRpin = 11;             // pin for the IR sensor
IRrecv irrecv(IRpin);       // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{
 pinMode(pinD, OUTPUT);
 pinMode(pinU, OUTPUT);
 Serial.begin(9600);
 irrecv.enableIRIn(); // Start the receiver
}

void loop() 
{
  
 if (irrecv.decode(&results))   //Have we received an IR signal?
   {
     
     irrecv.resume();   // Receive the next value
   }
 
 switch(results.value)
{

//Turn Volume Up

 case 17752860:
   digitalWrite(pinU, HIGH);
   delay(100);
   Serial.println(results.value, DEC);
   digitalWrite(pinU, LOW);
 break;
 
//Turn Volume Down

 case 17699820:
   digitalWrite(pinD, HIGH);
   delay(100);
   Serial.println(results.value, DEC);
   digitalWrite(pinD, LOW);
 break;
 
 }
 
}

My guess is that the result.value holds its value until the next one comes in but I am not familiar with the library. Maybe there is a way to set it to 0 after it has been used once.

...R

Put the switch/case that controls the LEDs inside the code block that executes when a code is received

irrecv.resume() wil reset the buffer

So when you receive something, you need to deal with it before calling resume(). it might just be duplicating what's in results.value somewhere else but typically one adds the code handling the key directly in the

if (irrecv.decode(&results)) {  // if we have received an IR signal
  // then deal with it, the code is in  results.value
  ...
  ...
  // now get ready for the next key
  irrecv.resume();   // get ready to receive the next value, results.value cannot be considered valid
}

Thanks everyone for the suggestions. I'm sorry to say that I'm such a noob that I can't do much with them as such, but I'm willing to learn if anyone's got the patience. The code I'm working with has been cobbled together from other scripts and examples so I honestly don't even understand it myself.

UKHeliBob:
Put the switch/case that controls the LEDs inside the code block that executes when a code is received

I understand what you mean, but I don't know how to do that. Would you mind posting or pointing me to an example?

J-M-L:
irrecv.resume() wil reset the buffer

So when you receive something, you need to deal with it before calling resume(). it might just be duplicating what's in results.value somewhere else but typically one adds the code handling the key directly in the

if (irrecv.decode(&results)) {  // if we have received an IR signal

// then deal with it, the code is in  results.value
  ...
  ...
  // now get ready for the next key
  irrecv.resume();  // get ready to receive the next value, results.value cannot be considered valid
}

I don't quite follow.

Apologies for my ignorance!

Try this (not tested)

#include <IRremote.h>

const int pinD = 2;     // pin for Volume DOWN
const int pinU = 4;     // pin for Volume UP
int IRpin = 11;             // pin for the IR sensor
IRrecv irrecv(IRpin);       // create instance of 'irrecv'
decode_results results;     // create instance of 'decode_results'

void setup()
{
  pinMode(pinD, OUTPUT);
  pinMode(pinU, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  if (irrecv.decode(&results))   //Have we received an IR signal?
  {
    switch (results.value)
    {
      //Turn Volume Up
      case 17752860:
        digitalWrite(pinU, HIGH);
        delay(100);
        Serial.println(results.value, DEC);
        digitalWrite(pinU, LOW);
        break;
      //Turn Volume Down
      case 17699820:
        digitalWrite(pinD, HIGH);
        delay(100);
        Serial.println(results.value, DEC);
        digitalWrite(pinD, LOW);
        break;
    }
    irrecv.resume();   // Receive the next value
  }
}

UKHeliBob:
Try this (not tested)

#include <IRremote.h>

const int pinD = 2;    // pin for Volume DOWN
const int pinU = 4;    // pin for Volume UP
int IRpin = 11;            // pin for the IR sensor
IRrecv irrecv(IRpin);      // create instance of 'irrecv'
decode_results results;    // create instance of 'decode_results'

void setup()
{
  pinMode(pinD, OUTPUT);
  pinMode(pinU, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
  if (irrecv.decode(&results))  //Have we received an IR signal?
  {
    switch (results.value)
    {
      //Turn Volume Up
      case 17752860:
        digitalWrite(pinU, HIGH);
        delay(100);
        Serial.println(results.value, DEC);
        digitalWrite(pinU, LOW);
        break;
      //Turn Volume Down
      case 17699820:
        digitalWrite(pinD, HIGH);
        delay(100);
        Serial.println(results.value, DEC);
        digitalWrite(pinD, LOW);
        break;
    }
    irrecv.resume();  // Receive the next value
  }
}

That worked perfectly! Thank you so much!