Combining led blink and fade (PWM)

UKHeliBob:
Here is an extended example of a state machine controlling LEDs

const byte ledPins[] = {5, 6, 9, 10};

byte LEDCOUNT = sizeof(ledPins) / sizeof(ledPins[0]);
byte ledIndex = 0;
const unsigned long FIVESECS = 5000;
unsigned long currentTime;
unsigned long startTime;

enum states
{
  ALL_FADE_UP_TOGETHER,
  ALL_ON_FOR_5_SECS,
  ALL_FADE_DOWN_TOGETHER,
  ALL_FADE_UP_DOWN_IN_SEQUENCE,
  DO_NOTHING
};
byte currentState = ALL_FADE_UP_TOGETHER;

void setup()
{
  Serial.begin(115200);
  for (int pin = 0; pin < LEDCOUNT; pin ++)
  {
    pinMode(ledPins[pin], OUTPUT);
    digitalWrite(ledPins[pin], HIGH);
  }
  Serial.println("Fading all up together");
}

void loop()
{
  currentTime = millis();
  switch (currentState)
  {
    case ALL_FADE_UP_TOGETHER:
      {
        static int pwmLevel = 255;
        static int pwmIncrement = -1;
        unsigned long period = 20;
        if (currentTime - startTime >= period)
        {
          setPwmLevelForAllLeds(pwmLevel);
          startTime = millis();
          pwmLevel += pwmIncrement;
          if (pwmLevel <= 0)
          {
            setPwmLevelForAllLeds(255);
            currentState = ALL_ON_FOR_5_SECS;
            startTime = currentTime;
            setPwmLevelForAllLeds(0);  //all on
            Serial.println("Waiting 5 seconds");
          }
        }
      }
      break;
    //*****
    case ALL_ON_FOR_5_SECS:
      if (currentTime - startTime >= FIVESECS)
      {
        currentState = ALL_FADE_DOWN_TOGETHER;
        Serial.println("Fading all down together");
        startTime = currentTime;
        setPwmLevelForAllLeds(0);  //all on
      }
      break;
    //*****     
    case ALL_FADE_DOWN_TOGETHER:
      //    case ALL_FADE_UP_TOGETHER:
      {
        static int pwmLevel = 0;
        static int pwmIncrement = 1;
        unsigned long period = 20;
        if (currentTime - startTime >= period)
        {
          setPwmLevelForAllLeds(pwmLevel);
          startTime = millis();
          pwmLevel += pwmIncrement;
          if (pwmLevel >= 255)
          {
            setPwmLevelForAllLeds(255);  //all off
            currentState = ALL_FADE_UP_DOWN_IN_SEQUENCE;
            startTime = currentTime;
            setPwmLevelForAllLeds(255);  //all off
            Serial.println("Fading all up down in sequence");
          }
        }
      }
      break;
    //*****
    case ALL_FADE_UP_DOWN_IN_SEQUENCE:
      {
        static unsigned long startTime;
        static int pwmLevel = 255;
        static int pwmIncrement = -1;
        unsigned long period = 5;
        if (currentTime - startTime >= period)
        {
          analogWrite(ledPins[ledIndex], pwmLevel);
          startTime = millis();
          pwmLevel += pwmIncrement;
          if (pwmLevel <= 0)
          {
            pwmIncrement = -1;
            pwmLevel += pwmIncrement;
          }
          if (pwmLevel >= 255)
          {
            pwmLevel = 255;
            analogWrite(ledPins[ledIndex], pwmLevel);  //make sure that the  LED is off
            pwmIncrement = -1;
            ledIndex++;
            if (ledIndex >= LEDCOUNT)
            {
              currentState = DO_NOTHING;
              Serial.println("Doing nothing forever");
            }
          }
          break;
        }
      }
    //
***
    case DO_NOTHING:
      {
        break;
      }
  }
}
void setPwmLevelForAllLeds(byte pwmLevel)
{
  for (int ledIndex = 0; ledIndex < LEDCOUNT; ledIndex++)
  {
    analogWrite(ledPins[ledIndex], pwmLevel);
  }
}




NOTES :

it runs on a Uno and uses 4 LEDs

The LEDs on my test system are active LOW, ie they are at max brightness when the output driving them is at zero (LOW). You will need to adjust either your hardware or the program

There are no delay()s in the program and all timing is done using millis()

It includes an example of waiting for a period apparently doing nothing, but loop() is still running freely so the program could do other things such as reading an input to change or cancel the sequence

The states are held in an enum and have explicit names which I find helpful

The program gives you a status report of what it is doing on the Serial monitor

When it enters the DO_NOTHING state it is actually very busy doing nothing !

It has not been extensively tested or optimised but seems to work

The variables could undoubtedly be tidied up to use more local variables. As it is there is a mish-mash of local and global variables.

Really appreciate !!!

I've tried 13 led on my previous code and the light works fine cause I got a battery for it I guess.

Trying to understand the code now... couple questions from beginner...

If I want to put more state in the code, besides setting in enum,
what else should I write for : (led7 fade in/out, led6&8 fade in/out) ?

appreciate for big help guys!!!