Arduino programming guide series

Save SRAM with the F() macro

In embedded devices, like the Arduino, RAM is limited. However, there are a few simple methods you can use to reduce the memory footprint of your sketches so that they will fit in the available memory space. The F() macro is one such method.

The image above is a photo of static RAM (SRAM) cells of a STM32F103VGT6 microcontroller, taken by a scanning electron microscope. By ZeptoBars - http://zeptobars.ru/en/read/open-microchip-asic-what-inside-II-msp430-pic-z80, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=25044206

The Arduino Uno's ATmega328P only has 2048 bytes of SRAM (static RAM). It also has 32 KBytes of flash memory.

The flash memory is where your sketch is stored when you upload it. Flash memory persists when you turn the Arduino off.

The SRAM is where the various variables in your sketch are stored during execution. Unlike flash memory, the contents of the SRAM do not persist when you turn the Arduino off.

In the Arduino Uno, there is a lot more flash than SRAM space.

Let's look at an example of how SRAM space is used, and how easy it is to misuse it.

Take this simple instruction:

Serial.println("Hello world!");

It doesn't do anything fancy. It will simply print a short string of text to the serial monitor.

The string of text in the double quotes will occupy 12 bytes in the SRAM. If you have a few additional println() statements like that, your sketch will easily fill the SRAM with static strings of text.

If your program is large with a lot of variables like this, there is a good chance you will run out of RAM, and your program will crash.

Because the string in this example is static, i.e. it does not change, you can easily optimize your sketch by storing the string in the plentiful flash memory instead of the SRAM.

Serial.println(F("Hello world!"));

I have marked the F() macro used in the println() instruction in bold.

The F() macro tells the compiler that the contents of the parameter should be stored in the flash memory (program memory or PROGMEM), instead of the SRAM, hence saving you this valuable resource for better use.

The F() macro provides us an easier syntax for marking compatible data type values to be stored in program memory, in place of the PROGMEM keyword modifier. If you wanted to use the raw PROGMEM modifier instead of the F() macro, you would do it like this:

const char a_string[] PROGMEM = "Hello world!";

void setup()
{
  Serial.begin(9600);
  for (byte k = 0; k < strlen_P(a_string); k++) {
    myChar = pgm_read_byte_near(a_string + k);
    Serial.print(myChar);
  }
}

I find the F() macro much easier compared to manually marking a constant string for storage in program memory and then reading it back one byte at a time.

New to the Arduino?

Arduino Step by Step Getting Started is our most popular course for beginners.

This course is packed with high-quality video, mini-projects, and everything you need to learn Arduino from the ground up. We'll help you get started and at every step with top-notch instruction and our super-helpful course discussion space.

We publish fresh content each week. Read how-to's on Arduino, ESP32, KiCad, Node-RED, drones and more. Listen to interviews. Learn about new tech with our comprehensive reviews. Get discount offers for our courses and books. Interact with our community. One email per week, no spam; unsubscribe at any time

Image
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}