Home Learning How Arduino Handles Memory: SRAM, Flash, and EEPROM Explained

How Arduino Handles Memory: SRAM, Flash, and EEPROM Explained

by shedboy71
[lebox id="1"]

Flash, SRAM, and EEPROM are the three different types of memory that Arduino boards use. Each type has its own job. To write stable, efficient, and scalable sketches, you need to know how these types of memory work and how Arduino uses them. This is especially true as projects get more complicated.

Many problems with Arduino, like random crashes, corrupted variables, or unexpected resets, are not logic errors but memory problems, especially when SRAM runs out.

This guide goes into great detail about each type of memory, shows how Arduino allocates memory, and gives a lot of examples of how to code in real life.

Arduino Memory Types at a Glance

Memory Type Purpose Volatile Typical Size (Uno)
Flash Program storage No 32 KB
SRAM Runtime variables Yes 2 KB
EEPROM Persistent data No 1 KB

Flash Memory (Program Memory)

What Flash Memory Does

Flash memory stores:

  • Your compiled sketch
  • Constant data (if explicitly stored there)
  • Bootloader

Flash memory is non-volatile, meaning it retains data when power is removed.

On most Arduino boards:

  • Flash is much larger than SRAM
  • Ideal for constants, strings, and lookup tables

Flash Memory Example: Basic Program Storage

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("Hello from Flash");
  delay(1000);
}

Even though the string literal appears small, by default it is copied into SRAM at runtime, which can be wasteful.

Storing Data in Flash with PROGMEM

#include <avr/pgmspace.h>

const char message[] PROGMEM = "Stored in Flash";

void setup() {
  Serial.begin(9600);

  char buffer[20];
  strcpy_P(buffer, message);
  Serial.println(buffer);
}

void loop() {}

Why this matters: The string stays in Flash and is only copied into SRAM when needed.


Flash Lookup Table Example

#include <avr/pgmspace.h>

const int sineTable[10] PROGMEM = {
  0, 173, 342, 500, 642, 766, 866, 939, 984, 1000
};

void setup() {
  Serial.begin(9600);

  for (int i = 0; i < 10; i++) {
    int value = pgm_read_word(&sineTable[i]);
    Serial.println(value);
  }
}

void loop() {}

Best use cases for Flash:

  • Text strings
  • Lookup tables
  • Fixed configuration data
  • Fonts and graphics

SRAM (Static Random-Access Memory)

What SRAM Does

SRAM stores:

  • Global variables
  • Local variables
  • Function call stack
  • Heap (dynamic memory)

SRAM is volatile and extremely limited. On an Arduino Uno, you have only 2048 bytes.


SRAM Allocation Breakdown

|-------------------|
| Global variables  |
|-------------------|
| Heap (malloc/new)|
|-------------------|
| Free SRAM        |
|-------------------|
| Stack            |
|-------------------|

If the heap and stack collide, your program becomes unstable.

Example: Global vs Local Variables

int globalCounter = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int localCounter = 0;
  globalCounter++;
  localCounter++;
  Serial.println(globalCounter);
}

Global variables permanently consume SRAM, while local variables are created and destroyed on the stack.

Dangerous SRAM Usage: Strings

String name = "Arduino";
String greeting;

void setup() {
  greeting = "Hello " + name;
  Serial.println(greeting);
}

This causes:

  • Heap fragmentation
  • Unpredictable crashes in long-running programs

Safer Alternative: Character Arrays

char name[] = "Arduino";
char greeting[20];

void setup() {
  strcpy(greeting, "Hello ");
  strcat(greeting, name);
  Serial.println(greeting);
}

This uses fixed memory, avoiding fragmentation.

Measuring Free SRAM

extern int __heap_start, *__brkval;

int freeMemory() {
  int v;
  return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}

void setup() {
  Serial.begin(9600);
  Serial.print("Free SRAM: ");
  Serial.println(freeMemory());
}

void loop() {}

This helps diagnose memory leaks and overuse.

EEPROM (Electrically Erasable Programmable ROM)

What EEPROM Does

EEPROM stores:

  • Calibration values
  • User settings
  • Persistent counters

EEPROM:

  • Retains data after power loss
  • Has limited write cycles (typically ~100,000)

Writing to EEPROM

#include <EEPROM.h>

void setup() {
  EEPROM.write(0, 123);
}

void loop() {}

This writes a single byte to address 0.

Reading from EEPROM

#include <EEPROM.h>

void setup() {
  Serial.begin(9600);
  int value = EEPROM.read(0);
  Serial.println(value);
}

void loop() {}

EEPROM Put and Get (Preferred)

#include <EEPROM.h>

struct Settings {
  int threshold;
  float calibration;
};

Settings config = { 100, 1.23 };

void setup() {
  EEPROM.put(0, config);

  Settings loaded;
  EEPROM.get(0, loaded);

  Serial.begin(9600);
  Serial.println(loaded.threshold);
  Serial.println(loaded.calibration);
}

void loop() {}

put() only writes if the data changes, reducing wear.

EEPROM Wear Management Example

int address = 0;

void saveValue(int value) {
  EEPROM.update(address, value);
}

update() avoids unnecessary writes.

Common Memory Mistakes

Mistake 1: Too Many Global Variables

int bigArray[500];  // Consumes 1000 bytes of SRAM

This alone uses nearly half of Uno SRAM.


Mistake 2: Uncontrolled Dynamic Allocation

char* buffer = (char*)malloc(100);

Repeated allocations cause fragmentation.

Mistake 3: Forgetting PROGMEM for Strings

Serial.println("Long debug message...");

Repeated string literals silently consume SRAM.

Best Practices for Arduino Memory Management

  • Store constants in Flash using PROGMEM
  • Avoid String class in long-running sketches
  • Use EEPROM sparingly and intentionally
  • Monitor free SRAM during development
  • Prefer fixed-size buffers
  • Keep global variables minimal

Memory Comparison Summary

Feature Flash SRAM EEPROM
Volatile No Yes No
Size Large Very small Small
Speed Fast Fastest Slow
Best Use Code, constants Variables Persistent data

Final Thoughts

The difference between beginner sketches and reliable embedded systems is knowing how to use Arduino memory.

You can greatly improve stability, performance, and scalability by carefully choosing where data lives, like in Flash, SRAM, or EEPROM.

Most of the time, Arduino problems in the real world are caused by memory.

With the methods shown here, you can avoid those problems and write code that is as good as what professionals do.

Share
[lebox id="2"]

You may also like