How to make a loop inside a switch/case

Hello, I’m doing a simple project for my university where I turn on/off a lamp with a IR Remote control. I just used the switch/case to read the inputs and make the decisions. I alredy can turn the light on and off and also make blink, but just when I press the button. How can I make a loop to keep my light blinking and stop it when press the button again (or the same button to turn off)?

There is my actual code:

#include <IRremote.h>

const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led=13;
int timer=1000;


IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
Serial.begin(9600);
pinMode(Rele,OUTPUT);
pinMode(Led,OUTPUT);
irrecv.enableIRIn();
}

void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);

switch(results.value){
  case 0X40BF807F: //Turn light on
  digitalWrite(Rele,HIGH);
  break;
  case 0X40BF40BF: //Turn light off
  digitalWrite(Rele,LOW);
  break;

  case 0X40BFA05F: //Decrease Timer
  timer=timer-250;
  break;

  case 0X40BF609F: //Increase Timer
  timer=timer+250;
  break;
  
  case 0X40BF20DF: //Blink
  digitalWrite(Rele,LOW);
  delay(timer);
  digitalWrite(Rele,HIGH);
 }
irrecv.resume();
}
}

When your code is in the IDE, press Ctrl-T to reformat to a style most of us can read easily. Also, get rid of the “magic numbers” in your code. They also make it hard to read. For example:

#include <IRremote.h>

#define LIGHTON       0X40BF807F
#define LIGHTOFF      0X40BF40BF
#define REDUCETIMER   0X40BFA05F
#define INCREASETIMER 0X40BF609F
#define BLINK         0X40BF20DF


const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led = 13;
int timer = 1000;


IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  pinMode(Rele, OUTPUT);
  pinMode(Led, OUTPUT);
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);

    switch (results.value) {
      case LIGHTON: //Turn light on
        digitalWrite(Rele, HIGH);
        break;

      case LIGHTOFF: //Turn light off
        digitalWrite(Rele, LOW);
        break;

      case REDUCETIMER: //Decrease Timer
        timer = timer - 250;
        break;

      case INCREASETIMER: //Increase Timer
        timer = timer + 250;
        break;

      case BLINK: //Blink
        digitalWrite(Rele, LOW);
        delay(timer);
        digitalWrite(Rele, HIGH);

      default:
        Serial.print("I shouldn't be here. value = "):
        Serial.println(results.value);
        break;

    }
    irrecv.resume();
  }
}

Now, think about your problem and write a function to start and stop blinking based on the state of your switch

This may help:

//**********************************************************************
 
#include "IRremote.h"
//LarryD

//Sketch to demonstrate using an IR hand remote to control Arduino outputs.
//The remote used here uses the NEC protocol.
//This remote sends the button code (example 0xFF629D) then a repeat code 0xFFFFFFFF
//The repeat code is re-sent as long as an IR remote button is pressed.
//The IR receiver used is the TSOP4838
 
/*  17 IR button remote layout   http://i.imgur.com/X1KIdqI.png
 
   ^
< OK  >  
   v
1  2  3 
4  5  6
7  8  9
*  0  # 
 
*/
 
 
const byte RECV_PIN = 7;   //IR receive pin
 
IRrecv irrecv(RECV_PIN);   //create instance of 'IRrecv'
decode_results results;    //create instance of 'decode_results'
 
unsigned long   TimerUp;   //UP arrow on the remote
boolean         TimerUpFlag = false;
 
unsigned long   TimerDown; //DOWN arrow on the remote
boolean         TimerDownFlag = false;
 
unsigned long TimerIntensity;
unsigned long TimerIncDec;
boolean intesityUpFlag   = false;
boolean intesityDownFlag = false;
int brightness;
 
unsigned long   dummy;
unsigned long * TimerPtr = &dummy; //pointer to the current timer
 
const byte upLED        = 13;  //turns on as long as the UP button is pressed
const byte downLED      = 12;  //turns on as long as the DOWN button is pressed
const byte leftLED      = 11;  //toggles on/off
const byte rightLED     = 10;  //toggles on/off
const byte intensityLED =  9;  //a LED which can have its intensity adjusted
 
 
//                           s e t u p ( )
//**********************************************************************
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); //start receive
 
  pinMode(upLED, OUTPUT);
  pinMode(downLED, OUTPUT);
  pinMode(leftLED, OUTPUT);
  pinMode(rightLED, OUTPUT);
  pinMode(intensityLED, OUTPUT); //this is a PWM output pin
 
} //                    E N D  O F  s e t u p ( )
 
 
 
//                            l o o p ( )
//**********************************************************************
void loop()
{
  if (irrecv.decode(&results)) //is there IR remote button code
  {
    //Serial.println(results.value);
    processButton(); //process button press
    irrecv.resume(); //restart for next button press
  }
 
  //**********************                                //Turn off upLED
  //if timing is enabled, is it time to stop
  if (TimerUpFlag && millis() - TimerUp >= 250ul)
  {
    TimerUpFlag = false; //disable timing
    TimerPtr = &dummy;   //pointer to dummy timer
    digitalWrite(upLED, LOW);
  }
 
  //**********************                                //Turn off downLED
  //if timing is enabled, is it time to stop
  if (TimerDownFlag && millis() - TimerDown >= 250ul)
  {
    TimerDownFlag = false; //disable timing
    TimerPtr = &dummy;     //pointer to dummy timer
    digitalWrite(downLED, LOW);
  }
 
  //**********************                                //LED intensity
  //are we still within the adjustment time
  if (millis() - TimerIntensity <= 300ul)
  {
    //is it time to increase/decrease the intensity
    if (millis() - TimerIncDec >= 200ul)
    {
      TimerIncDec = millis();
 
      if (intesityUpFlag == true) //Increase
      {
        brightness += 5;
        if (brightness > 255)
        {
          brightness = 255;
        }
      }
      else if (intesityDownFlag == true) //Decrease
      {
        brightness -= 5;
        if (brightness < 0)
        {
          brightness = 0;
        }
      }
 
      analogWrite(intensityLED, brightness);
      //Serial.println(brightness); //debug
    }
  }
  //stop increasing/decreasing intensity
  else
  {
    intesityUpFlag = false;
    intesityDownFlag = false;
  }
 
  //************************************
  //Other non blocking code goes here
  //************************************
 
} //                   E N D  O F  l o o p ( )
 
 
 
//======================================================================
//                       F U N C T I O N S
//======================================================================
 
//                   p r o c e s s B u t t o n ( )
//**********************************************************************
//process IR remote button presses
void processButton()
{
  switch (results.value)
  {
    //**********************
    case 0xFF629D:                                           //UP Arrow
      {
        Serial.println("UP");
        TimerPtr = &TimerUp;  //point to this timer
        TimerUpFlag = true;   //enable timing
        digitalWrite(upLED, HIGH);
        TimerUp = millis();
      }
      break;
 
    //**********************
    case 0xFFA857:                                           //DOWN Arrow
      {
        Serial.println("DOWN");
        TimerPtr = &TimerDown;  //point to this timer
        TimerDownFlag = true;   //enable timing
        digitalWrite(downLED, HIGH);
        TimerDown = millis();
      }
      break;
 
    //**********************
    case 0xFF22DD:                                           //LEFT Arrow
      {
        Serial.println("LEFT");
        digitalWrite(leftLED, !digitalRead(leftLED));   //Toggle LED
      }
      break;
 
    //**********************
    case 0xFFC23D:                                           //RIGHT Arrow
      {
        Serial.println("RIGHT");
        digitalWrite(rightLED, !digitalRead(rightLED)); //Toggle LED
      }
      break;
 
    //**********************
    case 0xFF42BD:                                           // * button
      {
        Serial.println("*");
        TimerPtr = &TimerIntensity;  //point to this timer
        intesityUpFlag = true;       //enable intensity up adjustment
        intesityDownFlag = false;
        TimerIncDec = millis();
        TimerIntensity = millis();
      }
      break;
 
    //**********************
   case 0xFF52AD:                                           // # button
      {
        Serial.println("#");
        TimerPtr = &TimerIntensity;  //point to this timer
        intesityDownFlag = true;     //enable intensity down adjustment
        intesityUpFlag = false;
        TimerIncDec = millis();
        TimerIntensity = millis();
      }
      break;
 
    //**********************
    case 0xFF02FD:
      Serial.println("OK");
      break;
 
    //**********************
    case 0xFF6897:
      Serial.println("1");
      break;
 
    //**********************
    case 0xFF9867:
      Serial.println("2");
      break;
 
    //**********************
    case 0xFFB04F:
      Serial.println("3");
      break;
 
    //**********************
    case 0xFF30CF:
      Serial.println("4");
      break;
 
    //**********************
    case 0xFF18E7:
      Serial.println("5");
      break;
 
    //**********************
    case 0xFF7A85:
      Serial.println("6");
      break;
 
    //**********************
    case 0xFF10EF:
      Serial.println("7");
      break;
 
    //**********************
    case 0xFF38C7:
      Serial.println("8");
      break;
 
    //**********************
    case 0xFF5AA5:
      Serial.println("9");
      break;
 
    //**********************
    case 0xFF4AB5:
      Serial.println("0");
      break;
 
    //**********************
    case 0xFFFFFFFF: //Repeat code
      {
        Serial.println("REPEAT");
        *TimerPtr = millis();       //reset the current timer
      }
      break;
 
  } // END switch case
 
} //             E N D  o f  p r o c e s s B u t t o n ( )
 
//**********************************************************************
 
//======================================================================
//                        E N D  O F  C O D E
//======================================================================

Some Simple changes :slight_smile:
Notes are in the code

#include <IRremote.h>

#define LIGHTON       0X40BF807F
#define LIGHTOFF      0X40BF40BF
#define REDUCETIMER   0X40BFA05F
#define INCREASETIMER 0X40BF609F
#define BLINK         0X40BF20DF

const int RECV_PIN = 8; //Receiver Pin
const int Rele = 10; //Light bulb
const int Led = 13;
int timer = 1000;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  pinMode(Rele, OUTPUT);
  pinMode(Led, OUTPUT);
  irrecv.enableIRIn();
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);

    switch (results.value) {
      case LIGHTON: //Turn light on
        Mode = 1;
        break;

      case LIGHTOFF: //Turn light off
        Mode = 0;
        break;

      case REDUCETIMER: //Decrease Timer
        timer = timer - 250;
        break;

      case INCREASETIMER: //Increase Timer
        timer = timer + 250;
        break;

      case BLINK: //Blink
        Mode = 2;
        digitalWrite(Rele, LOW);
        delay(timer);
        digitalWrite(Rele, HIGH);

      default:
        Serial.print("I shouldn't be here. value = ");
        Serial.println(results.value);
        break;
    }

// The IR receiver reuslts change each cycle so you need to latch the "Mode" into a sequence so the light will keep blinking while you reduce or increase timer
    switch (Mode) {
      case 1: //Turn light on
        digitalWrite(Rele, HIGH);
        break;
      case 0: //Turn light off
        digitalWrite(Rele, LOW);
        break;
      case 2: //Blink
        static unsigned long _DelayTimer;
        if ( (unsigned long)(millis() - _DelayTimer) >= (timer)) { // Blink without delay timer allowing your IR receiver to work
          _DelayTimer = millis();
          digitalWrite(Rele, !digitalRead(Rele)); // reads the output and uses the opposite
        }
        break;
    }
    irrecv.resume();
  }
}