Saving to EEPROM on power-out

Hi everybody,

Is there a good strategy for saving a few key variables to EEPROM when you have a sudden power outage? Maybe a cap that can hold the board on long enough to get a few bytes written?

I have a project that runs two metering pumps and keeps track of the liquid level in a few different containers. Whenever there is an interruption in power, the program can reset and take care of itself to get back into action, but it loses the values that hold the current liquid levels. I don't want to save them every time they are modified because that would wear out my EEPROM. But it would be nice if something could give me a warning that the power died and then give me the few milliseconds I need to save the values before the board dies.

1 Like

You need to get the power out event to trigger an interrupt. Detecting it is tricky. One way is to feed the power through a diode with a large capacitor on the arduino end. Then use a voltage comparator on the input end to detect when the power is removed. The size of capacitor used depends on how much current your circuit draws.

We have a suggested circuit and additional notes here:

http://ruggedcircuits.com/html/circuit__13.html

-- The QuadRAM shield: add 512 kilobytes of external RAM to your Arduino Mega/Mega2560

To expand on Mike’s suggestion, here is a schematic. It assumes that you’re running the Arduino from a wall wart or some other external power supply. The capacitor stores enough charge to power the Arduino for a few tens or hundreds of milliseconds, and the diode allows you to power output devices (e.g. relays, motors, LCD backlights etc.) from the external supply without draining the capacitor when the power goes off. The voltage divider should be designed to produce no more than 5v on the Arduino pin when external power is applied. You can connect the top end of the voltage divider either to the input voltage (if it is free from transients and has a low ripple voltage), or to the Arduino Vin.

If your sketch has a fast enough main loop compared to how long the charge in the capacitor lasts, you can poll the analog input in that loop to detect when the voltage across the capacitor has dropped to a level that indicates power failure, and write to EEPROM when that happens. Otherwise, you could use the analog comparator to generate an interrupt.

An Arduino Uno that is driving no significant load takes around 45mA, so if your power supply is 9v and you detect power outage at 8v across the capacitor, with a 1000uF capacitor you have around 40ms before the voltage has dropped to 6v. If you are running from 12v and detect power outage at 10v, you have twice as much time.

Why not save the values every 10 secods or so? If you are concerned about wearing the EEProm out, why not wear level it? A very simple wear leveler (to give you an idea) is here:

http://blog.blinkenlight.net/experiments/counting-resets/wear-leveling/

dc42: To expand on Mike's suggestion, here is a schematic. It assumes that you're running the Arduino from a wall wart or some other external power supply. The capacitor stores enough charge to power the Arduino for a few tens or hundreds of milliseconds, and the diode allows you to power output devices (e.g. relays, motors, LCD backlights etc.) from the external supply without draining the capacitor when the power goes off. The voltage divider should be designed to produce no more than 5v on the Arduino pin when external power is applied. You can connect the top end of the voltage divider either to the input voltage (if it is free from transients and has a low ripple voltage), or to the Arduino Vin.

If your sketch has a fast enough main loop compared to how long the charge in the capacitor lasts, you can poll the analog input in that loop to detect when the voltage across the capacitor has dropped to a level that indicates power failure, and write to EEPROM when that happens. Otherwise, you could use the analog comparator to generate an interrupt.

An Arduino Uno that is driving no significant load takes around 45mA, so if your power supply is 9v and you detect power outage at 8v across the capacitor, with a 1000uF capacitor you have around 40ms before the voltage has dropped to 6v. If you are running from 12v and detect power outage at 10v, you have twice as much time.

Thankyou, this is exactly what I was looking for.

I can fire an interrupt on the analog comparator that will get everything together and write it to the EEPROM. I think I can condense the data into just a few bytes so I shouldn't need long.

Is there any sin in using a larger cap to get more time, or is there a limit to what you can do there. Could a similar approach be used to keep the board on for as long as a few seconds in hopes that power would be quickly restored and the reset would be unnecessary? Perhaps the interrupt could trigger a sleep mode.

Delta_G: Is there any sin in using a larger cap to get more time, or is there a limit to what you can do there. Could a similar approach be used to keep the board on for as long as a few seconds in hopes that power would be quickly restored and the reset would be unnecessary? Perhaps the interrupt could trigger a sleep mode.

You can certainly use a larger capacitor to get more time. If you are using your own atmega-based hardware instead of an Arduino, you can also get more time by reducing the current consumption, for example by omitting the serial to USB converter and by running the mcu at a lower frequency. You could certainly use sleep mode to extend the time, but at some point you will need to have the mcu wake up from sleep mode to check whether the power is still dropping and write to the EEPROM if it is.

Why isn’t the USB to serial powered only from the USB? The only time it needs to work is when the USB is connected…

Because it is connected to the rest of the circuit and so having signals going into an unpowerd chip is a good way of damaging it.

Have you considered using a battery backed RAM? Just throwing another option out here

If it is only a very limited set of variables a RTC chip could also do the trick.

Grumpy_Mike: Because it is connected to the rest of the circuit and so having signals going into an unpowerd chip is a good way of damaging it.

The isolation resistors would do a good job of protecting it.

If a digital input is set HIGH and the voltage is allowed to diminish, it triggers LOW at 1.1V? And if set LOW and the voltage allowed to increase, it triggers HIGH at 3.3V? Do I have those right? And they read fast. And

Arduino (Atmega) pins default to inputs, so they don't need to be explicitly declared as inputs with pinMode(). Pins configured as inputs are said to be in a high-impedance state. One way of explaining this is that input pins make extremely small demands on the circuit that they are sampling, say equivalent to a series resistor of 100 megohm in front of the pin. This means that it takes very little current to move the input pin from one state to another, and can make the pins useful for such tasks as implementing a capacitive touch sensor, reading an LED as a photodiode, or reading an analog sensor with a scheme such as RCTime.

If you put 300 megohm between 5V and the pin, would that read as 1.25V? But the line has to see more than the trigger state for HIGH to not read LOW. So what if you connected to the same pin a small resistor, a small cap and ground the before reading the pin, you did a HIGH output to load the cap and then switched to input... something like when reading a led? I think that the right RC should power the line enough to start the read as HIGH and that until Vcc falls enough the pin should read HIGH at least with the right resistor between Vcc and the pin.

That should allow monitoring Vcc without using serial Rx or Tx.

BTW, how much backup can I get using a thin plastic jar inside a thick glass jar with electrodes and water.... and only feeding it 5V? Or maybe there's a way to get 5V using 2.5V caps? They don't add V in series do they?