Delay of several if statements

Hello all

I am trying to find a possibility to be able to add timing to serveral if's.

One if statement should finish. The one after that should only start after a delay and the third one after the delay attributed to it.

I have written the following code. I don't find the reason why it doesn't work. I especially don't understand why the third statement appears at almost the same time as the second no matter what delay I attribute put.

long previousReset = 0;
bool one = false;
bool two = false;
void setup() {
  Serial.begin(9600);


}

void loop() {
  if( (millis() - previousReset >= 1000)
      && (one == false) && (two == false) ){
    previousReset = millis();
    Serial.println("first");
    one = true;
  }
  if( (millis() - previousReset >= 3000)
      && (one == true) && (two == false) ){
    previousReset = millis;
    Serial.println("second");
    two = true;
    one = false;
  }
  if( (millis() - previousReset >= 15000)
      && (two == true) && (one == false) ){
    previousReset = millis();
    Serial.println("third");
    two = false;
  }
}

What better way is there to achieve this?

Thank you!

moses

In your second if statement you have

previousReset = millis;

Instead of:

previousReset = millis();

What is happening is the pointer to the function millis is being assigned to previousReset. Who knows what value that is...

i think switch statement for each case would be better. And calculate the time since the previous just once at the beginning, calling millis() just once.

unsigned long msec = millis();
unsigned long time = msec - previousReset;
static int state = 0;

swtich (state) {
case 0:
if (1000 < time) {
Serial.println ("first");
previousReset = msec;
state = 1;
}
break;
....
}

the last case sets state back to 0.

I saw the title and thought "I hope this isn't full of delay();s. Thankfully not. For using millis(); ++Karma;

I get:
first
(delay)
second
(delay)
third
(short delay)
first
...etc
So not what you described when you said

I especially don't understand why the third statement appears at almost the same time as the second

You don't need to use, for example:

one == true

or

one == false

just

one

on its own will do for true and

!one

for false.

You problem intrigued me but I am about to go out so cannot give it any more attention, sorry.

A more general method would be a state variable. That allows you to have many states with only one variable to keep track of.

unsigned long previousReset = 0;
byte state = 0;
void setup()
{
  Serial.begin(9600);
}


void loop()
{
  switch (state)
  {
    case 0:
      if (millis() - previousReset >= 1000)
      {
        Serial.println("first");
        previousReset = millis();
        state++;
      }
      break;


    case 1:
      if (millis() - previousReset >= 3000)
      {
        Serial.println("second");
        previousReset = millis();
        state++;
      }
      break;
      
    case 2:
      if (millis() - previousReset >= 15000)
      {
        Serial.println("third");
        previousReset = millis();
        state = 0;
      }
      break;
  }
}

Since all of your states do very much the same thing, using arrays would make sense here:

unsigned long previousReset = 0;
byte state = 0;


const char * StateNames[3] = {"first", "second", "third"};
const unsigned long StateDelays[3] = {1000, 3000, 15000};
const byte MaxState = 2;


void setup()
{
  Serial.begin(9600);
}


void loop()
{
  if (millis() - previousReset >= StateDelays[state])
  {
    Serial.println(StateNames[state]);
    previousReset = millis();
    state++;
    if (state > MaxState)
      state = 0;
  }
}

ToddL1962:
In your second if statement you have

previousReset = millis;

Instead of:

previousReset = millis();

What is happening is the pointer to the function millis is being assigned to previousReset. Who knows what value that is...

Oops! It's crazy I had a look at the code many times but it never caught my eye.

Thank you.

PerryBebbington:
I saw the title and thought "I hope this isn't full of delay();s. Thankfully not. For using millis(); ++Karma;

I get:
first
(delay)
second
(delay)
third
(short delay)
first
...etc
So not what you described when you said
You don't need to use, for example:

one == true

or

one == false

just

one

on its own will do for true and

!one

for false.

You problem intrigued me but I am about to go out so cannot give it any more attention, sorry.

Thank you for the Karma and the advises...

gciurpita:
i think switch statement for each case would be better. And calculate the time since the previous just once at the beginning, calling millis() just once.

unsigned long msec = millis();
unsigned long time = msec - previousReset;
static int state = 0;

swtich (state) {
case 0:
if (1000 < time) {
Serial.println ("first");
previousReset = msec;
state = 1;
}
break;
....
}

the last case sets state back to 0.

What would be the advantage of the "precalculation"?

johnwasser:
A more general method would be a state variable. That allows you to have many states with only one variable to keep track of.

unsigned long previousReset = 0;

byte state = 0;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  switch (state)
  {
    case 0:
      if (millis() - previousReset >= 1000)
      {
        Serial.println("first");
        previousReset = millis();
        state++;
      }
      break;

case 1:
      if (millis() - previousReset >= 3000)
      {
        Serial.println("second");
        previousReset = millis();
        state++;
      }
      break;
     
    case 2:
      if (millis() - previousReset >= 15000)
      {
        Serial.println("third");
        previousReset = millis();
        state = 0;
      }
      break;
  }
}





Since all of your states do very much the same thing, using arrays would make sense here:


unsigned long previousReset = 0;
byte state = 0;

const char * StateNames[3] = {"first", "second", "third"};
const unsigned long StateDelays[3] = {1000, 3000, 15000};
const byte MaxState = 2;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (millis() - previousReset >= StateDelays[state])
  {
    Serial.println(StateNames[state]);
    previousReset = millis();
    state++;
    if (state > MaxState)
      state = 0;
  }
}

Thank you for the two ideas!

Well the example was more of a "prove of concept" kind of thing.

I like the idea of the arrays. I need to have a look if this approach would be possible.

Could someone tell me which is the correct / better way of writing if statements and others:

if (compare) {
do something
do something else
} else {
do another thing
}

or

if (compare)
{
do something
do something else
}
else
{
do another thing
}

Thank you

Could someone tell me which is the correct / better way of writing if statements and others:

That depends on your definition of better. Personally I prefer the second style but with better indenting

if (compare)
{
  do something;
  do something else;
}
else
{
  do another thing;
}

The Auto formatting tool in the IDE can be configured to use this layout automatically

Thank you UKHeliBob

Does this mean there is no general rule of how to do it?

Is it a matter of preference?

moserroger:
What would be the advantage of the "precalculation"?

it's good practice to avoid redundant code.

Is it a matter of preference?

Yes. The compiler does not care about the layout of the code, only that the syntax is correct.

Similarly in the case of how variable names are written

Thank you again UKHeliBob

Now that we are talking about the blink without delay concept. I was wondering why I couldn't write the definition of the previous event in the loop part of the code. Why does it have to be in the header?

unsigned long previousmillis;

Thank you

moses

I was wondering why I couldn't write the definition of the previous event in the loop part of the code. Why does it have to be in the header?

Try it.

You'll learn about local variables, scope, loop() as a function, and static variable qualifiers.

//unsigned long previousmillis;
static unsigned long previousmillis = 0;

Hello cattledog

Thank you for the reply.

So far I never really understood about static even though I read about it. May be it will be getting clearer now. I will read about it again.

Cheers,

moses

Is there anything that speaks against using delay() in setup()? I guess the interruption of the code are less problematic in setup()?

moserroger:
Is there anything that speaks against using delay() in setup()?

Feel free to use it if you want the program to do nothing for a period of time

moserroger:
So far I never really understood about static even though I read about it. May be it will be getting clearer now. I will read about it again.

Possibly because static has several different meanings, depending on the context it is used in. Read carefully :slight_smile: