What is EEPROM?

EEPROM is a non-volatile memory supported on many Arduino boards. “Non-volatile” means that it keeps its content when you power off the device.

The table below summarizes the capacity of the popular IoT boards:

Board EEPROM capacity
Arduino Leonardo 1 KB
Arduino Mega 2560 R3 4 KB
Arduino Micro 1 KB
Arduino Nano 1 KB
Arduino Nano Every 256 B
Arduino UNO 1 KB
Arduino UNO WiFi 256 B
Arduino Yún 1 KB
SparkFun RedBoard 1 KB
Teensy 2.0 2.5 KB
Teensy 3.2 2 KB
Teensy 3.5 4 KB
Teensy 3.6 4 KB
Teensy 4.0 4 KB
Teensy LC 128 B
Teensy++ 2.0 4 KB

Several other platforms support an emulation for EEPROM. For example, ESP32 uses a file in the Flash memory to replace EEPROM.

EEPROM is a perfect location to store your application configuration, and JSON is an excellent choice for the configuration format.

The only problem with EEPROM is that it’s slow to read and extremely slow to write.

How to use EEPROM?

The EEPROM is not mapped in the memory address space, so you must use dedicated functions. To write a byte to EEPROM, you must write:

EEPROM.write(address, value);

To read a byte from EEPROM, you must write:

value = EEPROM.read(address);

How to use EEPROM with ArduinoJson?

ArduinoJson doesn’t know about EEPROM.read() and EEPROM.write(), so it cannot natively use EEPROM.

However, serializeJson() and deserializeJson() support a generic interface that we can be used for virtually any kind of storage: Stream.

It’s quite easy to create a Stream class that calls EEPROM.read() and EEPROM.write(), but you don’t need to write it yourself because the StreamUtils library already provides an EepromStream class that does exactly this.

To write a JSON document to EEPROM, use:

EepromStream eepromStream(address, size);
serializeJson(doc, eepromStream);
eepromStream.flush();  // (for ESP)

As you can see, we pass two arguments to the constructor of EepromStream: the address and the size of the region of EEPROM that we want to expose as a Stream.
If you don’t know what to use for address, use 0.
If you don’t know what to use for size, use the value from the table above. On some platforms, you can use EEPROM.length(), which returns the quantity EEPROM available on the board.

The last line calls EEPROM.commit(); it is only required on ESP8266 and ESP32.

Similarly, you can read a JSON document from EEPROM with:

EepromStream eepromStream(address, size);
deserializeJson(doc, eepromStream);

Of course, don’t forget to include StreamUtils.h at the top of your source file.

StreamUtils is a powerful library that deserves more attention. Please give it a star to spread the word.

See also