One way to diagnose memory problems is to measure how much memory is in use.

Flash

Measuring Flash memory usage is trivial. The compiler does that for you, every time you compile!

EEPROM

You are 100% in control of EEPROM usage. You have to read and write each byte to a specific address, so there is no excuse for not knowing exactly which bytes are in use!
// ************************************************
// Write floating point values to EEPROM
// ************************************************
void EEPROM_writeDouble(int address, double value)
{
   byte* p = (byte*)(void*)&value;
   for (int i = 0; i < sizeof(value); i++)
   {
      EEPROM.write(address++, *p++);
   }
}

// ************************************************
// Read floating point values from EEPROM
// ************************************************
double EEPROM_readDouble(int address)
{
   double value = 0.0;
   byte* p = (byte*)(void*)&value;
   for (int i = 0; i < sizeof(value); i++)
   {
      *p++ = EEPROM.read(address++);
   }
   return value;
}

SRAM

SRAM usage is more dynamic and therefore more difficult to measure. The freeMemory() function below is one way to do this. You can add this function definition to your code, then call it from various places in your code to report the amount of free SRAM.

SRAM utilization is dynamic and will change over time. So It is important to call freeMemory() at various times and from various places in your sketch to see how it changes over time.

This code is taken from this small library: https://github.com/mpflaga/Arduino-MemoryFree and works on both AVR and ARM (M0) processors.

#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else  // __ARM__
extern char *__brkval;
#endif  // __arm__

int freeMemory() {
  char top;
#ifdef __arm__
  return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
  return &top - __brkval;
#else  // __arm__
  return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif  // __arm__
}

What freeMemory() is actually reporting is the space between the heap and the stack. it does not report any de-allocated memory that is buried in the heap. Buried heap space is not usable by the stack, and may be fragmented enough that it is not usable for many heap allocations either. The space between the heap and the stack is what you really need to monitor if you are trying to avoid stack crashes.

This guide was first published on Aug 02, 2013. It was last updated on Mar 08, 2024.

This page (Measuring Memory Usage) was last updated on Mar 08, 2024.

Text editor powered by tinymce.