Using timer

Hi, I'm a new Arduino owner and programmer and I need some help with an timer.

I want to do a program to execute some actions and one for a determined time (for example: 5 minutes) as open a valve, but while the valve is open (for the 5 minutes) I want the Arduino doing other actions like update the informations on the LCD display, blink a LED,... How can I use a timer without using delay function?
I've tried the millis funcition, but it counts the time that the program started and I don't know exactly how to use it.

Thanks!

Hint : millis() + math will do it.

-jim lee

There are a useful links in this sticky

Blink without delay
Seversl things ...
Planning snd implementing ...

jimLee:
Hint : millis() + math will do it.

-jim lee

Thanks for the tips... I'm kind of a newbie and I still cat't use the millis.

Can you, please, send me a tip or a model of it?

Thanks!!!

When you want to start your "5 minutes" look at the clock on the wall. It doesn't say zero does it? It says 15:32 or whatever.

Look at the clock again, several thousand times per second.

When ClockTime-StartTime is greater than 5 minutes, do the action required such as turning off an output pin.

The subtraction is important. Don't add times. Using subtraction will prevent the "rollover error".

MorganS:
The subtraction is important. Don't add times. Using subtraction will prevent the "rollover error".

No, you just get a different rollover error. If lastTime is ULONG_MAX and thisTime is 0 (one millisecond later), then thisTime - lastTime will instead have you thinking that ~50 days have elapsed. But I guess just about everybody is happy to experience that once-in-50-days time-warp, because just about everybody implements it. :slight_smile:

MorganS:
When you want to start your "5 minutes" look at the clock on the wall. It doesn't say zero does it? It says 15:32 or whatever.

Look at the clock again, several thousand times per second.

When ClockTime-StartTime is greater than 5 minutes, do the action required such as turning off an output pin.

The subtraction is important. Don't add times. Using subtraction will prevent the "rollover error".

When the code is like this works just perfect:

void loop() {
// put your main code here, to run repeatedly:

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
currentMillis = millis();
if((unsigned long)(currentMillis - previousMillis) < 5000){
digitalWrite(2,HIGH);
previousMillis = millis();
}
else{
digitalWrite(2,LOW);
}
}

The LED lights up and after 5 secs turn off.

But when I put a if clause before the millis the problem starts...

void loop() {
// put your main code here, to run repeatedly:
int buttonStatus = digitalRead(4);
if(buttonStatus == 1){
unsigned long currentMillis;
unsigned long previousMillis = 0;
currentMillis = millis();
if((unsigned long)(currentMillis - previousMillis) < 5000){
digitalWrite(2,HIGH);
previousMillis = millis();
}
else{
digitalWrite(2,LOW);
}
}
}

If I press the button before 5 secs after the reset, the LED lights up and not turn off. If I press the button after 5 secs since the last reset nothing happens.

What am I doing wrong? :`(

Thanks everybody!

jaholmes:
If lastTime is ULONG_MAX and thisTime is 0 (one millisecond later), then thisTime - lastTime will instead have you thinking that ~50 days have elapsed.

No.

#include <limits.h>
void setup() {
  unsigned long lastTime = ULONG_MAX;
  unsigned long thisTime = 0;
  Serial.begin(250000);
  Serial.print(thisTime);
  Serial.print(F(" - "));
  Serial.print(lastTime);
  Serial.print(F(" = "));
  Serial.println(thisTime - lastTime);
}
void loop() {}

0 - 4294967295 = 1As expected.

Whandall:
No.

#include <limits.h>

void setup() {
  unsigned long lastTime = ULONG_MAX;
  unsigned long thisTime = 0;
  Serial.begin(250000);
  Serial.print(thisTime);
  Serial.print(F(" - "));
  Serial.print(lastTime);
  Serial.print(F(" = "));
  Serial.println(thisTime - lastTime);
}
void loop() {}


`0 - 4294967295 = 1`As expected.

Oh golly. Yes, brain out to lunch and forgot how integer underflow worked! :stuck_out_tongue:

Is this should work?

unsigned long time0 = millis();
while((time0 + 2000) > millis()){
(...)

Thanks!

It will not work reliably and the while blocks.

Remember you are going through loop() a zillion times a second. Just look at the clock on your way through. Then you can look at it a lot without blocking.

-jim lee

Thanks everybody!!!

Using if is a better choice?

unsigned long time0 = millis();
if((time0 + 2000) > millis()){
(...)

Jim Lee I'm sorry, but I got a little confused... What's wrong? Or better asking, what I should do in the code above?
I'm a complete newbie and I'm sorry if sometimes I get stuck or keep asking the same thing... =(

instead of your while() loop you had above. You are actually already inside a big loop. That's all.

-jim lee

Thanks!!!!!