Understanding millis() pb

Hello everyone
I have a question about using the milli(s) expression.
i have the following code (might look familiar :stuck_out_tongue: );



```
int led1 = 1;
int led2 = 2;
int led3 = 3;
int led4 = 4;
int led5 = 5;
int led6 = 6;
int button = 8;
long drukTijd;

void setup(){                
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(button, INPUT);

                                // start opstelling
digitalWrite(led1, HIGH);
digitalWrite(led6, HIGH);}


void loop()
{
int state = digitalRead(button);
if(state == HIGH && (millis() - drukTijd)> 5000)
{changeLights();}
}

void changeLights(){

  digitalWrite(led1,LOW);
  digitalWrite(led6,LOW);
  digitalWrite(led3,HIGH);
  digitalWrite(led4,HIGH);
  delay (2000);

  digitalWrite(led2,HIGH);
  digitalWrite(led5,HIGH);
  digitalWrite(led3,LOW);
  digitalWrite(led4,LOW);
  delay (2000);

  digitalWrite(led1,HIGH);
  digitalWrite(led6,HIGH);
  digitalWrite(led2,LOW);
  digitalWrite(led5,LOW);
  delay (2000);
```

my question is about the following lines;
int state = digitalRead(button);
if(state == HIGH && (millis() - drukTijd)> 5000)

why does this work ? in my eyes im telling the program;
if button is high and (milliseconds - a number between -2147483648 ~ 2147483647) > 5000, and it works, how ? what am i really reffering to ?
so a unit of time - a number, converted to time compared to an amount of time.

also;
does this mean by typing drukTijd between the brackets with millis, i have now converted drukTijd to be an amount of time ? instead of being a counter, its now still a counter and i added the unit time to it?

side note:
it doesnt work as intended
if i load it up and press the button within 5 seconds it wont run,
then if i press the button after 5 seconds it runs as intended and i cant restart it by pressing the button again, which is what i want.
but, when the program runs, and finishes, i can start it again instantly, even when 5secs havnt passed, why is this ?

ive also adjusted the delays to 500, so the program is done after 1,5secs but i can still rerun it instantly, so what is wrong with my counter ?
how do i program it so that it can be pressed instantly, but wont re run within 5 seconds

thanks for your help in advance

quick note:
Any millis related variables should be unsigned long

So this is wrong:

1 Like

Just a guess, but is your button pulling the input pin low rather than high? Have you correctly set an external pull-down resistor?

To be clear, you should set the switch input to INPUT_PULLUP, and then pull it down with the switch. I think you would then need to alter your code to look for a low on the input.

1 Like

The value of drukTijd is never changed from its initial value of zero which it is given when declared as a global variable. Note that it should really be declared as an unsigned long

So, when you subtract zero from millis() what you get is the current value of millis(). Effectively the line of code

 if (state == HIGH && (millis() - drukTijd) > 5000)

Is testing whether the button state is HIGH and whether 5 seconds has passed since the sketch started

If you want to start the 5 second timing period again then what you should do is set drukTijd to the current value of millis() when the timing period starts

1 Like

so the decleration
`long drukTijd;'
is also wrong ?

and should be unsigned long drukTijd; if i get it right ?

Correct

Using an unsigned variable allows you to program timing without causing problems when the value of miilis() rolls over to zero after 49 and a bit days

1 Like

it shouldnt be its a maker button,
ive changed the switch to INPUT_PULLUP and had it look for low, but than it just acts like the button is allways pressed, (which makes sense button being maker), whats interesting is that it completely ignores the
(millis() - drukTijd)> 5000)
part and just keeps looping
changeLights

ive set it up hardware wise:

5v --- switch in
switch out --- resistor 220 ohm --- ground
switch out --- input 8

how can i do that since the current value changes all the time ?

You save the value when the timing period starts

See Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

1 Like

save the first current time (millis()) in a variable and compare it with the current time.

1 Like

What did you want this to do?

void loop()
{
  int state = digitalRead(button);
  if (state == HIGH && (millis() - drukTijd) > 5000)
  {
    changeLights();
  }
}

If you want to ignore the button until it has been more than five seconds since the last time the lights were active:

void loop()
{
  int state = digitalRead(button);
  if (state == HIGH && (millis() - drukTijd) > 5000)
  {
    changeLights();
    drukTijd = millis(); // Start the 'ignore button' timer.
  }
}
1 Like

aah and it all falls into place, i was wondering why i didnt have to assign drukTijd to an output in some way, so if i get it right the druktijd = millis() command "stamps" the time from start to point x(changelights in this case), and when millis surpasses that time > 5000 it will be "true" and the value drukTijd will be overruled to the next amount of time, this time from start to the 2nd "true"?

This may help.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.