Libraries, Functions and Running out of Flash Memory

I'm new to Ardunio and very rusty on C. My problem is I've hit the limit on my Uno’s flash/program memory (ATmega328 = 32KB) limit for my project and I'm reasonably sure %80 or more is occupied by my libraries and their functions. I have read and attempted to apply space saving coding techniques with only very small marginal size differences (without touching the libraries). Here are the libraries I'm using:

Time.h
TimeAlarm.h
SoftwareSerial.h
TinyGPS.h
U8glib.h * I know my font selection using the u8glib will also add considerably to the flash size required.
Wire.h
Adafruit_BMP085.h

My question is: Is there an easy method for determining which libraries and functions in my code occupy the most program space?

The only idea I came up with was to use the example code for each library, remove functions I'm not using (eg serial debugging) and add absent functions that I’m using, compile and check the size. Is there a better way?

I don't want to post my code because it's unfinished, parts don't work, uncommented and generally very ugly.

For those interested in photos of my project and who haven't guessed it's a GPS Alarm Clock here it is http://www.flickr.com/photos/andrew-d/sets/72157630172598358/with/7162560453/.

Thanks for any help / suggestions.

I'm guessing it is your font. How big is it?

[quote author=James C4S link=topic=110994.msg833911#msg833911 date=1340254054] I'm guessing it is your font. How big is it? [/quote]

Font’s in use from the u8glib library: u8g_font_micro = 850 bytes u8g_font_fur11r = 1,726 bytes u8g_font_fur20n = 612 bytes

Total = 3,188 bytes (~3.11KB)

Reference http://code.google.com/p/u8glib/wiki/fontsize

So I knew the fonts used a bit but I don’t think they are the major culprit.

andrew-d:
My question is: Is there an easy method for determining which libraries and functions in my code occupy the most program space?

You could get a broad idea by first compiling an empty sketch, eg.

void setup () {}
void loop () {}

I got 466 bytes there.


Then add in a library, and use it, eg.

#include <SoftwareSerial.h>

SoftwareSerial mySerial (2, 3);

void setup () 
{
mySerial.begin (9600);
}
void loop () 
{
mySerial.println ("Hello, world.");
}

3286 bytes. So SoftwareSerial added 2820 bytes.

Repeat for other libraries.

It’s not quite as straightforward as that, because some libraries will share code (eg. Print class). But it’s a guide.


The other thing you can do is decompile the .elf file, browse through it, and see how many bytes each part takes.

avr-objdump -S xxx.elf > myoutput.txt

The name of the .elf file is shown if you do a “verbose compile”.

Thanks Nick and James,

Nick I did attempt using the process you described but thought there must be an easier/better way. I also found that totals were equalling more than my program. Your explanation of parts sharing code makes sense here.

I have a Mega board (the same one Nick helped me resurrect- thanks again) that I don't want to use but might have to for this project.

I will investigate the .elf file and attempt to see what's using up all that space.

Just a tip: copy and paste is quick and easy, but uses a lot of flash, compared to doing things with arrays. I don't know whether or not that applies to you.

Also, using longer data types (eg. int, long) takes more instructions that working with byte types. So if you know a variable will fit into a byte, don't use int or long for it.

Ok here’s some data that might provide useful to others. Rather than write code using each library and only the functions I have used I went for the simple and lazy option of sizing an included example (the one I considered most relevant to my project). This info needs a long list of disclaimers and conditions when attempting to apply it to how much a library of function might add to your project.

Library Name: Time.h
Example used: TimeSerial.pde
Size: 4,424 bytes
Extra Libraries:

Library Name: TimeAlarm.h
Example used: TimeAlarmExample (Needed to change WProgram.h to Arduino.h)
Size: 6,508 bytes
Extra Libraries: Time.h

Library Name: SoftwareSerial.h
Example used: SoftwareSerialExample
Size: 4,512 bytes
Extra Libraries: 

Library Name: TinyGPS.h (v12)
Example used: Test_with_gps_device
Size: 15,590 bytes
Extra Libraries: SoftwareSerial.h

Library Name: U8glib.h v1.06
Example used: Console (with ST7920 + SPI)
Size: 8,582 bytes
Extra Libraries: +Fonts used need to be added

Library Name: Wire.h
Example used: Digital_potentiometer
Size: 2,544 bytes
Extra Libraries: 

Library Name: Adafruit_BMP085.h
Example used: BMP085test
Size: 8,862 bytes
Extra Libraries: Wire.h

Library Name: <core>
Example used: SerialCallResponceASCII
Size: 3,514 bytes
Extra Libraries:

These examples use hardware serial and serial print. Some code will be shared. Additional functions, strings, variables, code, etc will add considerably to the size. How this applies to your project will vary greatly. Your mileage will vary. And there are probably other factors to consider when considering the effect on the size of your project. Let me disclaim everything. :wink:

But back to my project its clear several libraries are large and from the examples the two largest are the TinyGPS library and the Adafruit_BMP085 library. The Adafruit one surprised me with its size. I’m guessing the code and the library was written for readability not size or it’s simply complex to communicate with the BMP085 sensor.

I’m going to comment out my code using the Adafruit_BMP085 library and continue on.

Thanks for the help.