Tag Archives: Uno

Arduino Memory Management.

Arduino UnoI had been playing with my Arduino Uno for about 3 months when I decided I needed a real project to put my skills to the test. My first real project was to web enable my garage door. I planned to use the Ethernet Shield to host a simple web page. However, during the development I started getting strange behavior. Only the first portion of my web page was being served. Not yet knowing my problem was related to memory, I tried in vain to comment out different parts of my code to find an elusive bug. After a bit of frustrating troubleshooting, I discovered that my problem wasn’t a code bug, it was memory based.

As it turns out, the ATMega328 chip for my Arduino Uno has 3 kinds of memory…

ATMega328 Memory
Type Amount Description
SRAM 2 Kb RAM for your program to run
EEPROM 1 Kb Can be used as durable storage
FLASH 32 Kb This is what you upload your sketch to

SRAM is the static random access (i.e. volatile) memory for your sketches. The variables you create and the Libraries you use can quickly eat up this limited memory resource. To get an idea of how small 2 Kb is, generate a 2 Kb Lorem Ipsum.

Since I was using three libraries, Ultrasonic.h, SPI.h, and Ethernet.h, I suspected I might have a problem there. I loaded up the following simple sketch to see what my base memory footprint was before writing any code.

I examined the SRAM consumption and found I had only consumed about 273 bytes (~15%) of the SRAM. Therefore, the memory consumption from the libraries I was using was not an issue. Next, I started adding the code for my simple web page to see if something I was doing there was problematic.

After adding the above code, and examining the SRAM consumption, I was starting to understand where my memory problems were coming from. The strings in my println functions were being consumed by SRAM even though they were static. At runtime, such strings are copied from FLASH to SRAM. I could tell, at my current rate of SRAM consumption, my sketch wasn’t going to cut it. By this point, I wasn’t yet reading incoming data from submitting the form and I was already consuming 1236 bytes (~60%) of the available SRAM. Also, I still needed to add code for using the ultrasonic sensor to read if the garage door was up or down and inject that into the HTML.

Luckily, I discovered the F() function for leaving static strings in FLASH memory instead of copying them to SRAM. The F() function basically tells your Arduino not to copy the strings into SRAM. Rather, a pointer is used to read the strings from FLASH. Since every character in my HTML consumes a byte of memory, this trick saves a lot of SRAM. The following demonstrates the kind of changes I needed to make.

After making this change, my SRAM memory consumption was only about 400 bytes (21%).

This simple trick works for static strings in sketches but what if you wanted declare a variable in a sketch and not have that variable copied to SRAM at runtime?

PROGMEM is a variable modifier specifically for this purpose. In my case, I had a global constant that was being used by my sketch. Using the PROGMEM variable modifier, I was able to keep the variable value in FLASH and out of SRAM.

It’s worth noting that, in my case, I’m really only saving myself a few bytes of SRAM with the above variable. But the example illustrates that you can keep variables in FLASH to preserve what precious little SRAM you are limited with.

The last form of memory on the ATMega328 is EEPROM (1 Kb). This form of memory works like durable storage. Values stored in EEPROM are not volatile and persist even if the Arduino loses power. You can store one byte in EEPROM by supplying the memory address and the byte value. Then you can retrieve the byte by supplying the address. Therefore, it’s not practical to try to optimize SRAM memory consumption by saving data in EEPROM. The real benefit of using EEPROM is data durability.

For completeness, it’s worth mentioning that the data write/erase cycle lifespan is 100,000 for EEPROM, 10,000 for FLASH, and basically unlimited for SRAM. Therefore, choosing the appropriate memory location for volatile data would be prudent so that you don’t prematurely wear out the chip.

There is a great memory optimization series on Adafruit’s web site. Check out Memories of an Arduino for more information. Also, there is a good tutorial on Arduino.cc that covers the basics.