IR Remote and Loop Codes

So I press the button 2 in my IR remote, then the strobe blinks as coded, but it only blinks once. How do I code it in a manner that if I press button 2 on my remote, it turns the LED on and blinks on a loop, then pressing the button 2 again turns the LED off.

code for reference:

/* 
source: www.electroschematics.com
You'll need to change the led pins and the codes 
accordingly to your configuration and IR remote
*/

#include <IRremote.h>

int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
int led1 = 3; //NAV
int led2 = 2; //STROBE
int itsONled[] = {0,0,0,0};
/* the initial state of LEDs is OFF (zero) 
the first zero must remain zero but you can 
change the others to 1's if you want a certain
led to light when the board is powered */
#define code1  12495 // code received from button 1
#define code2  6375 // code received from button 2

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);   // you can comment this line
  irrecv.enableIRIn();  // Start the receiver
  pinMode(3, OUTPUT);   //NAV
  pinMode(2, OUTPUT);   //STROBE

}

void loop() {
  if (irrecv.decode(&results)) {
    unsigned int value = results.value;
    switch(value) {
       case code1:
         if(itsONled[1] == 1) {        // if first led is on then
            digitalWrite(led1, LOW);   // turn it off when button is pressed
            itsONled[1] = 0;           // and set its state as off
         } else {                      // else if first led is off
             digitalWrite(led1, HIGH); // turn it on when the button is pressed
             itsONled[1] = 1;          // and set its state as on
         }
          break; 
       case code2:
         if(itsONled[2] == 1) {
            digitalWrite(led2, LOW);
            itsONled[2] = 0;
         } else {
             digitalWrite(led2, HIGH);
             delay(50); 
             digitalWrite(led2, LOW); 
             delay(50); 
             digitalWrite(led2, HIGH); 
             delay(50); 
             digitalWrite(led2, LOW); 
             delay(1000);
             itsONled[2] = 1;
         }
          break;
            
    }
    Serial.println(value); // you can comment this line
    irrecv.resume(); // Receive the next value
  }
}

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code , use code tags and post the code here

please use </> to post your code

you'll want a sub-function that does things separate from waiting for IR codes.

that sub-function would toggle an LED (e.g. digitalWrite (led, ! digitalRead(led)):wink: when a state variable is set by the IR receiving code. it would use millis() to determine how often to toggle the LED. of course, that sub-function could do more than just handle one LED

the IR receiving would toggle that state variable when it recognizes a new occurrence of the IR code.

think about breaking thing down into parts and letting loop() process those parts relatively independently

Edited my post, apologies for the mistake as it is my first time to post here. :slight_smile:

Thanks for your input, I will try to digest this as I literally started coding 2 days ago and everything is overwhelming. But yes, I have read about millis function as well.

You have to separate the blinking from the place where it processes input. The input processing turns on a flag and in the loop() it blinks the light once a second while the flag is on.

/*
  source: www.electroschematics.com
  You'll need to change the led pins and the codes
  accordingly to your configuration and IR remote
*/

#include <IRremote.h>

const int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
const int led1 = 3; //NAV
const int led2 = 2; //STROBE
boolean itsONled[4];  // Defaluts to 'false'
/* the initial state of LEDs is OFF (zero)
  the first zero must remain zero but you can
  change the others to 1's if you want a certain
  led to light when the board is powered */
#define code1  12495 // code received from button 1
#define code2  6375 // code received from button 2

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);   // you can comment this line
  irrecv.enableIRIn();  // Start the receiver
  pinMode(led1, OUTPUT);   //NAV
  pinMode(led2, OUTPUT);   //STROBE
}

void loop()
{
  static unsigned long previousMillis = 0;
  // if led2 is 'on', show the blink pattern once per second.
  if (itsONled[2] && millis() - previousMillis >= 1000)
  {
    previousMillis = millis();

    digitalWrite(led2, HIGH);
    delay(50);
    digitalWrite(led2, LOW);
    delay(50);
    digitalWrite(led2, HIGH);
    delay(50);
    digitalWrite(led2, LOW);
  }


  if (irrecv.decode(&results))
  {
    unsigned int value = results.value;
    switch (value)
    {
      case code1:
        if (itsONled[1])         // if first led is on then
        {
          digitalWrite(led1, LOW);   // turn it off when button is pressed
          itsONled[1] = false;           // and set its state as off
        }
        else                          // else if first led is off
        {
          digitalWrite(led1, HIGH); // turn it on when the button is pressed
          itsONled[1] = true;          // and set its state as on
        }
        break;
      case code2:
        if (itsONled[2])
        {
          digitalWrite(led2, LOW);
          itsONled[2] = false;
        }
        else
        {
          itsONled[2] = true;
        }
        break;

    }
    Serial.println(value); // you can comment this line
    irrecv.resume(); // Receive the next value
  }
}
1 Like

I am starting have a grasp on the correction you did on my code. Thank you so much I appreciate the help. :grin:

@johnwasser Thanks for the code again, but I do need 1 more advice.

I now added a button 3 in my input and coded a separate blink sequence.

If I press 3, it works perfectly as coded, but if I switch on the button 2, the delay sequence switches alternately with the button 3.

How can I code it that button 3's sequence is independent than that of button 2?

/*
  source: www.electroschematics.com
  You'll need to change the led pins and the codes
  accordingly to your configuration and IR remote
*/

#include <IRremote.h>

const int RECV_PIN = 12; // the pin where you connect the output pin of TSOP4838
const int led1 = 3; //NAV
const int led2 = 2; //STROBE WING
const int led3 = 4; //STROBE TAIL
const int led4 = 5; //BEACON
boolean itsONled[13];  // Defaults to 'false'
/*old code int itsONled[] = {0,0,0,0};
/* the initial state of LEDs is OFF (zero)
  the first zero must remain zero but you can
  change the others to 1's if you want a certain
  led to light when the board is powered */
#define code1  12495 // code received from button 1
#define code2  6375 // code received from button 2
#define code3  31365 // code received from button 3

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);   // you can comment this line
  irrecv.enableIRIn();  // Start the receiver
  pinMode(led1, OUTPUT);   //NAV
  pinMode(led2, OUTPUT);   //STROBE WING
  pinMode(led3, OUTPUT);   //STROBE TAIL
  pinMode(led4, OUTPUT);   //BEACON
}

void loop()
{
  static unsigned long previousMillis = 0;
  // if led2 is 'on', show the blink pattern once per second.
  if (itsONled[2] && millis() - previousMillis >= 1000)
  {
    previousMillis = millis();

    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    delay(50);
    digitalWrite(led2, LOW);
    delay(50);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    delay(50);
    digitalWrite(led2, LOW);
  }
  if (itsONled[4] && millis() - previousMillis >= 1000)
  {
    previousMillis = millis();

    digitalWrite(led4, HIGH);
    delay(50);
    digitalWrite(led4, LOW);
    delay(50);
     }


  if (irrecv.decode(&results))
  {
    unsigned int value = results.value;
    switch (value)
    {
      case code1:
        if (itsONled[1])         // if first led is on then
        {
          digitalWrite(led1, LOW);   // turn it off when button is pressed
          itsONled[1] = false;           // and set its state as off
        }
        else                          // else if first led is off
        {
          digitalWrite(led1, HIGH); // turn it on when the button is pressed
          itsONled[1] = true;          // and set its state as on
        }
        break;
      case code2:
        if (itsONled[2])
        {
          digitalWrite(led2, LOW);
          itsONled[2] = false;
        }
        else
        {
          itsONled[2] = true;
        }
        break;
        case code3:
        if (itsONled[4])         
        {
          digitalWrite(led4, LOW);  
          itsONled[4] = false;           
        }
        else                         
        {
          itsONled[4] = true;
        }
        break;

    }
    Serial.println(value); // you can comment this line
    irrecv.resume(); // Receive the next value
  }
}

You have to remove all delay() calls from all of your blink patterns and turn each pattern into a finite state machine. Call the FSM from loop() and each state will repeat until its time expires, then it will go on to the next state.

For example:

void LEDPattern2()
{
  static int state = 0;
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  // if this pattern isn't playing, reset to the beginning
  if (!itsONled[2])
  {
    if (state != 0) // Pattern was in progress
    {
      // Turn off the LEDs and start over at state 0
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      state = 0;
    }
    return;
  }

  switch (state)
  {
    case 0:
      previousMillis = currentMillis;
      state = 1;
      break;

    case 1:
      digitalWrite(led2, HIGH);
      digitalWrite(led3, HIGH);
      // delay(50);
      if (currentMillis - previousMillis > 50)
      {
        state = 2;
        previousMillis = currentMillis;
      }
      break;

    case 2:
      digitalWrite(led2, LOW);
      // delay(50);
      if (currentMillis - previousMillis > 50)
      {
        state = 3;
        previousMillis = currentMillis;
      }
      break;

    case 3:
      digitalWrite(led2, HIGH);
      digitalWrite(led3, LOW);
      // delay(50);
      if (currentMillis - previousMillis > 50)
      {
        state = 4;
        previousMillis = currentMillis;
      }
      break;

    case 4:
      digitalWrite(led2, LOW);
      // delay(1000);
      if (currentMillis - previousMillis > 1000)
      {
        state = 1;
        previousMillis = currentMillis;
      }
      break;
  }
}


void loop()
{
  static unsigned long previousMillis = 0;

  LEDPattern2();

Thank you for this. I will try it out. You're a life saver.