I was writing code for a MEGA, but as I developed the program, the RAM usage kept rising quite fast even though I did not add any variables.
I use a lot of
Serial.println("Different text to inform about status, erros etc");
I then made a small test (see image) - and found out that even when printing a fixed text without using any variables, this consumes quite some RAM.
This surprised me. Does anyone know why this is so? I would expect this to take up flash memory since it is fixed text that does not change in the program - but not RAM.
I searched the forum but did not find other posts about this topic.
Looking much forward to your kind replies.
Test code is below. Try to compile, remove the // and compile again. Then you probably get the same result as me.
void setup()
{
Serial.begin(9600);
}
void loop()
{
delay(1000);
Serial.println("This is just a text");
Serial.println("This is just another text");
//Serial.println("This is a third text");
}
In the AVR processor family, the FLASH is in a different address space from the RAM. Your sketch has easy access to RAM but very limited access to FLASH. To allow your sketch to treat strings as any other data they are all copied from FLASH to RAM before your sketch starts.
There is a trick you use to prevent this copying for string literals used for .print() or .println(). There is a macro named 'F()' that marks the string literal as data that should stay in FLASH and then casts it to special type ('__FlashStringHelper *'). The cast causes the compiler to select the .print() and ,print() functions that know how to fetch the characters from FLASH (a.k.a. PROGMEM).
Just change your prints to: Serial.println(F("This is just a text"));
to save a bunch of RAM.
Some day you might need a large look-up table of constant data. To keep your table from being copied into RAM you can use the "PROGMEM" attribute but be warned: The compiler doesn't keep track of the location of variables for you. You have to remember which addresses are in PROGMEM and call special functions like 'pgm_read_byte()' to read data from PROGMEM.
@johnwasser Bonus question: Will this work for lcd.print as well even when I am using the non-standard LiquidCrystal440.h which by the way I would like to share with other users who likes to use HD44780 compatible LCD displays with 2 enable pins - but I am too newbie to use github correctly.
Any object class derived from the Print class inherits its features, including support for the F() macro. The Stream class is derived from the Print class so streams (SD files, network servers, network clients) also support the F() macro.