Need Help With Police Light Modes

I just happened to have a board here with a few LEDs, so I threw this together quickly. Not as many LEDs, and just two flashing modes, but just to show the idea. Note there are no calls to delay().

Also note the switch is wired differently from yours, just from the pin to ground, no resistor, since the internal pullup resistor is used instead.

There are three modes: Off, Blinker and Chaser. There is a function for each: ledsOff(), blinker() and chaser().

Each has one argument to indicate initialization, i.e. the first call after changing modes. This is to ensure each mode always starts in a consistent state.

Therefore the state machine has six modes, an init mode for each mode, that only calls the function once, then a run mode for each.

#include <Button.h>                            //https://github.com/JChristensen/Button
#define BUTTON_PIN 2                           //wire the button between this pin and ground
#define TACT_DEBOUNCE 25                       //debounce time for tact switches, milliseconds
#define BLINK_INTERVAL 500                     //interval for blinker(), ms
#define CHASE_INTERVAL 200                     //interval for chaser(), ms
int8_t LED[] = { 5, 6, 7, 8 };                 //LEDs connected from these pins to ground, through appropriate current-limiting resistors
#define nLED sizeof(LED)/sizeof(LED[0])        //number of LEDs

Button btnMode = Button(BUTTON_PIN, true, true, TACT_DEBOUNCE);            //instantiate the button
enum MODES {OFF_INIT, OFF, BLINK_INIT, BLINK, CHASE_INIT, CHASE, LAST};    //LAST is not a "real" mode, just used to wrap back to the first mode.
uint8_t MODE;
unsigned long ms;

void setup(void)
{
    for (int i = 0; i < nLED; i++) {
        pinMode(LED[i], OUTPUT);
    }
}

void loop(void)
{
    ms = millis();
    btnMode.read();
    if ( btnMode.wasReleased() )
        if (++MODE >= LAST) MODE = OFF_INIT;
    
    switch (MODE) {
        case OFF_INIT:
            ledsOff(true);
            ++MODE;
            break;
        
        case OFF:
            ledsOff(false);
            break;
        
        case BLINK_INIT:
            blinker(true);
            ++MODE;
            break;
            
        case BLINK:
            blinker(false);
            break;
            
        case CHASE_INIT:
            chaser(true);
            ++MODE;
            break;

        case CHASE:
            chaser(false);
            break;
            
    }        
}

void ledsOff(boolean init)
{
    if (init) {
        for (int i = 0; i < nLED; i++) {
            digitalWrite(LED[i], LOW);
        }
    }
}

void blinker(boolean init)
{
    static unsigned long msLast;
    static boolean ledState;
    
    if (init) {
        msLast = ms;
        ledState = HIGH;
        for (int i = 0; i < nLED; i++) {
            digitalWrite(LED[i], ledState);
        }
    }
    else if (ms - msLast >= BLINK_INTERVAL) {
        msLast = ms;
        ledState = !ledState;
        for (int i = 0; i < nLED; i++) {
            digitalWrite(LED[i], ledState);
        }
    }       
}
    
void chaser(boolean init)
{
    static unsigned long msLast;
    static uint8_t onLED;

    if (init) {
        msLast = ms;
        onLED = 1;
        digitalWrite(LED[0], HIGH);
        for (int i = 1; i < nLED; i++) {
            digitalWrite(LED[i], LOW);
        }
    }
    else if (ms - msLast >= CHASE_INTERVAL) {
        msLast = ms;
        for (int i = 0; i < nLED; i++) {        //iterate through all the LEDs
            if (i == onLED)                     //just turn the current LED on, turn the rest off
                digitalWrite(LED[i], HIGH);
            else
                digitalWrite(LED[i], LOW);
        }
        if (++onLED >= nLED) onLED = 0;         //next LED, or start over with the first LED
    }       

}