# Arduino |Automatically Save Variables to EEPROM on Power-Down

A recurring challenge for Arduino projects is that variables are volatile and will be lost completely unless previously stored to some sort of non-volatile storage such as de inbuilt EEPROM. This article shows a minimalistic approach to detect sudden loss of power and automatically store a variable to an EEPROM adress.

First I should mention that this approach of course also works for other type of storage devices, such an external SD-Card. The simple solution I used in this 12V application is a 2-stage voltage regulator set-up and a power-sense input tied to an interrupt. The first stage gets the input voltage down to 9V. A voltage devider on the 9V rail supplies a steady high signal to PIN 3 of the Arduino Nano as long as a power source is connected to the circuit. As soon as this sense-input falls low, an Interrupt Service Routine (ISR) is triggered that stores the variable to a pre-defined adress of the EEPROM. The second stage consists out of two 7805 type voltage regulators. One for the Arduino Nano and one for all periphial devices such as the LC-Display. The Arduinos 5 Volt supply voltage is tied to a 1F supercapacitor. This guarantees that the Arduino has enough power available to safely detect the missing supply voltage on the 9V rail and store the example variable to the EEPROM.

The whole Setup looks something like this:

Crude test setup with 1F supercapacitor

 #include <EEPROM.h> // Some Variable int SomeVariable; // Pin to be used as power-down sense int PWR_DWN_PIN = 3; // The EEPROM address to be used int EE_ADDR = 10; void setup() {  // Retrieve last stored value of SomeVariable from EEPROM  EEPROM.get(EE_ADDR, SomeVariable);  // Set-up Interrupt Service Routine  attachInterrupt(digitalPinToInterrupt(PWR_DWN_PIN), PWR_DWN_ISR,FALLING); } void loop() {  // Do something cool  } // This Interrupt Service Routine will get called on power-down void PWR_DWN_ISR () {    // Push SomeVariable to the EEPROM    EEPROM.put(EE_ADDR, SomeVariable);     } 

This Setup works very well. How long the supercapacitor can power the Arduino and whether or not you even need a separate supply rail for periphials depends on the current demand of your circuit. So heres some math.

The charge of a capacitor is defined as follows:

$Q = It$

Q = charge of capacitor in Coulomb
I = Current in Amps
t = time in Seconds

So if we re-arrange the equation we could wrongly assume that if we divide Q by the current demand of our device, we will get the expected runtime in seconds. But we need to take into consideration that the Arduino does not work all the way down to 0 Volts. We need to define a lower voltage limit and divide the change of charge by the current draw of your device. But how do we get Q to begin with? The charge of a capacitor Q can also be expressed by the following Formula:

$Q = CV$

V = Voltage in Volts

So we can combine the two formulas in a way that we can calculate the time (t) if we know the capacitance of the supercapacitor, the expected current draw of the device and the maximum permissible change in voltage.

$t = \frac{\Delta VC}{I}$

So for my example I am allowing the 5 Volts to drop to 4 Volts, I am assuming 100 mA max. current and the supercap has a capacity of exactly 1F.

$t = \frac{(5V - 4V) 1}{0.1A} = 10 s$

10 seconds should be plenty of time to store a variable (or a few more) to the EEPROM. This approach works very well so far. A possible improvement, if needed, migth be to implement a change interrupt trigger instead of a falling edge trigger and re-initialize periphials on power-up if needed (e.g. LCD). This becomes necessary if power is reconnected during a time where the Arduino is still running but periphials where already shut-down. In that case they need a clean initialization before they will function properly.

## One thought on “Arduino |Automatically Save Variables to EEPROM on Power-Down”

1. Hi I contemplated doing this for my laser cutter. I wanted to save the height above the bed using a rotary encoder . I ended up using eeprom update to save the new height only when it changed. Works well and reloads the data after s cold reset.