Switch Case break issue - How to Play pattern and still Switch Case back to 1

Hi, I'm sorry that the subject title is so vague. My project is a controller for a relay module connect to a marquee light, a relay for each letter.

I'm using a switch case sequence, which cycles through 3 different LEDs, representing 3 modes. The modes are (case 1) ALL RELAYS OFF, (case 2) ALL RELAYS ON, and (case 3) Relay Pattern Program.

I've noticed that when I put the break; line above the relay pattern code in case 3, I'm able to switch back to case 1, via a pushbutton - however, the pattern program does not play. If I put the break; line after the pattern code, then the pattern program plays, but the switch function does not work. I'm still new to programming, but is there something similar to a coroutine that I can use to make sure that I can still use the button and switch back to case 1, while the relay pattern is looping?

#define button 12
#define redLED 9
#define greenLED 10
#define blueLED 11

// Red LED :
int ledRed = 9; // the PWM pin the LED is attached to
int brightnessRed = 0; // how bright the LED is
int fadeAmountRed = 9; // how many points to fade the LED by

// Green LED :
int ledGreen = 10; // the PWM pin the LED is attached to
int brightnessGreen = 0; // how bright the LED is
int fadeAmountGreen = 5; // how many points to fade the LED by

// Blue LED :
int ledBlue = 11; // the PWM pin the LED is attached to
int brightnessBlue = 0; // how bright the LED is
int fadeAmountBlue = 5; // how many points to fade the LED by

int state = 1; //holds current state
int old = 0; //holds last state
int buttonPoll = 0; //hold button state

void setup() {
// initialize 6 digital pins as outputs.
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);

pinMode (button, INPUT); //button
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(blueLED, OUTPUT);

digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);

digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);

}

void loop() {

//debouncing routine , reading button
buttonPoll = digitalRead(button); //polls state of button
if(buttonPoll ==1) { //checks if pressed
delay(50); //wait 50 ms
buttonPoll = digitalRead(button); // poll button again
if(buttonPoll == 0) { //if it is 0 considered one press
state = old +1; //increase state by 1;
}}
else{ //if button not pressed
delay(50); //wait 50ms
}

switch (state) {
case 1:
//Red LED Indicator / MARQUEE OFF
digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
//ALL RELAYS OFF / MARQUEE OFF
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);

old = state;
break;

case 2:
//Green LED Indicator/ FULL MARQUEE
digitalWrite(redLED, LOW);
digitalWrite(greenLED, HIGH);
digitalWrite(blueLED, LOW);
//ALL RELAYS ON / FULL MARQUEE
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);

old = state;
break;

case 3:
//Blue LED Indicator / Marquee Pattern ON
digitalWrite(redLED, LOW);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, HIGH);

old = state;

// Program - Marquee Pattern:

// Starts with all relays off, for 1200 ms:
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(800);

// One by one turns on:
digitalWrite(1, LOW);
delay(800);
digitalWrite(2, LOW);
delay(800);
digitalWrite(3, LOW);
delay(800);
digitalWrite(4, LOW);
delay(800);
digitalWrite(5, LOW);
delay(800);
digitalWrite(6, LOW);
delay(800);
digitalWrite(7, LOW);
delay(800);
digitalWrite(8, LOW);

// All are on for about 7 seconds
delay(6600);

// 1
//All turn off for 800 ms:
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(800);

//All turn on for 800 ms:
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(800);

// 2
//All turn off for 800 ms:
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(800);

//All turn on for 800 ms:
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(800);

// 3
//All turn off for 800 ms:
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(800);

//All turn on for 800 ms:
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(800);

// 4
//All turn off for 800 ms:
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
delay(800);

//All turn on for 4 seconds:
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
delay(6600);

// All turn off in step sequence, then off for 4 seconds
digitalWrite(1, HIGH);
delay(120);
digitalWrite(2, HIGH);
delay(120);
digitalWrite(3, HIGH);
delay(120);
digitalWrite(4, HIGH);
delay(120);
digitalWrite(5, HIGH);
delay(120);
digitalWrite(6, HIGH);
delay(120);
delay(2400);

break;

default:

digitalWrite(redLED, HIGH);
digitalWrite(greenLED, LOW);
digitalWrite(blueLED, LOW);
old = 1;

}

}

I do see now that this is how we use the millis() function, as in the Blink without Delay example sketch. Unfortunately, I don't see any simple way to convert my code into this style, instead of using the delay() function...

If anyone has any advice, Thank you in advance!!

Try to start from scratch using millis () of course. Try to utilize array.

Your reply seems to suggest that you know what you should do but you just don't want to do it.

A possible outline. Give the marquee sequence its own switch/case within case 3. You could even put it in a function and call it when at state 3. You'll need a free running millis() timer outside the switch.

The dwellTimer is reset by setting its accumulated value equal to millis(). It's done when accumulated ( millis() - preset ) >= preset.

Untested.

Further down the road you could save a lot of code by putting the repetitive digitalWrite(X,HIGH) sequences in for() loops.

case 1:
  set state 1 outputs
  load dwellTimer preset
  reset dwellTimer
  set state = 2
break

case 2:
  if(dwellTimer done){  // state 1 finished, arrange things for state 2
    set state two outputs
    load dwellTimer preset // can be different for each state
    reset dwellTimer
    set state = 3
  }
break

case 3: 
like case 2
break