IR Remote with Flashing LEDs

Hi, im working on a project and have hit a roadblock. Im trying to program an LED with 4 modes, an off mode, on mode, fast flashing and slow flashing. These modes are controlled using an IR Remote. so far I have been able to turn the LED on and off. But when I try to program the flashing LEDs i am only able to make the flash once and then it stops. I would like them to flash when i press a certain button on the IR remote and continue to flash until another button is pressed. Could anyone help me please. My current code is below. Thanks


#include <IRremote.h>
#include <IRremoteInt.h>

int RECV_PIN = 11; //define input pin on Arduino
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(10, OUTPUT);

}
void loop() {
  if (irrecv.decode( & results)) {
    String hex = String(results.value, HEX);
    Serial.print("Hexadecimal Code: ");
    Serial.println(hex);
    irrecv.enableIRIn();

    if(hex == "ff18e7"){
        digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
    } 
    if(hex == "ffa25d" ){
     
        digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(100);               // wait for a second
        digitalWrite(10, LOW);    // turn the LED off by making the voltage LOW
        delay(100);               // wait for a second
        digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(100);               // wait for a second
        digitalWrite(10, LOW);    // turn the LED off by making the voltage LOW
        delay(100);               // wait for a second
    

    }
    if(hex == "ff629d"){
        digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(50);                // wait for a second
        digitalWrite(10, LOW);    // turn the LED off by making the voltage LOW
        delay(50);                // wait for a second
        digitalWrite(10, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(50);                // wait for a second
        digitalWrite(10, LOW);    // turn the LED off by making the voltage LOW
        delay(50);                // wait for a second
    }

    if(hex == "ff4ab5"){
      digitalWrite(10,LOW);    // turn the LED off by making the voltage LOW
       

    }
    

    
  }


}

The first thing you need to do is stop using delay( ) as it stops sketch execution until the delay period is finished.

Study this:


The next thing you need to do is learn to write your sketch as a State Machine.

Study this:

Here is a demo code to do what, I think, that you want. This code uses the newest version of the IRremote library. You will need to set the pins to your setup and get the key codes from your remote and insert them into the code. It uses the blink without delay timing that @LarryD mentioned and a sort of simple state machine.

#include <IRremote.h>

const byte IR_RECEIVE_PIN = 4;
const byte LED_PIN = 5;

unsigned long keycommand = 0;
bool newIR = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("IR receive test");
   IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
   pinMode(LED_PIN, OUTPUT);
   //digitalWrite(LED_PIN, HIGH);
}

void loop()
{
   static unsigned long ledTimer = 0;
   unsigned long ledIntervalFast = 100;
   unsigned long ledIntervalSlow = 1000;

   checkIR();

   if (newIR)
   {
      printIR();
      newIR = false;
   }
   if (keycommand == 1) // fast flash
   {
      if (millis() - ledTimer >= ledIntervalFast)
      {
         ledTimer = millis();
         digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      }
   }
   if (keycommand == 2) // slow flash
   {
      if (millis() - ledTimer >= ledIntervalSlow)
      {
         ledTimer = millis();
         digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      }
   }
   else if (keycommand == 3) // off
   {
      digitalWrite(LED_PIN, LOW);
   }
   else if (keycommand == 4) // on
   {
      digitalWrite(LED_PIN, HIGH);
   }
}

void checkIR()
{
   static unsigned long timer = 0;
   unsigned long interval = 100;
   if (millis() - timer >= interval)
   {
      timer = millis();

      if (IrReceiver.decode())
      {
         keycommand = IrReceiver.decodedIRData.command;
         // ignore repeat codes
         if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT))
         {
            IrReceiver.resume();
            return;
         }
         IrReceiver.resume();
         newIR = true;
      }
   }
}

void printIR()
{
   Serial.print("decoded command = ");
   Serial.print(keycommand);
   Serial.println();
}
1 Like

I think the OP is using an old version of the IR library so they might want to upgrade to the latest version (3.0 ? )

I have seen a lot of people lately have installed the new version but are using code written for the old version. The older code usually works OK but not always. There is a warning issued (if warnings are enabled) to that effect when compiling. There are good reasons to use the new version. The GitHub page for the IRremote library explains why and also how to fix older code to work with the new version.

Thankyou @LarryD and @groundFungus for your feedback. @groundFungus i've tried to enter my key codes and switch the pins in the demo code that you sent but it doesn't seem to work. Maybe i've entered them in wrong.
FYI my key codes are:

UP - ff18e7
DOWN - ff4ab5
LEFT - ff10ef
RIGHT - ff5aa5
1 - ffa25d
2 - ff629d
3 - ffe21d
4 - ff22dd

#include <IRremote.h>

const byte IR_RECEIVE_PIN = 4;
const byte LED_PIN = 5;

unsigned long keycommand = 0;
bool newIR = false;

void setup()
{
   Serial.begin(115200);
   Serial.println("Hexadecimal Code: ");
   IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
   pinMode(LED_PIN, OUTPUT);
   //digitalWrite(LED_PIN, HIGH);
}

void loop()
{
   static unsigned long ledTimer = 0;
   unsigned long ledIntervalFast = 100;
   unsigned long ledIntervalSlow = 1000;


   checkIR();

   if (newIR)
   {
      printIR();
      newIR = false;
   }
   if (keycommand == "ff629d") // fast flash
   {
      if (millis() - ledTimer >= ledIntervalFast)
      {
         ledTimer = millis();
         digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      }
   }
   if (keycommand == "ffa25d") // slow flash
   {
      if (millis() - ledTimer >= ledIntervalSlow)
      {
         ledTimer = millis();
         digitalWrite(LED_PIN, !digitalRead(LED_PIN));
      }
   }
   else if (keycommand == "ff4ab5" ) // off
   {
      digitalWrite(LED_PIN, LOW);
   }
   else if (keycommand == "ff18e7") // on
   {
      digitalWrite(LED_PIN, HIGH);
   }
}

void checkIR()
{
   static unsigned long timer = 0;
   unsigned long interval = 100;
   if (millis() - timer >= interval)
   {
      timer = millis();

      if (IrReceiver.decode())
      {
         keycommand = IrReceiver.decodedIRData.command;
         // ignore repeat codes
         if ((IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT))
         {
            IrReceiver.resume();
            return;
         }
         IrReceiver.resume();
         newIR = true;
      }
   }
}

void printIR()
{
   Serial.print("decoded command = ");
   Serial.print(keycommand);
   Serial.println();
}

How did you obtain those key codes? Are you using the new version of the IRremote library?

To get the key codes (commands), run the code, open serial monitor and press a key, note down what it says after "decoded command =". That is the key code to put into the code. The codes returned by the old version of the library will, probably, not work. The commands are numbers, not strings.

@groundFungus Thankyou so much, it is working perfectly now. I really appreciate your help.

Glad you got it to work. Do you understand how it works?

To be completely honest not really.

What is it that is giving you trouble?

It is very late here and I need to sleep. I can try to help you in the morning. In the meantime, read up on using millis() for timing.
Non-blocking timing tutorials:
Blink without delay().
Beginner's guide to millis().
Several things at a time.

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