Low memory available?

I’m theorycrafting my keyboard layout at the moment and arduino IDE is giving me a scary warning about low dynamic memory that may cause stability problems when compiling/verifying.

Sketch uses 21,512 bytes (75%) of program storage space. Maximum is 28,672 bytes.
Global variables use 2,046 bytes (79%) of dynamic memory, leaving 514 bytes for local variables. Maximum is 2,560 bytes.
Low memory available, stability problems may occur.

I don’t have a unit to test on yet, so I’m not sure if these stability problems are something I need to worry about, but is this something to be concerned about? Am I doing something strange/incorrect to cause 2k of global variables?

Source for layout is here.

It’s hard for me to be sure without testing. There’s definitely optimization to be done.

That’s quite a bit of memory used! For reference, I’m at 1905 bytes, 74.4%, probably 0.6% below the warning threshold. I’ll have a look at your sketch to see what’s eating your memory.

1 Like

Interesting! Compiling the sketch here on Linux, Arduino 1.8.0 (with avr-gcc 4.9.2) yields:

- Size: firmware/james_layout/james_layout-0.0.0-gb0eb-dirty.elf
  - Program:   20886 bytes (72.8% Full)
  - Data:       1782 bytes (69.6% Full)

1.7k is perfectly reasonable, and I don’t see anything in the sketch that would increase memory use so drastically. What OS are you on, and what version of Arduino (& gcc/clang) are you using with it?

Ah! Apparently I was using Arduino 1.6.13 instead of 1.8.3. I switched to 1.8.3 & I’m down to 69%. My mistake!

For future reference though (as I think I’m probably going to start hitting that warning again soon), are there patterns one should be following/avoiding to keep memory usage reasonable?

Most of the time when I noticed an increase in memory use, was because I started using structures that were just too big.
Whenever you need to store something in a global, try to find a way to store as little as possible, or push the data to PROGMEM or EEPROM. Only keep in RAM what absolutely must be read-writeable at run-time. And don’t use things like bool stateMap[8] when you could use uint8_t stateMap and bit operations (and save 7 bytes!).

1 Like

For PROGMEM, if I understand the Arduino documentation, that means I just declare the variable with PROGMEM?
For storing in EEPROM, that means using the EEPROM get/set functions?

Thanks so much for your help!

Almost. You’ll need to use the pgm_read_byte/pgm_read_word-family of functions to read data back from there, too.

Yes. Perhaps in combination with the EEPROM-Settings plugin, if you want to be able to use other plugins that use EEPROM for settings.

1 Like

Hm…I’m a bit confused now. I added a bit more to my sketch and I’m back to 79% and getting the warning.
However, I’m not clear exactly what’s consuming memory for me: Looking at my sketch, as far as I can tell, it’s just function definitions, enums, and PROGMEM structures. I have some LED structs declared, but removing those only drops usage down 1%.

I think I’m missing something…

Ah, I think I was missing the obvious - I’m including a bunch of plugins that themselves use SRAM. I think I can remove a few LED effects and get back under the threshold.

The biggest one there is HostOS, with its OS-guesser mode enabled. That pulls in the FingerprintUSBHost library which uses a lot of RAM, well over 250 bytes. Looking at its code, I think we could reduce that significantly… until then, #define KALEIDOSCOPE_HOSTOS_GUESSER 0 will help, at the cost of not guessing the OS at boot time.

Yep! Plugins will add some RAM usage, some more than others. LED effects usually use little SRAM, surprisingly.

1 Like

Ah, that would explain it!

The first one I looked at was the Stalker effect, which declares a 2D array & was 4% of my RAM – I guess that’s not representative :stuck_out_tongue:

Thanks again for your assistance, I really appreciate it!

Stalker is one of the outliers =)

1 Like