37. EEPROM-Based Microcontroller Restart Counter

The task is to track the number of times a microcontroller restarts (due to reset or power failure) and display the count on a serial terminal (e.g., PuTTY, Arduino IDE).

We are going to use EEPROM (Electrically Erasable Programmable Read-Only Memory) to store the restart count because it retains data even after power loss.

Requirements

  • Increment and store the counter in EEPROM each time the microcontroller resets.
  • Display the restart count on the serial terminal.
  • Allow the user to reset the counter to zero via a serial command (e.g., typing ‘R’ or ‘reset’).


 Below are the solutions to the given task using different microcontrollers:

  1. ESP32
  2. Arduino UNO

We are using the ESP32 DevKitC v4 development board and programming it using the Arduino IDE.

  • Before uploading, make sure to select “ESP32 Dev Module” as the board to ensure correct settings and compatibility.

ESP32 does not have a real EEPROM chip inside. Instead, part of its Flash memory is used to simulate EEPROM behaviour.

Hardware Connection

Connect the ESP32  development board to your computer using a USB cable.

Code

#include <EEPROM.h>

#define EEPROM_SIZE 64  // Using 64 bytes of flash (adjust as needed)
#define RESTART_COUNT_ADDR 0

void setup() {
  delay(3000);
  Serial.begin(115200);
  while (!Serial)
    ;  // Wait for serial connection

  // Initialize EEPROM emulation with specified size
  EEPROM.begin(EEPROM_SIZE);

  Serial.println("ESP32 EEPROM Emulation - Restart Counter");

  // Read, increment, and store restart count
  int restartCount = EEPROM.read(RESTART_COUNT_ADDR);
  restartCount++;
  EEPROM.write(RESTART_COUNT_ADDR, restartCount);
  EEPROM.commit();  // Must commit to save changes

  Serial.print("Device restarted ");
  Serial.print(restartCount);
  Serial.println(" times.");

  // Reset option
  Serial.println("Do you want to reset the counter. Press Y or N");
  while (1) {
    if (Serial.available()) {
      char input = Serial.read();
      if (input == 'Y' || input == 'y') {
        Serial.println("Resetting counter...");
        EEPROM.write(RESTART_COUNT_ADDR, 0);
        EEPROM.commit();
        Serial.println("Counter reset. Restart device.");
        break;
      } else {
        Serial.println("Counter not reset");
        break;
      }
    }
  }
}


void loop() {
  Serial.println("Performing normal operations...");
  delay(5000);
}

Code Explanation

  • EEPROM_SIZE (macro)
    • Sets the emulated EEPROM size to 64 bytes of Flash (allocated by EEPROM.begin(EEPROM_SIZE)).
  • RESTART_COUNT_ADDR (macro)
    • Address 0 where the restart counter is stored.
  • setup()
    • At start, it waits 3 seconds, opens Serial at 115200, sets up a 64-byte EEPROM, reads the counter at address 0, adds 1, saves it with EEPROM.commit(), prints the new count, and asks if you want to reset it.
  • loop()
    • Placeholder activity—prints a status line every 5 seconds.
  • EEPROM.begin(EEPROM_SIZE)
    • Allocates a 64-byte region in Flash to emulate EEPROM.
  • EEPROM.read(RESTART_COUNT_ADDR)
    • Reads one byte from address 0 ; here it’s stored into an int, but only the low byte is meaningful.
  • EEPROM.write(RESTART_COUNT_ADDR, value)
    • Writes a byte to the RAM buffer at address 0; does not reach Flash until EEPROM.commit().
  • EEPROM.commit()
    • Flushes buffered changes to Flash—required on ESP32 to persist writes.

Precautions when Allocating Flash to EEPROM

  1. Don’t exceed Flash partition size
    • The emulated EEPROM uses the “app data” area of Flash and is safe up to about 4096 bytes. Allocating more (e.g., EEPROM.begin(8000)) can corrupt other Flash data or cause runtime errors.
  2. Write infrequently
    • Each Flash cell supports a limited number of writes (~100k).
      • Avoid continuous writing in loop().
      • Use EEPROM.commit() only when values actually change.
  3. Call EEPROM.commit() after writing
    • Without this, your changes stay only in RAM and disappear after a restart.
  4. Avoid overlapping with other Flash uses

We are using the Arduino UNO development board and programming it using the Arduino IDE.

  • Before uploading, make sure to select “Arduino UNO” as the board to ensure correct settings and compatibility.

Hardware Connection

Connect the Arduino UNO  development board to your computer using a USB cable.

Firmware Implementation

We are going to use EEPROM.h library to implement this task. In Arduino UNO, there is a separate 1KB EEPROM chip available.

Code

#include <EEPROM.h>


#define RESTART_COUNT_ADDR 0     // Address in EEPROM for restart count


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


  Serial.println("EEPROM-Based Microcontroller Restart Counter");


  // Increment and read the restart counter
  int restartCount;
  EEPROM.get(RESTART_COUNT_ADDR, restartCount);
  restartCount++;
  EEPROM.put(RESTART_COUNT_ADDR, restartCount);


  Serial.print("Microcontroller restarted ");
  Serial.print(restartCount);
  Serial.println(" times.");


  // Provide option to reset the counter
  Serial.println("Do you want to reset the counter. Press Y or N");
  while(1)
  {
    if (Serial.available()) {
    char input = Serial.read();
    if (input == 'Y' || input == 'y') {
      Serial.println("Resetting restart counter...");
      EEPROM.put(RESTART_COUNT_ADDR, 0);
      Serial.println("Restart counter reset. Please restart the microcontroller.");
      break;
    }
    else{
      Serial.println("Counter not resetted");
      break;
    }
   
  }
  }
}


void loop() {
  Serial.println("Doing some task.......");
  delay(5000);
}

Code Explanation

  • RESTART_COUNT_ADDR (macro)
    •  Constant 0 — the EEPROM address where the restart counter is stored.
  • setup()
    • Runs once at boot; starts Serial, prints a heading, loads the restart count from EEPROM, increments it, writes it back, then offers a one-time option to reset.
  • loop()
    • Periodic placeholder work: prints a message every 5 seconds..
  • EEPROM.get(address, variable)
    • Reads bytes from EEPROM starting at address and decodes them into a variable’s type (here: an int restart count).
  • EEPROM.put(address, variable)
    • Writes variable to EEPROM starting at address (type-aware); on AVR, it avoids rewriting bytes that already match, reducing wear.

Precautions

  • Be careful while writing to the EEPROM, as it has limited write cycles.
  • Writing time is 3.3ms per byte; consider this while writing your code.

Output

Video