Go Down

Topic: reset millis() ? (Read 809 times) previous topic - next topic

erich

hello,

i thought to use millis() for a time out check (t1-t0).
to avoid running in trouble around millis() oveflow i
want to know if there is a way to reset millis() or
what would be other ways to check timeouts ?

thx for help

erich

jims

Here is an example of delaying safely in the face of overflows...
Code: [Select]
void delayMillis(unsigned long tc)
{
       unsigned long start = millis();
       unsigned long finish;
       unsigned long now;

       if ( tc == 0) return;
       finish = start + tc;

       if ( finish < start) {    // we need to roll over
           for(;;) {
               now = millis();
               if ( now < start && now >= finish) return;
           }
       } else {                // we can't roll over
           for(;;) {
               now = millis();
               if ( now >= finish || now < start) return;
           }
       }
}


And you could reset the millis counter by making an extern variable declaration for it in your sketch and setting it to zero, but you might expect "bad things" to happen in any other bit of code that was using millis() for timing.

erich

hello,

thx for the quick reply.
but as i understand it your example is for a delay.

whereas i want to be sure during the following example that a possibel overflow is doing no harm,
where a simple reset of millis() before would easily solve the issue:

void blah() {
 
 time0 = millis();
 
 while (Serial.read() != 3) {
   time1 = millis();
     
      if ((time1-time0) > 3000) {
         return;
      }
  }

  //do some things as there was no timeout

}

jims

Ah, then what needs doing is to rewrite the function as a test to see if a certain amount of time has passed...
Code: [Select]
int after(unsigned long start, unsigned long interval)
{
       unsigned long finish;
       unsigned long now = millis();

       if ( interval == 0) return;
       finish = start + interval;

       if ( finish < start) {    // we need to roll over
           if ( now < start && now >= finish) return 1;
       } else {                // we can't roll over
           if ( now >= finish || now < start) return 1;
       }
       return 0;
}


Then you can use it in your code like this...
Code: [Select]
void blah() {
 
 time0 = millis();
 
 while (Serial.read() != 3) {  
   if ( after( time0, 3000) return;


You could of course do this...
Code: [Select]
extern volatile unsigned long timer0_overflow_count;
...
timer0_overflow_count = 0;
...

... but you never know what code you would break in various libraries and internal functions that are using that counter and don't expect it to be reset, not to mention that as an undocumented API it could change at any moment.

erich

thx a lot for your help, i give it a try

best

erich

Go Up