Run light sequence function continuously in if statement

Thanks for checking out this question!

My goal - run light sequence function on momentary button press (button 2) continuously until another of the 3 momentary buttons are pressed.

  /* switch
     * 
     * Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
     * press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
     * a minimum delay between toggles to debounce the circuit (i.e. to ignore
     * noise).  
     *
     * David A. Mellis
     * 21 November 2006
     */
     #include "FastLED.h"
    
    int inPin = 8;         // the number of the input pin
    int inPinTwo = 9;
    int inPinThree = 10;
    int outPin = 13;       // the number of the output pin
    
    int state = HIGH;      // the current state of the output pin
    int reading;           // the current reading from the input pin
    int readingTwo;
    int readingThree;
    int previous = LOW;    // the previous reading from the input pin
    
    int pixelNumber;
    
    // the follow variables are long's because the time, measured in miliseconds,
    // will quickly become a bigger number than can be stored in an int.
    long time = 0;         // the last time the output pin was toggled
    long debounce = 200;   // the debounce time, increase if the output flickers
    
    //NEOPIXEL
    #define LED_PIN     7
    #define LEDPIN 7
    #define LED_TYPE     NEOPIXEL
    #define NUM_LEDS    2
    #define BRIGHTNESS 10
    #define FRAMES_PER_SECOND 60
    CRGB leds[NUM_LEDS];
    #define COLOR_ORDER GRB
    #define CHIPSET     WS2811
    
    bool gReverseDirection = false;
    CRGBPalette16 gPal;
    
    void setup()
    {
      
      
      pinMode(inPin, INPUT);
      pinMode(inPinTwo,INPUT);
      pinMode(inPinThree,INPUT);
      pinMode(outPin, OUTPUT);
    
      Serial.begin(9600);
    
      // set up LED strip info
    FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
    FastLED.setBrightness(BRIGHTNESS);
    }
    
    void loop()
    {
      
     
    //    BUTTON 1 - SOLID LIGHT
      reading = digitalRead(inPin);
    
      // if the input just went from LOW and HIGH and we've waited long enough
      // to ignore any noise on the circuit, toggle the output pin and remember
      // the time
      if (reading == HIGH && previous == LOW && millis() - time > debounce) {
        if (state == HIGH){
          state = LOW;
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
        }
        else{
          state = HIGH;
          fill_solid(leds,NUM_LEDS,0xFAF6D1);
          FastLED.show();
          }
    
        time = millis();    
      
      }
        digitalWrite(outPin, state);
        previous = reading;
    
    //  BUTTON 2 - GLITTER LIGHT
       readingTwo = digitalRead(inPinTwo);
      if (readingTwo == HIGH && previous == LOW && millis() - time> debounce){
        if(state == HIGH){
          state = LOW;
          fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);
          FastLED.show();
          }
        else{
          state = HIGH;
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
        }
    
        time = millis();
        }
        digitalWrite(outPin,state);
        previous = readingTwo;
            
        
    //  BUTTON 3  - MOVEMENT SENSOR LIGHT
           readingThree = digitalRead(inPinThree);
      if (readingThree == HIGH && previous == LOW && millis() - time> debounce){
        if(state == HIGH){
          state = LOW;
           fill_solid(leds,NUM_LEDS,CRGB::Black);
            FastLED.show();
          }
        else{
          state = HIGH;
          
        }
    
        time = millis();
        }
        digitalWrite(outPin,state);
        previous = readingThree;
    }
    
    //glitter effect
    void addGlitter( fract8 chanceOfGlitter) {
      if( random8() < chanceOfGlitter) {
        leds[ random16(NUM_LEDS) ] += CRGB::White;}
    }

The issue - the function seems to be only ran once (see button 2), which doesn’t achieve the required effect. I realize that changing this if statement to a while statement would be beneficial, but I cannot figure out how to break out of this while loop upon button press. I know that setting ‘state = LOW’ will break the while loop but if I leave it in, the light sequence function never runs.

 //  BUTTON 2
       readingTwo = digitalRead(inPinTwo);
      if (readingTwo == HIGH && previousTwo == LOW && millis() - time> debounce){
        while(state == HIGH){
    //      state = LOW;
          fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);
          FastLED.show();
      }
    
    
        while(state == LOW){
          state = HIGH;
         
          fill_solid(leds,NUM_LEDS,CRGB::Black);
            FastLED.show();

}

Any help would be greatly appreciated!

I know that setting 'state = LOW' will break the while loop but if I leave it in, the light sequence function never runs.

You have this:-

while(state == HIGH){
...........
      }

So that loop will continue until state changes to LOW.

You have nothing in that loop that will change the state variable, so you need to add something that will.

Reading all the buttons and changing the variable if any one is pressed will do this.

Thanks for responding Mike!

Grumpy_Mike:
Reading all the buttons and changing the variable if any one is pressed will do this.

I have the variable "state" that stores HIGH/LOW and changes when the buttons are pressed. Do I need another variable other than that? The if statements change the variables on each button press, but I cannot figure out how to inject that "state" variable into a while loop without immediately ending it.

but I cannot figure out how to inject that "state" variable into a while loop without immediately ending it.

You have to do a digital read inside the loop and change the state variable as a result of that read. Or not use a while loop at all, but another for loop that ends after a set number of iterations when the fade is complete.

This is what I came up with and it works! Thanks for your help Mike!
I added state btnPress which sets/reads the values and then run and if statement depending on that. I’m sure there’s a more elegant way to write this, but hey when it works it works.

 #include "FastLED.h"


int inPin = 8;         // the number of the input pin
int inPinTwo = 9;
int inPinThree = 10;
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin

int reading;           // the current reading from the input pin
int readingTwo;
int readingThree;
int previous = LOW;    // the previous reading from the input pin
volatile int change;
int btnPress;

int pixelNumber;



// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

//NEOPIXEL
#define LED_PIN     7
#define LEDPIN 7
#define LED_TYPE     NEOPIXEL
#define NUM_LEDS    2
#define BRIGHTNESS 255
#define FRAMES_PER_SECOND 60
CRGB leds[NUM_LEDS];
#define COLOR_ORDER GRB
#define CHIPSET     WS2812B


void setup()
{
  
  
//BUTTON  
  pinMode(inPin, INPUT);
  pinMode(inPinTwo,INPUT);
  pinMode(inPinThree,INPUT);
  pinMode(outPin, OUTPUT);

  Serial.begin(9600);

  // set up LED strip info
FastLED.addLeds<LED_TYPE,LEDPIN>(leds,NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
btnPress = 1;

}

void loop()
{
//    BUTTON 1 - SOLID LIGHT
  reading = digitalRead(inPin);
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH){
      state = LOW;
      btnPress = 1;
    }
    else{
      state = HIGH;
      btnPress = 2;
      }

    time = millis();    
  
  }
    digitalWrite(outPin, state);
    previous = reading;

//  BUTTON 2 - GLITTER LIGHT
   readingTwo = digitalRead(inPinTwo);
  if (readingTwo == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
      btnPress = 3;
      }
    else{
      state = HIGH;
      btnPress = 4;
    }
    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingTwo;
        
    
//  BUTTON 3  - MOVEMENT SENSOR LIGHT
       readingThree = digitalRead(inPinThree);
  if (readingThree == HIGH && previous == LOW && millis() - time> debounce){
    if(state == HIGH){
      state = LOW;
       btnPress = 5;
      }
    else{
      state = HIGH;
      btnPress = 6;
    }

    time = millis();
    }
    digitalWrite(outPin,state);
    previous = readingThree;

   

    //BUTTON 1 - SOLID LIGHT
     if (btnPress == 1){
          fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
      }
    
    if (btnPress == 2){
          fill_solid(leds,NUM_LEDS,0xFfffff);
          FastLED.show();
           
      }  
    
    //  BUTTON 2 - GLITTER LIGHT
    if (btnPress == 3){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
    
      }
    if (btnPress == 4){
         fadeToBlackBy( leds, NUM_LEDS, 10);
          addGlitter(30);
          FastLED.show();
      }
    
    //  BUTTON 3  - MOVEMENT SENSOR LIGHT
    if (btnPress == 5){
            fill_solid(leds,NUM_LEDS,CRGB::Black);
          FastLED.show();
    
      }
    if (btnPress == 6){
    
      }
  }


//glitter effect
void addGlitter( fract8 chanceOfGlitter) {
  if( random8() < chanceOfGlitter) {
    leds[ random16(NUM_LEDS) ] += CRGB::White;}
}


  }

Thanks for posting your solution, many people don't do that and leave people looking up the thread in the dark as to what you used.
Have a Kama point for that.