I'm trying to make my sketch smaller. Right now I use an array for the AM/PM part of my time display. My thinking is this makes it easy to change the formatting:
char* ampms[]= {"am", "pm"};
void loop() // run over and over again
{ //get time from RTC
getDateDs1307(&second, &minute, &hour);
//change to 12 hour format.
if (hour>12) { hr = hour - 12; ampm=1; } else { hr = hour; }
//add leading 0 for hours
if (hr<10) { lcd.print("0"); }
//print hour in 12 hour format.
lcd.print(hr, DEC);
lcd.print(":");
//add leading 0 for minutes
if (minute<10) { lcd.print("0");}
//print minutes
lcd.print(minute, DEC);
//print am or pm using array.
dataFile.print(ampms[ampm]);
}
I could do this instead:
void loop() // run over and over again
{ //get time from RTC
getDateDs1307(&second, &minute, &hour);
//change to 12 hour format.
if (hour>12) { hr = hour - 12; } else { hr = hour; }
//add leading 0 for hours
if (hr<10) { lcd.print("0"); }
//print hour in 12 hour format.
lcd.print(hr, DEC);
lcd.print(":");
//add leading 0 for minutes
if (minute<10) { lcd.print("0");}
//print minutes
lcd.print(minute, DEC);
//print am or pm using array.
if (hour>12) { lcd.print("am");} else {lcd.print("pm"); }
}
No more am/pm array. But, I have to add an if... is one better than the other for memory? Why?
1 Answer 1
As Ignacio says, if the compiled size is the same both ways, look for something else. (But note that having the constants in flash memory (program memory) may still use about the same amount of RAM, and typically will take more program space.)
When I compile the code you showed (together with minor additions like declaration of variables) I show the array method using 4 bytes less code and 5 bytes more RAM than the if
method, so there are tradeoffs.
You can replace the clunky if
statement and its two lcd.print
s with the following:
lcd.print(hour>12? "am" : "pm");
Note that that line retains the two bugs that your if
statement has, but it produces them more compactly. :) [One error is that your if
statement prints pm
for hours 0 through 12 and am
for hours 13 through 23. Another error is that it prints zeroes instead of twelves for the hours after midnight and noon. More properly, a program should print like 12:xx am during hour 0 of the day, and like 12:xx pm, 1:xx pm, ... 11:xx pm during hours 12 through 23.]
Also note that as Gerben mentions, moving the "am" and "pm" strings into program memory via
lcd.print(hour>12? F("am") : F("pm"));
saves 6 bytes of RAM. However, that improvement in RAM usage is offset by 74 additional bytes of program space! The following saves 6 bytes of RAM while increasing program size by only 12 bytes so may be preferable:
lcd.print(hour>12? 'p' : 'a');
lcd.print('m');
The following lines of C can replace much of the code you showed. However, the printf
library uses about 1300 bytes of program space, so the following compact-source-code approach cannot be recommended unless you are already loading some printf
functions. It replaces the lines from if (hour>12) { hr = hour - 12; } ...
to the end with
enum { bufsize=8 };
char buf[bufsize];
snprintf (buf, bufsize, "%02:02%cm", hour%12, minute, hour>12? 'p' : 'a');
lcd.print(buf);
-
lcd.print(hour>12? F("am") : F("pm"));
will safe 6 more bytes.Gerben– Gerben2015年08月02日 08:34:39 +00:00Commented Aug 2, 2015 at 8:34 -
@Gerben, but program size increases 74 bytes. Printing characters (see edited answer) saves the 6 bytes of RAM but increases program size only 12 bytesJames Waldby - jwpat7– James Waldby - jwpat72015年08月02日 15:33:02 +00:00Commented Aug 2, 2015 at 15:33
-
didn't thing of checking that. That's very interesting. Having an almost empty sketch with only that line, will make it increase by only 26 bytes on my system.Gerben– Gerben2015年08月02日 15:42:28 +00:00Commented Aug 2, 2015 at 15:42
avr-size
says what?