C2
October 20, 2009, 2:17am
1
I made that up...
I'm printing values to a serial LCD and wonder what is a good way to handle the transition to a smaller number of digits.
For example, when printing the time (from TinyGPS crack function):
1:59:59 changes to 2:0:059
So I do something like this:
if ((static_cast<int>(hour)) < 10){
LCD.print("?x08?y0"); LCD.print("0"); LCD.print(static_cast<int>(hour));
}
if ((static_cast<int>(hour)) > 9){
LCD.print("?x08?y0"); LCD.print(static_cast<int>(hour));
}
LCD.print(":");
if ((static_cast<int>(minute)) < 10){
LCD.print("?x11?y0"); LCD.print("0"); LCD.print(static_cast<int>(minute));
}
if ((static_cast<int>(minute)) > 9){
LCD.print("?x11?y0"); LCD.print(static_cast<int>(minute));
}
LCD.print(":");
if ((static_cast<int>(second)) < 10){
LCD.print("?x14?y0"); LCD.print("0"); LCD.print(static_cast<int>(second));
}
if ((static_cast<int>(second) > 9)){
LCD.print("?x14?y0"); LCD.print(static_cast<int>(second));
}
But it does not seem to be the most efficient solution.
The same sort of issue when printing a servo angle that is decreasing from 100 to 990 degrees.
system
October 20, 2009, 2:35am
2
sprintf() is the function you want, it'll handle the zero-padding for you.
C2
October 20, 2009, 3:37am
3
I looked around a bit for the sprintf() function, but could not figure out how to use it.
Another post here suggested it was slow and the if condition is fine. I'd still like to learn new things though..
Anyway, the other post gave me an idea on how to streamline my code a bit:
LCD.print("?x08?y0");
if ((static_cast<int>(hour)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(hour));
LCD.print("?x10?y0"); LCD.print(":");
if ((static_cast<int>(minute)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(minute));
LCD.print("?x13?y0"); LCD.print(":");
if ((static_cast<int>(second)) < 10)
LCD.print("0");
LCD.print(static_cast<int>(second));
system
October 20, 2009, 3:42am
4
As Fjornir said, sprintf() is the easy way to go. For example,
char timestr[20];
sprintf(timestr,"%02d:%02d:%02d",hour,minute,second);
LCD.print(timestr);
Will produce a string like: 02:09:07
If you want the hours to be padded with a space instead of a leading zero, use the format "%2d:%02d:%02d" instead.
-Mike
C2
October 20, 2009, 3:50am
5
Thanks!
In a parallel dimension so infinitely close, I found your other post:
It's mentioned in "K-R", the book "The C Programming Language" by Brian Kernighan and Dennis Ritchie.
There's also a good summary in Wikipedia: printf - Wikipedia .
-Mike
system
October 20, 2009, 4:06am
6
Another post here suggested it was slow and the if condition is fine.
Slow is relative. The arduino is clocked at 16MHz. 16 million clocks per second. Most instructions are retired in a single clock but the worst case is 3 clocks. But even if all of them were 3 clocks that's still 5.3 million instructions per second.
If you're in the middle of a tight inner loop for dealing with gyroscopic stability of a balancing robot then worry about timing. If you're updating a display with the current time who cares if the results are displayed a couple milliseconds faster or slower?
C2
October 20, 2009, 4:27am
7
I appreciate all the insight.
I noticed that the sprintf() function added 1388 bytes to my sketch size, but the short routine dropped to 17ms from 31ms, so it is actually much faster!
(I added a serial.print (millis()); line to the beginning and end of both methods to figure out the time, if that is a valid way)
I wonder, does adding the function bring overhead that can be reused if the function is used in other places?
system
October 20, 2009, 4:36am
8
(I added a serial.print (millis()); line to the beginning and end of both methods to figure out the time, if that is a valid way)
That mechanism for timing won't be perfectly precise but it is certainly "good enough"
I wonder, does adding the function bring overhead that can be reused if the function is used in other places?
Pretty much, yeah. Once the function is in, it is in, and you can use it other places at no additional cost.