Combining led blink and fade (PWM)

I haven't tried the code yet cause it says 'NUM_STATE' was not declared in this scope,

That's because there is not a variable named NUM_STATE in your code.

There is, however, one named NUM_STATES

I understand the part you told me that I didn't set currentState to LED7_IN_OUT,
but the last part you said I afraid that I could not total understand as a poor English speaker like me....

Sorry... Could you show me an example please.. It's been a little bit hard for me to read these much vocabulary which is difficult for me... sorry...

If we carry on like this I will end up writing the whole program for you. What I was aiming to do was to give you examples to work from.

Look at your LED7_IN_OUT code and work through what it does by writing down the value of each variable as if you were the computer. You should see the problem of the confusion that I mentioned.

I suggest that you start by adding some test states that simply print messages and move between them. This will give you practice of defining and using states. For now write the code for the single LED fading states as hard code in the state within switch/state. You can make it more compact later.

Once you have one LED fading up/down you can simply copy/paste it into another state and change the LED number.

klansie:
Thanks, I haven't tried the code yet cause it says 'NUM_STATE' was not declared in this scope, What should I define NUM_STATE as ?

As UKHeliBob has pointed out, there is missing and "S" at the end, typo. There is also another brainfart, the line "i = state - 4" should have been "i = state - 5".

Hi!
I have tried this excellent code from UKHeliBob with some modifications

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,
...



...

What I want:
Im am running the machine all the time and by pass state "Do nothing";

  1. ALL_FADE_UP_TOGETHER,
  2. ALL_ON_FOR_5_SECS,
  3. ALL_FADE_DOWN_TOGETHER,
  4. ALL_OFF_FOR_5_SECS,
    No. 1 again and so on...

What happens:
Because the pwmLevel in state "ALL_FADE_DOWN_TOGHETER" is static when arduino runs the program second time it becomes 256, third 257 etcetera (or in my case -1, -2, depending on my connections).

I have tried
different IF-statements but gets a small flash before fading down.

Maybe there is standard solution to this?

   case ALL_FADE_DOWN_TOGETHER:
      //    case ALL_FADE_UP_TOGETHER:
      {
        static int pwmLevel = 255;
        static int pwmIncrement = 1;
        unsigned long period = 7;  // 7 egen

        if (currentTime - startTime >= period)
        {
          if (pwmLevel == -1)
          {
            Serial.println("Fade down level -1: ");
            Serial.println(pwmLevel);
            pwmLevel = 255;
          }

          setPwmLevelForAllLeds(pwmLevel);
          startTime = millis();
          Serial.println("Fade down - period: ");
          Serial.println(pwmLevel);
          pwmLevel -= pwmIncrement;

          if (pwmLevel == 0) // original <=
          {
            setPwmLevelForAllLeds(0);   //all off
            currentState = ALL_OFF_FOR_5_SECS;
            startTime = currentTime;

            setPwmLevelForAllLeds(0);   //all off
          }
        }
      }
      break;

Best Regards Johan

Maybe there is standard solution to this?

One way would be to make pwmLevel global and set its value before entering the ALL_FADE_DOWN_TOGETHER state.

Please post your complete program

Thank you for answer!
This is my code right now.

Maybe a global variable is the best?

//https://forum.arduino.cc/index.php?topic=548353.msg3740954#msg3740954

const byte ledPins[] = {10};
byte LEDCOUNT = sizeof(ledPins) / sizeof(ledPins[0]);
byte ledIndex = 0;
const unsigned long FIVESECS = 5000;
const unsigned long OFFSECS = 5000;

unsigned long currentTime;
unsigned long startTime;

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

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

void loop()
{
  currentTime = millis();
  switch (currentState)
  {
    case ALL_FLASH:
      {
        static int pwmLevel = 255;
        /*  static int pwmIncrement = -255;
          unsigned long period = 20;
          if (currentTime - startTime >= period)
          {*/
        Serial.println("All Flash: ");
        Serial.println(pwmLevel);
        setPwmLevelForAllLeds(pwmLevel);
        startTime = millis();
        //  pwmLevel += pwmIncrement;
        if (pwmLevel == 255)
        {
          setPwmLevelForAllLeds(0);
          currentState = ALL_ON_FOR_5_SECS;
          startTime = currentTime;
          setPwmLevelForAllLeds(255);   //all on
          Serial.println("All ON  5 seconds");
          // }
        }
      }
      break;
    //*****
    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(0);
            currentState = ALL_ON_FOR_5_SECS;
            startTime = currentTime;
            setPwmLevelForAllLeds(255);   //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(255);   //all on
      }
      break;
    //*****
    case ALL_OFF_FOR_5_SECS:
      if (currentTime - startTime >= OFFSECS)
      {
        currentState = ALL_FLASH;
        Serial.println("All flash");
        startTime = currentTime;
        setPwmLevelForAllLeds(255);   //all on
      }
      break;
    //*****
    case ALL_FADE_DOWN_TOGETHER:
      //    case ALL_FADE_UP_TOGETHER:
      {
        static int pwmLevel = 255;
        static int pwmIncrement = 1;
        unsigned long period = 7;  // 7 egen

        if (currentTime - startTime >= period)
        {
          if (pwmLevel == -1)
          {
            Serial.println("Fade down level -1: ");
            Serial.println(pwmLevel);
            pwmLevel = 255;
          }

          setPwmLevelForAllLeds(pwmLevel);
          startTime = millis();
          Serial.println("Fade down - period: ");
          Serial.println(pwmLevel);
          pwmLevel -= pwmIncrement;

          if (pwmLevel == 0) // original <=
          {
            setPwmLevelForAllLeds(0);   //all off
            currentState = ALL_OFF_FOR_5_SECS;
            startTime = currentTime;

            setPwmLevelForAllLeds(0);   //all off
          }
        }
      }
      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);
  }
}

Does the code do what you want ?

The advantage of using static is that the previous value persists the next time that the variable is declared in the same scope but it can also be a disadvantage. It is OK when a function or state is entered and the previous value is needed but can be awkward if you need to reset the variable to its initial value in which case a global variable is much more convenient to use.

You should note that in your program you have 4 different static variables named pwmLevel each with their own scope and each of which can have different values at the same time and it prevents that value being used in other scopes. This may be what you intend but at the very least it makes the program harder to follow and may not be what you intend. If the values of the 4 variables is only needed in their own scope then it would be better to give them individual names to avoid confusion.