Resetting Millis()

Is there a way to reset millis() via code?

I know it will roll over for about 50 days before resetting itself, however I was wondering if there was a way of resetting it as a line of code and maybe call it after a certain amount of days or even every night?

No, and there is not a single reason why you want to :wink: If you do it right, the roll over does not give you any trouble.

It will if I have a millis timed operation running at the exact time it resets to 0 won't it?.

I will be running water pumps that will be timed a to run for example 1 minute via millis. if it resets in the middle of this minute the pump will continue to run because it won't have hit the value expected.

(I am a novice at coding by the way so please take it easy on me)

No it will work just fine if you use unsigned variables and calculate the time intervals using subtraction.

stevelondon2:
It will if I have a millis timed operation running at the exact time it resets to 0 won't it?.

Nope :slight_smile: Not as long as you ALWAYS check like millisNow - millisLast >= interval (and use unsigned varaibles for millisLast and millisNow)

But do note, millis() isn't accurate. So timing 1 minute is fine but timing multiple days it will drift significant. And you can't prevent that with resetting either :wink: So it all depends on the application if that matters.

It will if I have a millis timed operation running at the exact time it resets to 0 won't it?.

Your watch and wall clocks all roll over twice a day. When was the last time THAT caused you a problem?

Delta_G:
No it will work just fine if you use unsigned variables and calculate the time intervals using subtraction.

'unsigned long'
I always use 'uint32_t' to be explicitly clear.

what about article 1 on here (Just found a thread that I almost understand. lol.)

http://forum.arduino.cc/index.php?topic=184596.0

Oh I won't be timing for days. It will literally be a 1 or 2 minute timed event every day. This is why I thought that resetting it to 0 at midnight every day or even every Sunday take away the risk of it blundering.

Unfortunately (for me) I don't really understand your suggestion of coding, as I say I'm very new at this. Don't worry, I'm sure it will be ok as it is. Thanks anyway.

PaulS:
Your watch and wall clocks all roll over twice a day. When was the last time THAT caused you a problem?

You're right, but then I don't have a water pump controlled by my watch that can be caused to stay on and pump 100 gallons of saltwater over a brand new wooden floor.

Could you quickly show me roughly what you mean on this very basic mock up of what I would normally do.

int testmillis, var=0, startnow=0;

void setup()
{
}

void calledatsomepoint()
{
  startnow=1;
  testmillis = millis();
}

void loop()
{
  if (startnow == 1)
  {
    if (millis() - testmillis > 5000)
    {
      var++;
      testmillis = millis();
    }
  }
}

what about article 1 on here

What about it?

If you use subtraction, rollover won't be a problem. Let's take your watch as an example, since it overflows a lot sooner.

If it is 11:00, when you start pumping, and you need to stop 2 hours and 10 minutes later, you wouldn't have any problem, would you? It's 11:15. You've been pumping for 11:15 - 11:00 hours, or 15 minutes. It's 11:30. 11:30 - 11:00 is 0:30, which is less than 2:10, so you keep pumping.

Now, what happens when noon rolls around? 12:00 - 11:00 is 1:00, which is less than 2:10, so you keep pumping. Now, a minute later, it's 12:01. 12:01 - 11:00 is 1:01, which is less than 2:10, so you keep pumping. Going on an hour later, it's 12:59. 12:59 - 11:00 is 1:59, which is less than 2:10, so keeping pumping salt water all over the hardwood floor.

Now, a bunch of seconds later, it's 1:00. Oh no, rollover happened. But, is that a problem? You know how to handle 1:00 - 11:00 to get 2:00. So does the Arduino. 2:00 is less than 2:10, so more water puddled on the floor.

A bit later, it's 1:10. 1:10 - 11:00 is 2:10, which is no longer less than 2:10, so shut the water off and grab a mop.

Unfortunately (for me) I don't really understand your suggestion of coding

Look at the BlinkWithourDelay example. Adjust the timing to suit yourself and do what you want at the end of the period instead of turning an LED on or off.

unsigned long startMillis, now, period = 5000;

void setup()
{
}

void loop()
{
  now = millis();
  if (now - startMillis >= period)  //will not be affected by rollover
  {
    //do whatever
    startMillis = now;
  }
}

PaulS:
You know how to handle 1:00 - 11:00 to get 2:00.

Please don't assume that I am intelligent. It will only end badly. lol. Your post was making great sense until this part. I see the equation to work out 2 from 1-11. Or at least not one that would work both when the answer is positive and negative. I'll have a little play and come back if I work it out. Thanks Paul.

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing. It may help with understanding the technique.

...R

stevelondon2:
Please don't assume that I am intelligent. It will only end badly. lol.

I'm sure it is not true but it is nice to see that attitude. Many other beginners could benefit from it :slight_smile:

...R

Suppose that you need to subtract 97 from 110.

110
-97
---
???

When you handle the one column, 0 - 7 is a problem, right? No, you borrow from the tens column, making the calculation 10 - 7, which you can compute, right?

When you handle the tens column, 0 - 9 is a problem, right? No, you borrow from the hundreds column, making the calculation 10 - 9, which is easy, right?

Well, the Arduino knows all about borrowing. When it gets to the left-most digit, when there is nothing to the left, it still borrows. What does it get? Always a 1.

Well, not really, since the Arduino is dealing strictly with binary data in two complement form, but, the result is the same. Subtraction of unsigned long values always works, as long as millis() hasn't rolled over twice. That takes 49+ days, so as long as you don't need to run the pump for 7+ weeks and you never add times, millis() rollover is NOT a problem.

gfvalvo:
'unsigned long'
I always use 'uint32_t' to be explicitly clear.

But do know that millis IS a unsigned long so if it's compiled on a system where a unsigned long is not uint32_t you're in trouble.

stevelondon2:
Oh I won't be timing for days. It will literally be a 1 or 2 minute timed event every day.

Those two sentences contradict each other. Not only do you need to time the 1 minute, you ALSO need to time the rest of the 1439 minutes a day is long. And any error in that WILL add up. So if the Arduino is off by 3 minute a day (little under 0,3% which is very little for the Arduino clock) you will be off by half an hour after a week. Which might or might not be a problem for your application.

stevelondon2:
You're right, but then I don't have a water pump controlled by my watch that can be caused to stay on and pump 100 gallons of saltwater over a brand new wooden floor.

Might not be but they work fine for you to be present at meetings and not get fired. Which, in my opinion, is more damage then ruining the new floor...

stevelondon2:

int testmillis, var=0, startnow=0;

septillion:
Nope :slight_smile: Not as long as you ALWAYS check like millisNow - millisLast >= interval (and use unsigned varaibles for millisLast and millisNow)

And a little tip, names areMuchEasierToReadLikeThis insteadlikethis.

UKHeliBob:
Look at the BlinkWithourDelay example. Adjust the timing to suit yourself and do what you want at the end of the period instead of turning an LED on or off.

unsigned long startMillis, now, period = 5000;

void setup()
{
}

void loop()
{
 now = millis();
 if (now - startMillis >= period)  //will not be affected by rollover
 {
   //do whatever
   startMillis = now;
 }
}

I assume this part should also be in that?

void calledatsomepoint()
{
  startMillis =now;
}

Wouldn't it be effected if the rollover happened in between the 'period'?

Eg. startMillis is 10'000 (gotten from calledatsomepoint whilst millis() was 10'000), then 'now' is also 10'000 so the if statement won't run as < period.

1 sec later
now-startMillis=1000

2 sec later
now-startMillis=2000

3 sec later
now-startMillis=3000

What if millis() rolls over now?
'now' (which will now be 0) - startMillis= -10'000.

stevelondon2:
What if millis() rolls over now?
'now' (which will now be 0) - startMillis= -10'000.

Not if you use a unsigned long. An unsigned type can NOT be negative and will also roll over (but the other way) just like millis() does.

So for an unsigned long
2 - 3 = 4.294.967.295 :wink: NOT -1 :smiley:

septillion:
Those two sentences contradict each other.

I have an RTC clock on the system which will trigger each pumpkin section, I just wanted to use the millis in case the RTC fails. It doesn't matter if it fails and the pump doesn't come on, its if it fails when it is on and won't turn off.

septillion:
Not if you use a unsigned long. An unsigned type can NOT be negative and will also roll over (but the other way) just like millis() does.

So for an unsigned long
2 - 3 = 4.294.967.295 :wink: NOT -1 :smiley:

Riiiiiight. Gotcha. Thats where the unsigned comes in. So in my example above, what will 0 - 1000 produce in an unsigned long?