Site Overlay

F() Macro with Strings in Arduino Programming

When working with ESP8266 or with Arduino boards I sometimes come across expressions like client.println(F("Server started.")); – That is the moment when I wonder what difference there is compared to client.println("Server started.");. After all, both versions will usually work.

In looking for an answer, I found a good discussion on the Arduino forum that explains the background of the F() function. Here are the key takeaways:

  • Arduinos and Arduino-like devices such as the ESP8266 or the ESP-32 feature a so called Harvard architecture.
  • This means that there are separate memories for instructions and data.
  • Instructions are stored in the FLASH memory.
  • Data is stored in the RAM.
  • In the Arduino world, code memory is sometimes referred to as PROGMEM and data memory is referred to as SRAM.
  • String constants are data and would normally be stored in the (S)RAM.
  • Methods such as Serial.println() expect the String argument to be a pointer to a char[] array that resides in SRAM, not in the FLASH/PROGMEM section.
  • To preserve RAM, we could also try to put String constants into the PROGMEM/FLASH part of the device, but there is a problem: objects stored in PROGMEM/FLASH are different from the traditional char[] arrays stored in SRAM.
  • The F() function forces String data to be stored in PROGMEM/FLASH and ensures that these objects behave like ordinary char[] arrays in later parts of the code.

There is a very good explanation on PROGMEM and the F() macro on the Arduino reference pages. The key takeaway is:

When an instruction like

Serial.print("Write something to the Serial Monitor");

is used, the string to be printed is normally saved in RAM. If your sketch prints a lot of stuff on the Serial Monitor, you can easily fill the RAM. If you have free FLASH memory space, you can easily indicate that the string must be saved in FLASH using the syntax:

Serial.print(F("Write something to the Serial Monitor"));

Note in particular, that the “generous” amount of memory is in the FLASH and not in the RAM (RAM will always be limited to around a meagre 160 kB). Especially with the Pro devices, there is an abundant amount of PROGMEM/FLASH. So flong strings or a series of strings that e.g. hold HTML code to define a web page, it makes sense, the F() macro is useful to redirect storage towards the PROGMEM/FLASH memory part.