Need help with time display format. "solved"

I have a sketch that counts up from time 00:00:00. I need the millisecond portion to be printed out in three places.
Right now if millis is <1 is prints one millis digit and if millis is < 10 it prints two digits.
I would like it to print three digits every time.

Can anyone help me please?

Here is the sketch:

/*
  Example 37.2 – Super-basic stopwatch using millis();
  http://tronixstuff.wordpress.com/tutorials > chapter 37
  John Boxall | CC by-sa-nc
*/

unsigned long start, finished, elapsed;

void setup()
{
  Serial.begin(9600);
  
 start=millis();
 }

void displayResult()
{
  float h,m,s,ms;
  unsigned long over;
  elapsed=finished-start;
  h=int(elapsed/3600000);
  over=elapsed%3600000;
  m=int(over/60000);
  over=over%60000;
  s=int(over/1000);
  ms=over%1000;
  
  if ((h,0) < 10){
  Serial.print("0");
  }
  Serial.print(h,0);
  Serial.print(":");
  
   if ((m,0) < 10){
  Serial.print("0");
  }
  Serial.print(m,0);
  Serial.print(":");
  
   if ((s,0) < 10){
  Serial.print("0");
  }
  Serial.print(s,0);
  Serial.print(":");
 
  Serial.print(ms,0);
  
  Serial.println();
}

void loop()
{
  
    finished=millis();
    displayResult();
  
  delay(1000);
}

Here is the output:

00:01:07:940

00:01:09:152

00:01:010:365

00:01:011:578

00:01:012:792

00:01:014:5

00:01:015:217

00:01:016:431

00:01:017:644

00:01:018:858

00:01:020:71

00:01:021:285

00:01:022:498

00:01:023:712
]

Look up sprintf. That lets you add leading zeros and control the field width.

if ((m,0) < 10){

Wassat?

  float h,m,s,ms;
...
  h=int(elapsed/3600000);

Why not make h an int?

try this:

if(ms<100)
{
 Serial.print("0");
 if(ms<10)
 {
  Serial.print("0");
 }
}
Serial.print(ms);

or use sprintf as Nick suggested(remember to add stdio.h):

char buffer[5];
sprintf(buffer, "%03d", ms);
Serial.print(buffer);

Also as AWOL said, (m,0)<10 doesnt make any sense to me either…

AWOL:

if ((m,0) < 10){

Wassat?

I was trying to add a leading 0 if m was less that 10. Else the format would print like 00:7:00 instead of 00:07:00.[quote author=Nick Gammon link=topic=113092.msg850568#msg850568 date=1341557242]

  float h,m,s,ms;
...
  h=int(elapsed/3600000);

Why not make h an int?
[/quote]

I have tried changing the millis part to int but, not the h. I will try that also.

Antzy:
try this:

if(ms<100)

{
Serial.print(“0”);
if(ms<10)
{
  Serial.print(“0”);
}
}
Serial.print(ms);




I tried that with no success, assuming that I coded it correctly.

or use sprintf as Nick suggested(remember to add stdio.h):


char buffer[5];
sprintf(buffer, “%03d”, ms);
Serial.print(buffer);




Also as AWOL said, (m,0)<10 doesnt make any sense to me either...

Thank you for the sprintf code, I struggle with using it even though I have read about it several times. I like that idea the best especially if it works.

I tried that with no success, assuming that I coded it correctly.

Try using it in a seperate new program like this:

int ms=9;
if(ms<100)
{
 Serial.print("0");
 if(ms<10)
 {
  Serial.print("0");
 }
}
Serial.print(ms);

Then try replacing ms=9 with 99 and then 999. It should be working properly…
But if sprintf works well, then leave this and go for sprintf :slight_smile:

Thanks to all that have replied, here is my code after using sprintf. I also I had to change the floats to int as others suggested. I like the way it is working and it is perfect for my situation! I have ran the sketch for over 10 hours so, the output is actual time ran. 8)

/*
  Example 37.2 – Super-basic stopwatch using millis();
 http://tronixstuff.wordpress.com/tutorials > chapter 37
 John Boxall | CC by-sa-nc
 Modified by Mark M. with help of Arduino forum. 7/07/12
 */
#include <stdio.h>;

unsigned long start, finished, elapsed;

void setup()
{
  Serial.begin(9600);

  start=millis();
}

void displayResult()
{
  int h,s,m,ms;
  unsigned long over;
  elapsed = finished-start;
  h = int(elapsed/3600000);
  over = elapsed%3600000;
  m = int(over/60000);
  over = over%60000;
  s = int(over/1000);
  ms = over%1000;

  char hbuffer[5];
  sprintf(hbuffer, "%02d", h);
  Serial.print(hbuffer);

  Serial.print(":");

  char mbuffer[5];
  sprintf(mbuffer, "%02d", m);
  Serial.print(mbuffer);
  //Serial.print(m,0);
  Serial.print(":");

  char sbuffer[5];
  sprintf(sbuffer, "%02d", s);
  Serial.print(sbuffer);
  //Serial.print(s,0);
  Serial.print(":");

  // Serial.print(ms,0);

  char buffer[5];
  sprintf(buffer, "%03d", ms);
  Serial.print(buffer);

  Serial.println();
}

void loop()
{

  finished=millis();
  displayResult();

  delay(700);
}

output:

10:45:39:630
10:45:40:342
10:45:41:055
10:45:41:768
10:45:42:480
10:45:43:193
10:45:43:906
10:45:44:619
10:45:45:331
10:45:46:044
10:45:46:757
10:45:47:469
10:45:48:182
10:45:48:895
10:45:49:607
10:45:50:320
10:45:51:032
10:45:51:745
10:45:52:457
10:45:53:170
10:45:53:883
10:45:54:595
10:45:55:308
10:45:56:021
10:45:56:733
10:45:57:446
  char hbuffer[5];
  sprintf(hbuffer, "%02d", h);
  Serial.print(hbuffer);

  Serial.print(":");

  char mbuffer[5];
  sprintf(mbuffer, "%02d", m);
  Serial.print(mbuffer);
  //Serial.print(m,0);
  Serial.print(":");

  char sbuffer[5];
  sprintf(sbuffer, "%02d", s);
  Serial.print(sbuffer);

You can, of course, use, and reuse, a single buffer.

Thank you PaulS I did not know I could use the same buffer for all 3 sprintf lines! I appreciate you taking your time to look over my sketch and help me get the most bang for my byte! I have changed the sketch based on your suggestion and it is now smaller while, still working correctly.

I should have cleaned out the //commented out lines earlier but, I have now. I added helpful comments to a lot of lines to make the program easier to understand. I put the function at the bottom of the sketch so that setup() and loop() are now back to back.

Here is the code cleaned up and commented:

/*
  Example 37.2 – Super-basic stopwatch using millis();
 http://tronixstuff.wordpress.com/tutorials > chapter 37
 John Boxall | CC by-sa-nc
 Modified by Mark M. with help of Arduino forum. 7/07/12
 */
#include <stdio.h>;

unsigned long start, finished, elapsed;

void setup()
{
  Serial.begin(9600);      //start serial

  start = millis();        //start time for elasped time counter
}


void loop()
{
  finished = millis();   //start is in set-up, updating finished updates the time elapsed
  displayResult();       //do the math and print the results

  delay(700);           //delay to slow the output down for debugging
}


//////////////Elapsed time function "displayResult"//////////
void displayResult()
{
  int h,s,m,ms;              //hour, second, minute, milliseconds
  unsigned long over;
  elapsed = finished-start;
  h = int(elapsed/3600000);  //calculate the hour
  over = elapsed%3600000;
  m = int(over/60000);       //calculate the minute
  over = over%60000;
  s = int(over/1000);       //calculate the second
  ms = over%1000;           //calculate the millisecond

  char buffer[5];
  sprintf(buffer, "%02d", h);  //buffer hours to 2 places
  Serial.print(buffer);        //print the hour
  Serial.print(":");

  sprintf(buffer, "%02d", m); //buffer minutes to 2 places
  Serial.print(buffer);       //print the minute
  Serial.print(":");

  sprintf(buffer, "%02d", s); //buffer seconds to 2 places
  Serial.print(buffer);       //print the seconds
  Serial.print(":");

  sprintf(buffer, "%03d", ms); //buffer milliseconds to 3 places
  Serial.print(buffer);        //print the milliseconds

  Serial.println();            //start newline
}

Antsy, nick and Paul You have just given me a quick solution to an issue I have with my clock… Now does anyone know of a GPS library that can be told which time zone to use in presenting time/date information?. and Yes, I would like an egg in my beer…

Doc

Docedison: and Yes, I would like an egg in my beer...

How about the moon on a stick too while you're at it ;)

I must get round to buying myself a GPS module to tinker with - I could knock up a library for it then.

Can you get the ZDA sentence?

ZDA - Data and Time

$GPZDA,hhmmss.ss,dd,mm,yyyy,xx,yy*CC $GPZDA,201530.00,04,07,2002,00,00*60

where: hhmmss HrMinSec(UTC) dd,mm,yyy Day,Month,Year xx local zone hours -13..13 yy local zone minutes 0..59 *CC checksum

  char buffer[14];
  sprintf(buffer, "%02d:%02d:%02d:%03d:", h, m, s, ms);  //buffer time string
  Serial.println(buffer);        //print the time

How about just one sprintf call too?

Arrch:

  char buffer[14];

sprintf(buffer, “%02d:%02d:%02d:%03d:”, h, m, s, ms);  //buffer time string
 Serial.println(buffer);        //print the time




How about just one sprintf call too?

I guess it takes a bit more memory to do it but, it is nice to have less code to look at. I did have to remove the last : that you put in the code but, otherwise it works great.
Thanks Arrch!

/*
  Example 37.2 – Super-basic stopwatch using millis();
 http://tronixstuff.wordpress.com/tutorials > chapter 37
 John Boxall | CC by-sa-nc
 Modified by Mark M. with help of Arduino forum. 7/07/12
 */
#include <stdio.h>;

unsigned long start, finished, elapsed;

void setup()
{
  Serial.begin(9600);      //start serial

  start = millis();        //start time for elasped time counter
}


void loop()
{
  finished = millis();   //start is in set-up updating finished updates the time elapsed
  displayResult();       //do the math and print the results

  delay(700);           //delay to slow the output down for debugging
}


//////////////Elapsed time function "displayResult"//////////
void displayResult()
{
  int h,s,m,ms;              //hour, second, minute, milliseconds
  unsigned long over;
  elapsed = finished-start;
  h = int(elapsed/3600000);  //calculate the hour
  over = elapsed%3600000;
  m = int(over/60000);       //calculate the minute
  over = over%60000;
  s = int(over/1000);       //calculate the second
  ms = over%1000;           //calculate the millisecond

  char buffer[14];
  sprintf(buffer, "%02d:%02d:%02d:%03d", h, m, s, ms);  //buffer time string
  Serial.println(buffer);        //print the time
  
}