Pages: 1 2 [3]   Go Down
Author Topic: Updated stopwatch class on the playground.  (Read 7375 times)
0 Members and 1 Guest are viewing this topic.
Kansas City
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I ran into a problem calculating tenths/hundredths....  There may be a better workaround, but here is what I came up with.
The problem stems from the fact that millis() is an unsigned long - making their range from 0 to 4,294,967,295 (2^32 - 1).   Many of the other variables I was using were declared as integers - This yields a range of -32,768 to 32,767.  When I went to calculate tenths/hundredths, my result went amiss after 32 seconds.  So, here is what I ended up with so far.

Code:
int fractional;                     // variable used to store fractional part of time
int fractionalSecs;                 // variable used to store fractional part of Seconds
int fractionalMins;                 // variable used to store fractional part of Minutes
int fractionalHours;                 // variable used to store fractional part of Hours
unsigned long elapsedFrames;                  // elapsed frames for stop watch
unsigned long elapsedSeconds;                 // elapsed seconds for stop watch
unsigned long elapsedMinutes;                 // elapsed Minutes for stop watch
unsigned long elapsedHours;
float elapsedHun;                               //used in tenths/hundredths calculation
float elapsedHun2;                            //used in tenths/hundredths calculation
int elapsedHun3;                               //used in tenths/hundredths calculation


void printtime (
      unsigned long elapsedPTime,  // Time to dispaly
      int printnumberofdigits)   // number of digits to display - 8=HH:MM:SS.TT, 6=HH:MM:SS, 4=MM:SS
    {
     elapsedHours = (elapsedPTime / 3600000L);
     elapsedMinutes = (elapsedPTime / 60000L);
             elapsedSeconds = (elapsedPTime / 1000L);              // divide by 1000 to convert to seconds - then cast to an int to print
             elapsedFrames = (elapsedPTime / 10L);            // divide by 100 to convert to 1/100 of a second - then cast to an int to print
             fractional = (int)(elapsedFrames % frameRate);       // use modulo operator to get fractional part of 1 Second
             fractionalSecs = (int)(elapsedSeconds % 60L);        // use modulo operator to get fractional part of 60 Seconds
             fractionalMins = (int)(elapsedMinutes % 60L);        // use modulo operator to get fractional part of 60 Minutes
             fractionalHours = (int)(elapsedHours % 60L);        // use modulo operator to get fractional part of 60 Minutes     
     elapsedHun = (elapsedPTime - (elapsedSeconds*1000) ) ;   //remove everything but last 3 digits (fractions of a second)
     elapsedHun2 = elapsedHun/10;                                    //you will have millis with a decimal    (we only use last two digits)
     elapsedHun3 = int(elapsedHun2 + 0.5);                         // round this number up or down
//clearLCD();                                         // clear the LDC

if (printnumberofdigits > 4){    //print hours if needed
    if (fractionalHours > 1){
Serial.print(elapsedHours);
Serial.print(":");
 }
}


//always display minutes if > 59 seconds
if (elapsedSeconds > 59){
if (fractionalHours > 1){
  if (fractionalMins < 10){                            // pad in leading zeros
         Serial.print("0");                                 // add a zero
      }
}

    Serial.print(fractionalMins);       // convert the int to a string and print a fractional part of 60 Minutes to the LCD
      Serial.print(":");                                 //print a colon.
}

//always display seconds
 if (fractionalSecs < 10){                            // pad in leading zeros
      Serial.print("0");                                 // add a zero
      }
     Serial.print(fractionalSecs);

 if (printnumberofdigits > 6){   //Print Tenths + hundredths
           // convert the int to a string and print a fractional part of 60 Seconds to the LCD
      Serial.print(".");                                    //print a colon.

    if (fractional < 10){                                // pad in leading zeros
      Serial.print("0");                                 // add a zero
      }     
Serial.print(elapsedHun3);          // convert the int to a string and print a fractional part of 60 Seconds to the LCD
   // Serial.write(158);         //debug
// Serial.print(elapsedHun2);         //debug
 }

 //assemble seven segment numbers
 //  elapsedHours +  fractionalMins + fractionalSecs + elapsedHun3

 if (out7 = true){
// take elapsedHun3 and send to tens/hundredths seven segment
if (printnumberofdigits > 6){
      sevensegout(elapsedHun3,fractionalSecs, fractionalMins);       //dump tenths + hundredths to the third shift register
}
else {
         sevensegout(-1,fractionalSecs, fractionalMins);            //just print minutes + seconds
}
if (elapsedSeconds > 0){
// sevensegout(fractionalSecs,dataPins);    //dump seconds to the second shift register
}
if (elapsedSeconds > 59){
// sevensegout(fractionalMins,dataPinm);    //dump minutes to the first shift register
}
 }

 else {
         sevensegout(-1,fractionalSecs, fractionalMins);
}
 out7 = false;   //reset outputpin
  //selectLineTwo();
// Serial.print(round(elapsedHun2));
//  selectLineThree();
// Serial.print((elapsedHun2));
    //Serial.write(188);
    //Serial.print(elapsedPTime);
  } //end printtime



Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12482
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

refactored, give it a try
Code:
void printTime(uint32_t t, int digits)
{
  uint32_t x;
  if (digits == 8 || digits == 6) 
  {
  // HOURS
  x = t/ 3600000UL;
  t-= x * 3600000UL;
  print2digits(x);
  Serial.print(':');
  }

  // MINUTES
  x = t/ 60000UL;
  t -= x * 60000UL;
  print2digits(x);
  Serial.print(':');

  // SECONDS
  x = t/1000UL;
  t -= x * 1000UL;
  print2digits(x);

  if (digits == 8)
  {
  // HUNDREDS
  Serial.print('.');
  x = (t+5) /10L;  // rounded hundreds
  print2digits(x);
  }
}

// helper
void print2digits(uint32_t x)
{
  if (x < 10) Serial.print('0');
  Serial.print(x);
}
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great thread the library was really easy to use and I have it running now on my Arduino uni with an OLED display. I am making a quarter mile timer and want to display it as 11.59 say if it took 11.59 seconds, at the moment it is showing in milliseconds, how can i change this? thanks
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12482
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

by posting your code
Then we can see how it works now, and how to change it
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: 1 2 [3]   Go Up
Jump to: