Need help Converts seconds (float) to text string...

As a newbie, I am slowly learning what type of variables to use. One big focus is trying to keep the size of the code to minimum for the most efficiency. So I'm often wary of using some of the libraries. Anyway I have some code that I have not been able to figure out the easiest (& most efficient) way to convert/concatenate variables into a string.
Question: Any suggestions on how to do that, I'd like my function to return time in "###-H ##-M ##.#-S" format.
Question #2: Any comments/suggestions on the type of variables I am using. (Getting feel for when to use long vs int vs float etc.)

Here is the simple code I am working with...

/******************************************************************
*  Purpose:  Keep a log of how long this sketch runs, by
*    storing/updating/retrieving time (in seconds) in EEPROM
*    Want to Retrieve that, and on power down quickly update
*    the EEPROM with Total time.  Also want to be able to
*    easily display this time in specific format ####-H ##-M ##.#-S
*
*      3/16/2014    TimeConversion_Sketch_3.ino
********************************************************************/
float StartTime;    //Seed with known value of 4 hr, 16 m, 32.62s

void setup() {
Serial.begin(9600);
  Serial.print("Starting program...\n");
  pinMode(13,OUTPUT);
  StartTime = 15392.620;  // StartTime is normally retrieved from the EEPROM at the start of sketch.  

}

void loop() {
static int toggle=true;
float Time = (StartTime + (millis()/1000.0));      //convert from milli-sec to seconds

  Serial.print(ShowTime(Time));
  Serial.println("\nPause 10 seconds...");
  delay(10000);
  
  toggle = !toggle;      //Flas LED to show sketch is running
  if (toggle) {
      digitalWrite(13,HIGH);
  } else {
      digitalWrite(13,LOW);
  }
  
    
}  

/*    Convert Seconds into Hours, Minutes, and Seconds 
  Pass variable CurrentTime to funcion 
*/
String ShowTime(float CurrentTime) {
  float calc1,calc2;      // hold intermediate calculation values
  int Hours, Minutes;
  float Seconds;  

  calc1= float(CurrentTime/3600.0);        // Calculate Hours from seconds
  Hours = int(calc1);
  
  calc1 = (calc1 - long(calc1))*3600.0;    //get fractional part, convert back to seconds
  , 
  calc2  = calc1/60.0;                                 // Calculate Minutes from seconds
  Minutes = int(calc2);

  // get fractional part of Minutes in  calc2, convert to Seconds...
  Seconds = (calc2 - long(calc2))*60.0;
  
  Serial.print("DEBUG:  Clock: ");
  Serial.print(CurrentTime);  
  Serial.print("\t\tHour = ");
  Serial.print(Hours);
  Serial.print("\tMinutes = ");
  Serial.print(Minutes);
  Serial.print("\tSeconds = ");
  Serial.println(Seconds);

// eventually store this value back into EEPROM

return("XX-H XX-M XX-S");

/*
I'd like to return a string of the format '###-H ##-M ##=S  Not sure how to do that
the most efficient way, (i.e. keeping sketch compiles size to a minimum 
*/
  
}

Here is what I see on my Serial Monitor

Starting program...
DEBUG: Clock: 15392.62 Hour = 4 Minutes = 16 Seconds = 32.62
XX-H XX-M XX-S
Pause 10 seconds...
DEBUG: Clock: 15402.68 Hour = 4 Minutes = 16 Seconds = 42.68
XX-H XX-M XX-S
Pause 10 seconds...
DEBUG: Clock: 15412.71 Hour = 4 Minutes = 16 Seconds = 52.71
XX-H XX-M XX-S
Pause 10 seconds...
DEBUG: Clock: 15422.75 Hour = 4 Minutes = 17 Seconds = 2.75
XX-H XX-M XX-S
Pause 10 seconds...

If you want to be efficient, don't use floats if there's no need. Why don't you just use the milliseconds? Any calculation on floats need a multiple of time compared to the same operation on integers. If you have an integer holding the milliseconds, just insert a point in front of the last 3 digits of the output value and you have seconds.

Thank you for the feedback. I have modified the code accordingly (see below).

Now I still need help converting the information into a string of the format "###-D ####-H ##-M ##-S". Anyone have suggestions on how to convert from long to character, and concatenate these strings together?

Code without using "float"...

long StartTime=15392620;    //Seed with known value of 4 hr, 16 m, 32.62s

void setup() {
Serial.begin(9600);
  Serial.print("Starting program...\n");
  pinMode(13,OUTPUT);
  StartTime = StartTime + 3*86500000;      //add 3 days in m-secs to calculation
  
}

void loop() {
static int toggle=true;
static long Time = StartTime;      //convert fro milli-sec to seconds

// StartTime is normally retrieved from the EEPROM at the start of sketch.  
  Serial.print(ShowTime(Time));
  Serial.println("\tPause 10 seconds...");
  delay(10000);
  
  toggle = !toggle;      //Flas LED to show sketch is running
  if (toggle) {
      digitalWrite(13,HIGH);
  } else {
      digitalWrite(13,LOW);
  }
Time = (StartTime + millis());      //convert fro milli-sec to seconds
 
    
}  

/*    Convert Seconds into Hours, Minutes, and Seconds 
  Pass variable CurrentTime to funcion 
*/
String ShowTime(float CurrentTime) {
  const long mSpD = 86400000;      //# milliseconds/day
  long calc1;      // hold intermediate calculation values
  int Days, Hours, Minutes,Seconds;

  Serial.print("Conversion of ");
  Serial.print(CurrentTime);
  Serial.println(" mSec to Days, Hours, Minutes, & Seconds.");
  
  Days = CurrentTime/mSpD;

  calc1 = (CurrentTime - Days*mSpD);    //get fractional part
  Hours= calc1/3600000;        // m-seconds in an hour
 
  calc1 = (calc1 - Hours*3600000);    //get fractional part
  Minutes = calc1/60000;    // # m-seconds/minute
 
  calc1 = (calc1 - Minutes*60000);    //get fractional part
  Seconds = calc1/1000;    // # m-seconds/second

  Serial.print("DEBUG:  Clock: ");
  Serial.print(CurrentTime);  
  Serial.print("\t\tDays = ");
  Serial.print(Days);
  Serial.print("\tHour = ");
  Serial.print(Hours);
  Serial.print("\tMinutes = ");
  Serial.print(Minutes);
  Serial.print("\tSeconds = ");
  Serial.println(Seconds);

// eventually store this value back into EEPROM

return("XX-H XX-M XX-S");

/*
I'd like to return a string of the format '###-H ##-M ##=S  Not sure how to do that
the most efficient way, (i.e. keeping sketch compiles size to a minimum 
*/
  
}

Monitor results...
Starting program...
Conversion of 274892608.00 mSec to Days, Hours, Minutes, & Seconds.
DEBUG: Clock: 274892608.00 Days = 3 Hour = 4 Minutes = 21 Seconds = 32
XX-H XX-M XX-S Pause 10 seconds...
Conversion of 274902752.00 mSec to Days, Hours, Minutes, & Seconds.
DEBUG: Clock: 274902752.00 Days = 3 Hour = 4 Minutes = 21 Seconds = 42
XX-H XX-M XX-S Pause 10 seconds...
Conversion of 274912864.00 mSec to Days, Hours, Minutes, & Seconds.
DEBUG: Clock: 274912864.00 Days = 3 Hour = 4 Minutes = 21 Seconds = 52
XX-H XX-M XX-S Pause 10 seconds...

Schau Dir mal snprintf an: http://www.cplusplus.com/reference/cstdio/snprintf/

Thank you Pylon for the feedback, I thought of using sprintf() but wasn't sure if Arduino would support it.

Based on your suggestion, ad the link I tried using snsprintf() but get an error "'snsprintf' was not declared in this scope... and idea on what is wrong here?

#include <stdio.h>
long StartTime=15392620;    //Seed with known value of 4 hr, 16 m, 32.62s
char buffer[1000];


void setup() {
}

void loop() {j

}
String ShowTime(long CurrentTime) {
  long calc1;      // hold intermediate calculation values
  int Days, Hours, Minutes,Seconds;
/// stuff here
// eventually store this value back into EEPROM

return(snsprintf(buffer,"%d-D %d-H %d-M %d-S",Days, Hours,Minutes,Seconds));
}

TimeConversion_Sketch_4.ino: In function 'String ShowTime(long int)':
TimeConversion_Sketch_4:70: error: 'snsprintf' was not declared in this scope

When I try to compile the sketch.

ltetzner:
Thank you Pylon for the feedback, I thought of using sprintf() but wasn't sure if Arduino would support it.

It supports printf() and related functions, but the AVR implementation we use has an option to disable support for floating point formats and the Arduino IDE uses that option (presumably to save program space). As a result the floating point formats such as %f don't work.

Sorry, still not sure how to do this. I've tried variations of printf, sprintf, str.toCharArray(), itoa(X,Y,10) etc. nothing seems to be working so far. This CANT be that difficult. :sweat_smile:

Anyone?

I personally like to include <Streaming.h> which adds no overhead. Then you can have fun with formatting:

#include <Streaming.h>

...

    LocalHour = GPS.hour + TimeZoneHour;
    Serial.print("\nTime: ") ;
    Serial << ((LocalHour<10)?"0":"") ; 
    Serial.print(LocalHour, DEC); 
    Serial << (':') ;
    Serial << ((GPS.minute<10)?"0":"") ;
    Serial.print (GPS.minute, DEC); 
    Serial << (':') ;
    Serial << ((GPS.seconds<10)?"0":"") ;
    Serial.print(GPS.seconds, DEC) ;

    Serial.print("\nDate: ");
    Serial << ((GPS.day<10)?"0":"") ;
    Serial.print(GPS.day, DEC) ;              //DD
    Serial << "/" << ((GPS.month<10)?"0":"") ;
    Serial.print(GPS.month, DEC) ;            //MM
    Serial << "/20" ;
    Serial.println(GPS.year, DEC) ;           //YYYY

Ray

Thank you mrburnette . That is some strange looking code :fearful: I will look into it further. I especially like that it consumes no resources!!! Is the streaming.h included with the base arduino, or something I need to add to my libraries.

Is there a tutorial anywhere explaining this syntax? I am assuming the operations are worked starting at the right most position.
e.g. Serial << "Byte value: " << _HEX(b) << endl;
appends "endl" to " _HEX(b) "
appends above line to "Byte value:"
So Serial gets the combined string of text. Is "Serial" a variable I need to define elsewhere?
Can I do this type of concatenation to a variable...

char buffer[100];
buffer[] << "some ascii text (" << integer << ") more string" << long;

Where can I get some good background on the capabilities (& usage of) of "Streaming.h"

(and thanks for taking the time to reply)!

Sometimes, I forget to leave newbies the link.
http://arduiniana.org/libraries/streaming/

That should get you started. Find a good online C/C++ resource to discover goodies that are available to you but are not usually discussed in Arduino official pages.

Ray

Can this method be used to concatenate multiple strings into a single string?

Also can you explain the meaning of this line?

(LocalHour<10)?"0":"")

We want our display to be pretty:
HH:MM:SS
but numbers are not always cooperative, some are one digit, some are two digit.

So, the code : (LocalHour<10)?"0":"")

If the variable LocalHour is less than 10 then pad the output with "0" else (that colon) push out a null, ""
This effectively makes the length of HH:MM:SS always the same on the LCD

Ray