Reset millis

I am using millis() to perform some time-based calculations, and want to be able to reset millis automatically every 24hrs back to 0.
I am using a long integrer to count millis, and was thinging along the lines of;

If millis() >= 86400000
set timer0_overflow_count to 0

Would this sort of approach work, or is there a better approach?

Get a servo. Mount it over the Arduino. Once a day, rotate the servo arm so it presses the reset button.

Or, re-think why you think you need to reset millis(). You don't. Really.

lol - good idea with the servo.

I was going to suggest resetting the board every 40 days or whatever, to ensure the millis() never overflow, but was going to be boring and do it with wires and pins stuff :slight_smile:

Thanks for getting us know about it..

Thanks for getting us know about it..

My spidey spam senses are tingling.

Cylindric:
I was going to suggest resetting the board every 40 days or whatever, to ensure the millis() never overflow, but was going to be boring and do it with wires and pins stuff :slight_smile:

Overflow need not be a problem - check johnwasser's analysis in this thread: http://arduino.cc/forum/index.php/topic,60215.0.html

Sorry yes, forgot to mention that it's really not a big problem - easy to fix in code. Maybe just use the servo-button-reset-bot as a backup :slight_smile:

I would prefer a software solution, so would my original idea work?
I am not worried about the overflow, but resetting millis gives me a clean sheet every day, and resets the counters linked to millis.

but resetting millis gives me a clean sheet every day, and resets the counters linked to millis.

Do you reset your watch every day? Or, does it just keep on ticking?

Since millis() is used for relative timing (did this happen before that, or after? How long has it been since...?), expecting absolute values is not advisable.

pauldreed:
I would prefer a software solution, so would my original idea work?
I am not worried about the overflow, but resetting millis gives me a clean sheet every day, and resets the counters linked to millis.

To the first, I think not. It may appear to, but from what I've read, interferring with certain elements such as timing will affect all sorts of other libraries that use it. So you can expect issues with anything that uses those elements.

For the second, the problem is that you'll start by asking for zero to mean "midnight", but then tomorrow you'll be trying to work out how to deal with an Arduino resetting during the day. Will you then set the clock to 355322 to change it?

If you need real time, get an RTC. If you need durations, calculate them.

"duration = end - start" is easier than fiddling with underlying low-level calls.

If the functionality of millis() is not good enough you could add a wrapper around it with new functionality, lets call it MyMillis or MM.

To implement it you need one unsigned long and two simple functions.

unsigned long MMdelta = 0L;      // aka MMoffset, holds the offset between MyMIllis() and the system millis().

unsigned long MyMillis()             // returns the nr of millis since MMReset(); if MMReset is not called its value equals millis()
{
  return millis()- MMdelta;
}

void MMReset(unsigned long val = 0L)     // resets MyMillis, default to 0, optionally to any positive value.
{
  MMdelta = millis() - val;  
}

////////////////////////////////////////////
void setup()
{
  Serial.begin(115200);
  Serial.println("MyMillis demo");
  
  for(int i=0; i< 10; i++)
  { 
    delay(10);
    Serial.println(MyMillis());
  }
  delay(1000);
  MMReset();
  for(int i=0; i< 10; i++)
  { 
    delay(10);
    Serial.println(MyMillis());
  } 
  MMReset(1000);
  for(int i=0; i< 10; i++)
  { 
    delay(10);
    Serial.println(MyMillis());
  } 
}

void loop(){}

Of course you can make a class of it if you need more mili-counters.

Rob, the code takes some understanding (by a learner!!), but I'm working my way through it.
I'm stuck with;
for(int i=0; i< 10; i++)
What does this do??

See reference page - http://www.arduino.cc/en/Reference/For -

robtillaart:
See reference page - http://www.arduino.cc/en/Reference/For -

But i does not appear to be used anywhere?
int i=0; //On first run sets the value of i as 0
i< 10; //checks to see if i is less than 10
i++ //adds one to the value of i

Does it run through 10 times and then execute the next piece of code? i.e. a delay of 10 cycles?

  for(int i=0; i< 10; i++)
  { 
    delay(10);
    Serial.println(MyMillis());
  }

you almost got it, the above code does execute the block between { and } 10 times

you can use the i in side the block too

example:

  for(int i=0; i< 10; i++)
  { 
    delay(i);
    Serial.println(MyMillis());
  }

here the i causes different (increasing) delay's

for has a few special tricks:

endless loop

for ( ; ; ) 
{
  ...
}

executes the block forever

int i=0;
for (i=0 ; i<10 ;i++ ) 
{
  ...
}
for (  ; i>0 ;i-- ) 
{
  ...
}

two for loops, the int i is declared outside the for loops so it can be reused, the first loop counts to 10 and the second loop counts back to 0.
This is possible as the second for does not (re)initialize the var i.

Thanks Rob, I get it now!

Advice, spend a few hours/evenings at the reference and tutorial section of Arduino.cc just to read code there. It should give you an impression how things work and can be done. Time spend in these sections is well spent!

Succes,
Rob

pauldreed:
I am using millis() to perform some time-based calculations, and want to be able to reset millis automatically every 24hrs back to 0.
I am using a long integrer to count millis, and was thinging along the lines of;
If millis() >= 86400000
set timer0_overflow_count to 0
Would this sort of approach work, or is there a better approach?

If all you need is a personal time that never goes over 86400000, then you can do that with the modulo operator (%) instead of working with the Arduino internals:

unsigned long myMilliseconds = ( millis() % 86400000UL );

myMilliseconds will always run from 0 to 86399999, inclusive. Don't forget that this is from the program starting, not midnite (unless you start the program at exactly midnight). Also, the millisecond count resets after about 50 days so you'll only be able to track it that long.

[quote author=David Pankhurst link=topic=66962.msg492289#msg492289 date=1311125432]unsigned long myMilliseconds = ( millis() % 86400000UL );

myMilliseconds will always run from 0 to 86399999, inclusive. Don't forget that this is from the program starting, not midnite (unless you start the program at exactly midnight). Also, the millisecond count resets after about 50 days so you'll only be able to track it that long.
[/quote]Wait, won't that just do the same as millis()? That'll overflow the same way...

Reference:
Returns the number of milliseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Wait, won't that just do the same as millis()? That'll overflow the same way...

Yep, as its value is derived from millis() it has to follow wherever millis() goes even in an overflow ....