Skip to content
Buy 10+ on select items — save 10% auto-applied
Free US shipping on orders $35+
Order by 3pm ET — ships same-day from the US
Skip to main content

Arduino EEPROM: Save Settings After Power Loss | ShillehTek

September 13, 2026 19 views

Arduino EEPROM: Save Settings After Power Loss | ShillehTek
Project

Build an Arduino EEPROM pattern to save LED state and a settings struct that survives power loss, using update(), put(), and get() with ShillehTek parts.

30 min Beginner5 parts

Project Overview

Arduino EEPROM - Save Settings That Survive Power Loss: This Arduino Uno EEPROM project shows how to store a button-controlled LED state and restore it after a reset or full power loss, then expands to a reusable settings struct pattern for real builds.

You will start with a simple on/off state saved to a single EEPROM address, then move to saving multiple configuration values with EEPROM.put() and restoring them with EEPROM.get(). You will also add a “magic number” so a first boot loads safe defaults instead of random data, and follow write-cycle rules so the EEPROM lasts.

  • Time: ~30 minutes
  • Skill level: Beginner
  • What you will build: A persistent LED toggle, then a reusable settings-that-survive-reboots pattern with a counter, a threshold, and a calibration value.
Arduino Uno using EEPROM to remember an LED on/off state after power is unplugged and restored
Pull the plug, plug it back in - the LED remembers.

Parts List

From ShillehTek

External

  • None

Note: EEPROM cells are rated for about 100,000 writes each. That is plenty for human-changed settings, and far too few for anything written in loop(). Use EEPROM.update() (writes only if the value changed) and only save when something actually changes.

Step-by-Step Guide

Step 1 - Wire a Button and an LED

Goal: Build the smallest possible test rig for saving and restoring state.

What to do: Wire the button between D10 and GND and use the internal pull-up resistor. For the LED, you can use D13 (the onboard LED), or wire an external LED for a brighter output: D8 to 220 ohm to LED to GND.

Arduino Uno schematic showing a pushbutton on D10 with INPUT_PULLUP and an LED output used for an EEPROM state demo
One button in, one LED out - the EEPROM does the remembering.

Expected result: Your hardware is ready to toggle an LED from a button press.

Step 2 - The Classic Demo: A State That Survives Reset

Goal: Confirm EEPROM persistence by restoring the last LED state after power loss.

Code:

#include <EEPROM.h>
const int BTN = 10, LED = 13, ADDR = 0;
bool state;

void setup() {
  pinMode(BTN, INPUT_PULLUP); pinMode(LED, OUTPUT);
  state = EEPROM.read(ADDR) == 1;     // restore last state (blank EEPROM reads 255 = off)
  digitalWrite(LED, state);
}

void loop() {
  if (digitalRead(BTN) == LOW) {
    state = !state;
    digitalWrite(LED, state);
    EEPROM.update(ADDR, state ? 1 : 0);   // save only if it changed
    delay(300);                           // crude debounce
  }
}

What to do: Upload the sketch, press the button to turn the LED on, then unplug the board and plug it back in.

Expected result: The LED comes back on by itself. Turn it off, power-cycle, and it stays off.

Step 3 - The Real Pattern: A Settings Struct

Goal: Store and restore multiple settings safely in one operation.

What to do: Put related settings in a struct and save the whole struct using EEPROM.put(). Add a “magic number” so the code can detect a first boot (or corrupted data) and load defaults instead of using garbage values.

Code:

#include <EEPROM.h>

struct Settings {
  uint16_t magic;        // 0xCAFE means "these are valid"
  uint16_t boots;        // how many times the board has started
  int      threshold;    // e.g. an alarm level
  float    calOffset;    // e.g. a sensor correction
  bool     ledOn;
};
const uint16_t MAGIC = 0xCAFE;
const int ADDR = 0;
Settings cfg;

void save() { EEPROM.put(ADDR, cfg); }     // writes only bytes that changed

void load() {
  EEPROM.get(ADDR, cfg);
  if (cfg.magic != MAGIC) {                // first boot (or corrupted): defaults
    cfg = { MAGIC, 0, 500, 0.0, false };
    save();
  }
}

void setup() {
  Serial.begin(9600);
  load();
  cfg.boots++;                             // count this start-up
  save();
  Serial.print("boot #"); Serial.println(cfg.boots);
  Serial.print("threshold "); Serial.println(cfg.threshold);
  Serial.print("calOffset "); Serial.println(cfg.calOffset, 3);
}

void loop() {
  // change a setting from the Serial Monitor: type  t=700  or  c=1.25
  if (Serial.available()) {
    String s = Serial.readStringUntil('\n'); s.trim();
    if (s.startsWith("t=")) cfg.threshold = s.substring(2).toInt();
    if (s.startsWith("c=")) cfg.calOffset = s.substring(2).toFloat();
    save();
    Serial.println("saved");
  }
}

What to do: Upload, open the Serial Monitor (newline line ending), type t=700, then reset the board.

Expected result: “boot #” climbs with every reset, and “threshold 700” comes back after the reset. The struct survived.

Step 4 - Rules for Not Wearing It Out

Goal: Keep the EEPROM healthy for long-term projects.

What to do: Do not put a save in loop() without a “did it change?” check. For values that change often (a counter or a log), spread writes across addresses (wear leveling), or save only on a button press or on a schedule (for example, once per day). If you update the struct layout later, change MAGIC so older data is discarded cleanly. Also remember that a blank EEPROM reads 255 for each byte, so never assume unused memory contains zero.

Expected result: Persistent settings that keep working for the life of the project.

Step 5 - On the ESP32 and Beyond

Goal: Apply the persistence idea correctly on other microcontrollers.

What to do: ESP32 and ESP8266 do not have true EEPROM. The EEPROM library emulates it in flash, so you must call EEPROM.begin(size) and EEPROM.commit(). On ESP32, the better approach is the Preferences library for key/value storage with wear leveling built in (for example, prefs.putInt("threshold", 700)). If you need to store thousands of records, use an SD card or an external I2C EEPROM chip such as the AT24C32 found on DS3231 RTC modules.

Expected result: You can pick the right persistence tool for each board family.

Conclusion

In this Arduino EEPROM tutorial, you built an LED state that survives power loss and a reusable settings struct pattern using EEPROM.put(), EEPROM.get(), and a magic number to handle first boot defaults safely.

Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.

Photo credit: Images referenced from galoebn on Hackster.io.

Parts for this build

Everything used in this tutorial. Uncheck what you already have.

All 5 in stock
0 parts selected $0.00