Pages: [1]   Go Down
Author Topic: adding up millis  (Read 648 times)
0 Members and 1 Guest are viewing this topic.
California
Offline Offline
Sr. Member
****
Karma: 2
Posts: 433
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am working on a speedometer and trying to keep track of "ride time". Below is my code for when the speedometer has stopped. Previously when it started, "time2" was set to the value of millis().

I am trying to make sure that the time is still added correctly if millis() rolls over. I know that "time" itself will not keep track of more than 49 days of milliseconds and that this code will not work if the speedometer doesn't stop for 49 days. "time" will likely be reset to 0 fairly frequently anyway. But the arduino will only ever sleep, not restart. So I do need to worry about millis() rolling over.

"time" is the millis() that I have tallied up. "time2" is the value of millis() when I started counting last. Both are unsigned longs.
Code:
 void (stoppedMoving){
    if(millis() >= time2){//if time has NOT rolled over
      time += (millis()-time2);//add the difference between time2 and millis().
    }
    else{////if time has rolled over
      time += (4294967295 - time2) + millis();//if millis() has rolled over, add the number of milliseconds before it rolled over plus the milliseconds since it rolled over.
      }//end if time has rolled over
      moving=false;
  }//end stoppedMoving

Will this work?

Thanks
« Last Edit: March 01, 2013, 02:33:08 pm by stoopkid » Logged

0
Offline Offline
Shannon Member
****
Karma: 161
Posts: 10445
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can't get any more bits in the variable time than are in the result of millis()...

You need to count rollovers perhaps:
Code:
unsigned long time_lo ;  // synthesize a 64 bit unsigned integer from two unsigned longs
unsigned long time_hi ;

...
  unsigned long new_time_lo = time_lo + (millis () - time2) ;
  if (new_time_lo < time_lo)
    time_hi ++ ; // detect carry-over
  time_lo = new_time_lo ;

(Or does long long work and give a 64 bit int??)
Logged

[ I won't respond to messages, use the forum please ]

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23768
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If your math is all done in the form of

elapsedTime = (timeNow - timeEarlier);  // add elaspedTime to add  rideTime summary
where timeNow is the stopped time, and timeEarlier is the time you started

and all time related variable are unsigned long,
then there will not be a rollover problem.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

California
Offline Offline
Sr. Member
****
Karma: 2
Posts: 433
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If your math is all done in the form of

elapsedTime = (timeNow - timeEarlier);  // add elaspedTime to add  rideTime summary
where timeNow is the stopped time, and timeEarlier is the time you started

and all time related variable are unsigned long,
then there will not be a rollover problem.

Ah yes, I get it, that makes perfect sense... I was just over complicating it. Thanks!
Logged

Dallas, TX USA
Offline Offline
Edison Member
*
Karma: 47
Posts: 2341
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your math is all done in the form of

elapsedTime = (timeNow - timeEarlier);  // add elaspedTime to add  rideTime summary
where timeNow is the stopped time, and timeEarlier is the time you started

and all time related variable are unsigned long,
then there will not be a rollover problem.

If timeNow and timeEarlier are values form millis(),
then that will only work if the millis() timer is guaranteed to never rollover
between TimerEarlier and timeNow.

To ensure no rollover during the elapsed time requires zeroing out the millis() timer value.
(which is easy)
And if the millis() timer value has to be zeroed to make it work, why not then just
zero at "timeEarlier" when the elapsed time starts, and then the elapsed time
is merely mills() when you get to timeNow.
This avoids the calculation altogether.
It then simply becomes a matter of when to zero out millis().


--- bill
Logged

California
Offline Offline
Sr. Member
****
Karma: 2
Posts: 433
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think the point is, though, that as long as they are all unsigned longs, if millis() were to rollover. Then when you subtract timeEarlier from timeNow, it will rollover backwards and still give you the difference. The only thing that would mess this up is if you tried to subtract more than 49 days, then your actual calculation would "rollover". But like I said, I'm not worried about that. I'm only worried about millis() rolling over.
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If your math is all done in the form of

elapsedTime = (timeNow - timeEarlier);  // add elaspedTime to add  rideTime summary
where timeNow is the stopped time, and timeEarlier is the time you started

and all time related variable are unsigned long,
then there will not be a rollover problem.

If timeNow and timeEarlier are values form millis(),
then that will only work if the millis() timer is guaranteed to never rollover
between TimerEarlier and timeNow.

To ensure no rollover during the elapsed time requires zeroing out the millis() timer value.
(which is easy)
And if the millis() timer value has to be zeroed to make it work, why not then just
zero at "timeEarlier" when the elapsed time starts, and then the elapsed time
is merely mills() when you get to timeNow.
This avoids the calculation altogether.
It then simply becomes a matter of when to zero out millis().


--- bill

Incorrect, subtracting two unsigned numbers will result in the difference between the two numbers, including wrap-around. Try it for yourself.

The only caveat is that you can only detect an elapsed time that is less than the maximum amount that can be stored in the n-bits you are working with.
« Last Edit: March 01, 2013, 03:49:35 pm by Arrch » Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 439
Posts: 23768
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Arrch, which part are you saying is incorrect?
To  my mind,
time now   -  time earlier  = elapsed time
0x00000020 - 0xFFFFFF20 = 0x00000100

You may get the wrong result if the calculation is made after the time has rolled over for 24+ days or something on the extremes:
But normally it will be correct.
I would expect "ride time" in this case might be on a per trip basis, or added & stored in EEPROM, but millis() would be reset when the engine was shutdown and later restarted.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Arrch, which part are you saying is incorrect?

This part:
Quote
If timeNow and timeEarlier are values form millis(),
then that will only work if the millis() timer is guaranteed to never rollover
Logged

California
Offline Offline
Sr. Member
****
Karma: 2
Posts: 433
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
byte timeEarlier = 250;
byte timeNow = 5;
byte timeDifference;
void setup(){
 Serial.begin(9600);
 timeDifference = timeNow - timeEarlier;
 Serial.println(timeDifference);
}

void loop(){
 
 
}

returns 11

That's the difference, despite the fact that the byte rolled over.
Logged

Dallas, TX USA
Offline Offline
Edison Member
*
Karma: 47
Posts: 2341
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... subtracting two unsigned numbers will result in the difference between the two numbers, including wrap-around. Try it for yourself.
Yes, this is true. I stand embarrassedly corrected... smiley-red

--- bill
Logged

Pages: [1]   Go Up
Jump to: