Resetting millis() - again

SteveCS

Well-known member
Hi

I have a project that potentially sits for weeks on end, but at any point could be 'triggered'.

There are various millis() based timers involved in the event while it is occurring, and the event can last a varying length of time.

I have read all over the shop that you should never reset millis(), as it's not required and might break libraries.

My question is.... why not? I cannot check for a possible rollover conflict after approx 49 days, as the event lengths change considerably.

Therefore, surely, it's just simpler to say that if the event isn't occurring, and the millis() timer is over a certain limit, then reset the millis() to zero and avoid the potential rollover mid event issue?

Hmm
 
Best is to use relative offsets on millis() for each timer involved.
A uint32_t will always give the offset even after rollover of the millis() return value

No idea what the usage for each looks like - seems this might cover the use case?
Code:
uint32_t aTime;
bool aActive=false;

if ( time to wait 3300 milliseconds) {
 // 'a' thing START now
 aActive = true;
 aTime = millis();
}

if ( aActive && (millis() - aTime > 3300 ) {
 aActive = false;
 // 'a' thing DONE now
}
 
Hi

I have a project that potentially sits for weeks on end, but at any point could be 'triggered'.

There are various millis() based timers involved in the event while it is occurring, and the event can last a varying length of time.

I have read all over the shop that you should never reset millis(), as it's not required and might break libraries.

My question is.... why not? I cannot check for a possible rollover conflict after approx 49 days, as the event lengths change considerably.

Therefore, surely, it's just simpler to say that if the event isn't occurring, and the millis() timer is over a certain limit, then reset the millis() to zero and avoid the potential rollover mid event issue?

Hmm

Check <this post> for a good reference (thanks & credit to rcarr) on how to avoid any potential problems when millis() rolls over.

Mark J Culross
KD5RXT
 
OK. I will look into this further

I had this in my code, but it doesn't compile anyway, as the 'timer0_millis = 0;' line throws an error

Code:
  currentMillis = millis();

  if ((triggered == false) && (currentMillis > 4294963696)) {                                      // Reset millis() counter 1 hour before rollover assuming event isn't in progress
    noInterrupts ();
    timer0_millis = 0;
    interrupts ();
  }
 
Trying to reset the global system milliseconds value can only cause trouble.

Best is to use relative offsets on millis() for each timer involved.
...

Above code, here using elapsedMillis that seems to be linked in above link?
Same net effect - usage is cleaner - as the millis() ref is in the class code:
Code:
elapsedMillis aTime;
bool aActive=false;

if ( time to wait 3300 milliseconds) {
 // 'a' thing START now
 aActive = true;
 aTime = 0;
}

if ( aActive && (aTime > 3300 ) {
 aActive = false;
 // 'a' thing DONE now
}
 
Not sure my thick head understands that process

Is that basically only allowing the process to start if there is enough time remaining (3300 milliseconds)? This means I need to know the length of my process, which can vary greatly.
 
Not sure my thick head understands that process

Is that basically only allowing the process to start if there is enough time remaining (3300 milliseconds)? This means I need to know the length of my process, which can vary greatly.

Not seeing any code - assuming 'something happens' and sometime after that further response is needed?

That's what that code does: Waits for event "if ( time to wait 3300 milliseconds)" then gives a way to see when 3300 ms has passed from that time.

If the use case is different, it can be evolved once understood as a way to time a known interval from a given start point.

Given example code perhaps that could be demonstrated if it isn't clear.
 
I believe the reason why you should never reset the global timer is because other libraries likely assume that the time goes forward, so breaking this assumption likely causes a world of trouble.

What you should do instead is to keep your own timer and keep updating it with the delta time, something like:
Code:
static unsigned long previousTime=millis();
unsigned long currentTime=millis();
unsigned long deltaTime=currentTime-previousTime;
myTime+=deltaTme;
previousTime=currentTime;
Even if the global millis() rolls over, the deltaTime will be correct. Then it's up to you to handle myTime update correctly (e.g. add condition to increment myTimeHi when it rolls over)
 
Back
Top