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
*/
}
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
*/
}
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
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.
Thank you mrburnette . That is some strange looking code 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"
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.
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