Go Down

Topic: reset millis() ? (Read 1 time)previous topic - next topic

erich

May 15, 2007, 01:35 pm
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

#1
May 15, 2007, 04:22 pm
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

#2
May 15, 2007, 04:34 pm
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

#3
May 15, 2007, 06:08 pm
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

#4
May 15, 2007, 06:15 pm
thx a lot for your help, i give it a try

best

erich

Go Up