How to optimize your Arduino memory usage

If you are unfortunately hitting the memory limit on your arduino, let me first take the moment to congratulate you! You have already become a master of arduino and programming. Otherwise you would not have come up with so many lines of code to fill your arduino up!

Go through the typical practice I go through and trim some fat from your program so you will squeeze more onto your arduino.

First, you should know what content goes to what memory: program and variable initial values go to Flash, variables and their initial values go to SRAM. Yes, initial values go in both places. Read this if you want more understanding on what ram is what.

Now if Arduino IDE tells you your sketch is too long, it is complaining your sketch is bigger than the Flash. You should do the following things to reduce that usage:

1) Have you been using function calls instead of repeating your codes?

Eg. repeating code to blink LED:

void setup()

{}

void loop()

{

digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);

digitalWrite(2,HIGH);
delay(300);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(300);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(300);
digitalWrite(2,LOW);
delay(25);

digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);
digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);

}

This is very long and detailed. It offers no hint of what you’re doing but instead tells you all the details you don’t want to know and takes too much space. You should do the following:

Define a function to do the blink and call the function every time you want to blink:

void blink_long()

{

digitalWrite(2,HIGH); // This blinks the LED for 300ms
delay(300);
digitalWrite(2,LOW);
delay(25);
}
void blink_short()// This blinks the LED for 100ms
{
digitalWrite(2,HIGH);
delay(100);
digitalWrite(2,LOW);
delay(25);
}

void setup()
{}

void loop()
{
blink_short();
blink_short();
blink_short();

blink_long();
blink_long();
blink_long();

blink_short();
blink_short();
blink_short();

}
Aha! You were sending the Morse code of SOS for help! Now it is super clear. You have also saved precious memory on your arduino Flash. From my test with Duemilanove, compile size is 1136 bytes for the long and tedious version but only 896 bytes for the short and tidy version. Have in mind that the 448 bytes were used as overhead. The actual size of your sketch’s function is 688 bytes for the long version and 448 bytes for the short version. This doesn’t sound like much but version long costs you 76 bytes memory per beep while version short costs you 50 bytes memory per beep. This all adds up. Just think about more complicated functions.

2) Have you been too verbose in your messages?

Say you do Serial.print(“Haha, you know what, the resistance is just as we expected, 100 Ohm, right on my man!”);

You should be doing this instead Serial.print(resistance);

Output the bare essential to not waste your storage space on arduino.

Also, if you have several places where you output essentially the same messages, make them exactly same. Arduino IDE will optimize and only keep one copy of the message so you save Flash.

Eg.

Serial.print(“This egg is bad, it is green!”);

Serial.print(“This egg is also bad, it is pretty green!”);

Serial.print(“This is a bad egg waiter, it is green!”);

You should output “Bad egg! It’s green!” instead so similar messages don’t get stored in three different ways on the Flash.

3) Have you been using all the compiled functions?

Say you have Serial.begin() in you setup and a few Serial.print() functions spread out in your code, initially for debugging. Now you’re fully confident with your code, you should remove them or comment them out. Otherwise if a function appears in your code, it will be stored in the Flash. If you shed the libraries you don’t need, you will save considerable amount of space. Arduino IDE does a good job on this but you can always help by removing junks.

4) Have you avoided function overloads? This is an advanced topic and should only be attempted by the experienced.

Say you want to print a few numbers to your serial monitor, you do this;

int a=10;
float b=1.57;
void setup()
{
Serial.begin(115200);
}

void loop()
{
Serial.print(a);
Serial.print(b);
}
Compiled size is 3570 bytes.

Instead you should have never overloaded the Serial.print(float) function and stick to Serial.print(int) instead:

Serial.print(a);
Serial.print(int(b));
Serial.print(int(100*(b-int(b))));

Compiled size is only 3064 bytes. Although we increased the complexity of the code, we have avoided to overload the Serial.print(float), saving 500 bytes. In larger programs, you will always use Serial.print(char[]) method and possibly sprintf() to organize your output. In this case, stop using Serial.print(float) or even Serial.print(int) just because you’re lazy. Always use sprint() and Serial.print(char[]) so you save from not overloading two functions.

Now if you want to optimize your SRAM, you should watch out the above plus the following:

1) Have you used the appropriate variable types for the job?

If your variable can be stored in a short, don’t use long. If it is not float, use int. This is especially useful if you have arrays.

You should also think about your measurements. Say you want to store voltages from an analog input, you used float array to store 2.503V etc. Wrong! You should have used an int array to store the original reading, which is only between 0 and 1024. You save 50% space just by doing this. You can convert them later if you want.

2) Shorten your char [] sizes to appropriate sizes.

If you are using a 16X2 LCD, define char msg[17];

You don’t need too much more than 16 characters as message buffer.

3) Have you used too many string literals? This is again for advanced programmers.

If you have many strings in your program, you should use PROGMEM to store them in the Flash and access them only when needed. I have a whole other topic on this issue so it’s not detailed here.

In retrospect, I have regretted taking my above suggestions a couple times so you want to know about this too. Aggressively reducing variable size can lead to overflow and memory corrupt. Make sure you’re not giving too little space for your variables and plan for future expansion.

Arduino memory

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine

Do you ever wonder how much memory your arduino has and should you worry about it running out? Here is the answer:

There are three types of memory on the arduino’s main chip, the ATMEGA328 chip:SRAM, flash RAM, and EEPROM. Here is what they do:

SRAM holds all the variables you define, including integers, floats, strings, objects, etc, as well as the stack, the space used in function calls. There are only 2KB or 2048 bytes of SRAM on board so one should make some effort to save this memory. This RAM is volatile meaning its content is wiped clean when power is removed.

Flash RAM holds the arduino bootloader and the entire compiled program. The total size is 32KB or 32768 bytes. The bootloader is typically 2KB or less, leaving about 30KB for your compiled program. This memory is checked by Arduino IDE and will not be run out without the IDE complaining to you first. From my experience, around 100 lines of C code will consume 1KB or flash RAM. The initial value of a variable is also stored in the Flash RAM. If you have char msg[]=”Hello”; in your program. First it shows up on the Flash RAM as initial value of msg being “Hello”, then when the program starts running, “Hello” will be copied to the SRAM so taking space in both flash and SRAM. This is unfortunate for variables like an integer but constant strings don’t change their values so they don’t need to reside in SRAM at all time. With a mechanism, you can keep them in flash until you need them. Then load them to SRAM, use the string, then dump it. Flash RAM is non-volatile meaning its content is retained in case power is removed.

EEPROM is electrically erasable programmable read-only memory. It is used to store parameters and small amount of data so that every time arduino starts up, it can load the parameters and data. Then you can change these parameters and save them to the EEPROM so your changes won’t be lost when you power off. There are 1KB or 1024 bytes of EEPROM on ATMEGA328, the chip that UNO and Duemilanove use. EEPROM is slow so it is not practical to store variable on EEPROM.

 

For suggestions on how to optimize your arduino memory, read this post.