# Multiple timer problem

I have a facility where I am designing a "dead man" timer for 4 separate areas running from one Uno.

Basically, a timer runs for 15 minutes, and if there is no motion detected (a motion detector is in the area), an output goes HIGH. Anytime motion is detected, the timer needs to be set back to zero.

I'm currently setting the timers in this manner:

``````timer1 = (millis()/1000);
timer2 = (millis()/1000);
timer3 = (millis()/1000);
timer4 = (millis()/1000);
``````

The problem is, there are 4 timers running in 4 areas, so resetting the Uno would result in all areas resetting, which would prevent the other areas from working properly. In fact, the Uno might not ever be reset, in which point I'm worried about what's going to happen when the timers overflow.

Any way to bring the timers back to zero without resetting the board?

In fact, the Uno might not ever be reset, in which point I'm worried about what's going to happen when the timers overflow.

Have a look at blink without delay.

This is just blink without delay x 4.
Something like this.
Declare all time related variables as unsigned long.
unsigned long duration = 900000UL; // 900,000 mS = 15 minutes, 15 * 60 * 1000

``````void loop(){
currentTime = millis();
elapsedTime1 = currentTime - previousTime1;
elapsedTime2 = currentTime - previousTime2;
elapsedTime3 = currentTime - previousTime3;
elapsedTime4 = currentTime - previousTime4;
if (elapsedTime1 >=duration){
// nothing happened for 15 minutes
digitalWrite (output1, HIGH);
}
if (elapsedTime2 >=duration){
// nothing happened for 15 minutes
digitalWrite (output2, HIGH);
}
if (elapsedTime3 >=duration){
// nothing happened for 15 minutes
digitalWrite (output4, HIGH);
}
if (elapsedTime4 >=duration){
// nothing happened for 15 minutes
digitalWrite (output4, HIGH);
}
if (digitalRead (input1) == LOW){ // assumes motion detector pulls low
previousTime1 = millis; // reset 15 minute timer
}
if (digitalRead (input2) == LOW){ // assumes motion detector pulls low
previousTime2 = millis; // reset 15 minute timer
}
if (digitalRead (input3) == LOW){ // assumes motion detector pulls low
previousTime3 = millis; // reset 15 minute timer
}
if (digitalRead (input4) == LOW){ // assumes motion detector pulls low
previousTime4 = millis; // reset 15 minute timer
}
}
``````

digitalWrite (outputX, LOW);
to turn off the outputs when something is detected?
Or some other mechanism to reset it.

Awesome, I will give it a whirl and see where it goes. Thank you!

Ok, be sure to post all of what you come up with. I didn't write any of the pre-setup or setup code.

Will do.

One question, though - if we get to that 49th day of millis() and previousTimeX is now 4,000,000,000 and then then rolls over to zero, I'll end up with

elapsedTimeX = currentTime - previousTimeX
Which would mean that
elapsedTimeX = 0 - 4,000,000,000, which would be -4,000,000,000

I'm guessing I would have to put in a statement that if elapsedTimeX would have to be reset it back to Zero if it ever became negative, otherwise it would never work again.

Did I miss something?

Maybe you missed unsigned arithmetic.
Who knows?

Please use arrays rather than copying all your code and data four times.

Apart from that, what you're describing is very simple and if you code it correctly timer rollover will work correctly without any special code to handle it. Essentially, blink without delay gives you the timer logic and you just need to add a little code to update the 'previous time' value for a sensor whenever motion is detected.

check it out using the calculater on your computer:
current time (after rollover): 0x00000040 (40 ticks after rollover) (0x indicating hex format)
previous time (before rollover): 0xffffffc0 (40 ticks before rollover)
then: 0x00000040 - 0xffffffc0 = 0xffffffff00000080
now, arduino unsigned long only supports 8 hex digits - so the upper ffffffff drop off and the result left is 0x00000080.
So rollover is not an issue.

AWOL:
Maybe you missed unsigned arithmetic.
Who knows?

I guess if I knew everything, I wouldn't have to ask. Sorry to be a burden.

check it out using the calculater on your computer:
current time (after rollover): 0x00000040 (40 ticks after rollover) (0x indicating hex format)
previous time (before rollover): 0xffffffc0 (40 ticks before rollover)
then: 0x00000040 - 0xffffffc0 = 0xffffffff00000080
now, arduino unsigned long only supports 8 hex digits - so the upper ffffffff drop off and the result left is 0x00000080.
So rollover is not an issue.

Thanks for your help and patience.

CrossRoads, it works absolutely perfect. Thanks again for your help.

I have a way to go before the project is complete. When it is done I will post the code. I also just ordered some serial displays from China, so it will be a couple of weeks...

Cool.