Delay commands In separate loops

Hello just letting you know, I am still new to a arduino and dont know everything,
I am trying to write code for a led light strip using arduino, I currently just have it use a IR remote to change to three colors, (red, green and blue, ill add more later) I want to add a option to have it flash colors at three different speeds, I tried using a function that switches between colors, but it gets stuck on it flashing, and you have to reset it all to change the mode.

Is there a way to run a loop (with delay commands) and then break the loop and return to void loop if you press a button on the remote?

here is what I have so far: (im using a arduino uno)

    //        IR Remote:        //
#include <IRremote.h>
#define IRPIN 6

    //    Variables:  //
String MODE = "NOT_SELECTED";


    /////IR button Pinout - <Name> <pin>/////

    //    RGB Colors:    //

#define RED 9
#define GREEN 10
#define BLUE 11

void setup() {
  Serial.begin(9600);
  IrReceiver.begin(IRPIN);
  
  pinMode(RED, OUTPUT);
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
}

void loop() {
  
  if (IrReceiver.decode()) {
    Serial.println(IrReceiver.decodedIRData.command);
    IrReceiver.resume();
    int command = IrReceiver.decodedIRData.command;
    switch (command) {

    //        RED, GREEN, BLUE:       //
     case 12: {
        MODE = "RED";
        Serial.println(MODE);
        setColor(255, 0, 0);
        delay(20);
        break;
        }
        
      case 24: {
        MODE = "GREEN";
        Serial.println(MODE);
        setColor(0, 255, 0);
        delay(20);
        break;
        }
        
      case 94: {
        setColor(0, 0, 255);
        MODE = "BLUE";
        Serial.println(MODE);
        delay(20);
        break; 
      }

    //        WHITE:       //
       
      case 22: {
        setColor(255, 255, 255);
        MODE = "WHITE";
        Serial.println(MODE);
        delay(20);
        break; 
      }


    //        FLASH:       //

       case 8: {
        FLASH_SLOW();
        break;
        }
        
      case 28: {
        FLASH_MED();
        break;
        }
        
      case 90: {
        FLASH_FAST();
        break; 
      }
      
      default: {
        Serial.println(MODE);
      }
    }
  }
}

void setColor(int redValue, int greenValue, int blueValue) {
  analogWrite(RED, redValue);
  analogWrite(GREEN, greenValue);
  analogWrite(BLUE, blueValue);
}


//        FLASH:       //

 void FLASH_SLOW() {
  MODE = "FLASH_SLOW";
  
  while (MODE = "FLASH_SLOW") {
  setColor(0, 0, 255);
  delay(400);
  setColor(0, 255, 0);
  delay(400);
  setColor(255, 0, 0);
  delay(400);
  }
  
}

 void FLASH_MED() {
  MODE = "FLASH_MED";
  
  while (MODE = "FLASH_MED") {
  setColor(0, 0, 255);
  delay(300);
  setColor(0, 255, 0);
  delay(300);
  setColor(255, 0, 0);
  delay(300); 
  }

}

 void FLASH_FAST() {
  MODE = "FLASH_FAST";

  while (MODE = "FLASH_FAST") {
  setColor(0, 0, 255);
  delay(200);
  setColor(0, 255, 0);
  delay(200);
  setColor(255, 0, 0);
  delay(200); 
  }
  
}

delay() cannot be prematurely terminated.

Instead, learn how to use millis() to time events (as many events as you like). One place to start with this tutorial: https://www.baldengineer.com/blink-without-delay-explained.html

More advanced demo:

The way to do it is not to use delay(). Whilst the delay() is occurring then nothing else, including reading inputs, can happen. Use non blocking timing using millis() instead

See Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

you may be interested in this

#define RED   12
#define GREEN 10
#define BLUE  11

const int On  = LOW;
const int Off = HIGH;

unsigned long msecPeriod;
unsigned long msec0;

byte          PinLeds [] = { RED, GREEN, BLUE };
int           Nleds = sizeof(PinLeds);
int           idx;

// -----------------------------------------------------------------------------
void loop ( )
{
    unsigned long msec = millis ();

    // check for timed actions
    if (msecPeriod && msec - msec0 >= msecPeriod) {
        msec0 += msecPeriod;

        digitalWrite (PinLeds [idx], Off);
        if (Nleds <= ++idx)
            idx = 0;
        digitalWrite (PinLeds [idx], On);
    }

    // check for new command
    if (Serial.available ()) {
        char buf [20];
        int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
        buf [n] = '\0';

        int command = atoi (buf);

        // reset
        msecPeriod = 0;
        digitalWrite (RED,   Off);
        digitalWrite (BLUE,  Off);
        digitalWrite (GREEN, Off);

        // process command
        switch (command) {
        case 12:
            digitalWrite (RED, On);
            break;

        case 24:
            digitalWrite (GREEN, On);
            break;

        case 94:
            digitalWrite (BLUE, On);
            break;

        case 22:
            digitalWrite (RED,   On);
            digitalWrite (BLUE,  On);
            digitalWrite (GREEN, On);
            break;

        case 8:
            msecPeriod = 400;
            break;

        case 28:
            msecPeriod = 300;
            break;

        case 90:
            msecPeriod = 200;
            break;

        default:
            Serial.print   (" unknown command - ");
            Serial.println (command);

            Serial.println (" 12 - RED");
            Serial.println (" 24 - GREEN");
            Serial.println (" 94 - BLUE");
            Serial.println (" 22 - WHITE");
            Serial.println ("  8 - slow");
            Serial.println (" 28 - medium");
            Serial.println (" 90 - fast");
            break;
        }
    }
}

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);

    pinMode (RED,   OUTPUT);
    pinMode (GREEN, OUTPUT);
    pinMode (BLUE,  OUTPUT);
}

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