Cycling trough different lighting patterns with a push button

I am working on a christmas lighting-ish project involving an 20 different lighting groups flashing. I have programmed a few effects but I would like to be able to cycle through these effects using a single push button. Does anyone know how to do this?

I know this has been asked before, but I couldnt find one that really helped me, feel free to link to another topic if it contains the solution.

This is my code so far:

int var = 1;
int switch = 0;

void setup() {
  
  for (int pin = 22; pin <= 41; pin++ ){
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
  }
}

void loop() {
quadblink(1);
}

void allon() {
  for (int pin = 22; pin<= 41; pin++){
    digitalWrite(pin, LOW);  
  }
}

void alloff() {
  for (int pin = 22; pin<= 41; pin++){
    digitalWrite(pin, HIGH);  
  }
}

void snake() {
  for (int i = 0; i <=19; i++){
    for (int pin = 22; pin<= 41 - i; pin++){
      digitalWrite(pin - 1, HIGH);
      digitalWrite(pin, LOW);
      delay(160);
    }
  }
}

void allblink(int times){
  for (int i = 1; i <= 4 * times; i++){
    var = (var + 1) % 2;
    for (int pin = 22; pin <= 41; pin++){
      if(pin % 2 == var){
        digitalWrite(pin, LOW);  
      }else{
         digitalWrite(pin, HIGH);
      }
    }
    delay(250);
  }
}

void quadblink(int times) {
  for (int i = 1; i <= 20 * times; i++){
    var = (var + 1) % 4;

    for (int pin = 22; pin <= 41; pin++){
      if(pin % 4 == var){
        digitalWrite(pin, LOW);  
      }else{
         digitalWrite(pin, HIGH);
      }
    }
    delay(250);
  }
}

void randa(int times) {
  for (int i = 1; i <= 100 * times; i++){
    digitalWrite(random(22,42), LOW);
    digitalWrite(random(22,42), HIGH);
    delay(100);
  }  
}


Daan

Does anyone know how to do this?

It's only been done at 4,558,444,477 times, so there is a very good chance that the answer is yes.

In fact, the state change detection example shows how.

Could you be a bit more specific?

Could you be a bit more specific?

I don't see how. You want to do something on each pass through loop() that depends on how many times a switch has been pressed. The state change detection example shows how to count the number of times a switch has been pressed.

Perhaps something simple like this, using switch:case syntax.

void loop(){
if (digitalRead(button) == LOW){ // button is setup as pinMode (button, INPUT_PULLUP); and
                                                      // pin connects to Gnd when button is pressed
sequence = sequence +1;
}
if (sequence >=sequenceMax){
sequence = 0; // reset to top
}
// use the time to run each sequence as the switch debounce time
switch(sequence):
case 0: // allon
  for (int pin = 22; pin<= 41; pin++){
    digitalWrite(pin, LOW);  
  }
break;
case 1: // alloff

  for (int pin = 22; pin<= 41; pin++){
    digitalWrite(pin, HIGH);  
  }
break;

case 2: // snake
  for (int i = 0; i <=19; i++){
    for (int pin = 22; pin<= 41 - i; pin++){
      digitalWrite(pin - 1, HIGH);
      digitalWrite(pin, LOW);
      delay(160);
    }
  }
break;
case 3:
// etc - not sure how you'd feed "times" into these.

void allblink(int times){
  for (int i = 1; i <= 4 * times; i++){
    var = (var + 1) % 2;
    for (int pin = 22; pin <= 41; pin++){
      if(pin % 2 == var){
        digitalWrite(pin, LOW);  
      }else{
         digitalWrite(pin, HIGH);
      }
    }
    delay(250);
  }
}

void quadblink(int times) {
  for (int i = 1; i <= 20 * times; i++){
    var = (var + 1) % 4;

    for (int pin = 22; pin <= 41; pin++){
      if(pin % 4 == var){
        digitalWrite(pin, LOW);  
      }else{
         digitalWrite(pin, HIGH);
      }
    }
    delay(250);
  }
}

void randa(int times) {
  for (int i = 1; i <= 100 * times; i++){
    digitalWrite(random(22,42), LOW);
    digitalWrite(random(22,42), HIGH);
    delay(100);
  }  
}
} // end switch
} // end loop

The simple digitalRead() function will tell you if the switch is currently pressed (or not pressed). But it doesn't tell you if it has recently changed. Because this example needs to detect that the button has become pushed (when it wasn't previously pushed) in order to advance the pattern to the next pattern number.

Also look for debouncing as a physical button can generate many on/off cycles when it's pushed or released. See https://www.arduino.cc/en/Tutorial/Debounce

You'll also have to get rid of the delays and for loops in the lighting effect functions if you want the button to be responsive at all. Those functions should use millis based timing and only perform one small step of the effect at a time. They should rely on being called over and over and over again from loop to draw out the whole effect instead of trying to stay in the one function and finish the whole thing in one pass.