Save to EEPROM when poweroff

Hello. I'm designing a musical sequencer which can store some values from potentiometers to the EEPROM when I press the "save" button.
Now let's suppose I'm in the middle of a performance, and someone accidentaly disconnects my device... and when I connect it again, I lost everything.
Would it be possible that when the power goes off, I can hold the input voltage for a few ms and trigger an interrupt so it saves everything to EEPROM before it shuts down? The amount to save in the memory is 24 bytes
thanks

Absolutely, have a capacitor in the supply large enough to give you enough time to save the data, and monitor the supply voltage using the ADC - when the supply is cut off, the ADC detects this and you can enter the required function.

There's nothing to say you couldn't use a digital input either, and use external interrupts if you don't wish to poll an ADC reading or even poll a digital input. Although the ADC would be the best way to go about it, IMO - as you then have a continuous monitoring capability.

Most good designs should have the capacity to monitor it's voltage rails and have enough energy reserve to ride out brown-outs etc.

A few words of warning following on from that last answer:

  1. Do not attempt to write to EEPROM from inside an interrupt routine. Bad things could happen (your program may crash and not write to EEPROM)

  2. Writing to EEPROM is quite a power hungry operation - you’ll need to have a HUGE capacitor to do it reliably.

A far better option would be to use a small rechargeable battery. Use a similar system to monitor when the input power is disconnected, and when it is switch over to battery power. You’ll want a nice little trickle charge circuit to keep it topped up, and a way of switching between power sources (check out the Arduino UNO schematics to see how it switches between barrel jack and USB - it’s rather neat). Then, when you have completed your write to EEPROM you can cut off the battery power (Hint: a P-channel MOSFET / NPN pair make a good power switch).

majenko is right.
Writing to EEPROM when the power is going down could cause a few problems. For example half-written or half-cleared bytes. So you need a checksum and two sets of data in EEPROM.
It is much easier to use a battery backup, or to write it very often to EEPROM. You have to calculate how often you write it, so the EEPROM doesn't wear out in a few weeks.

capicoso:
Would it be possible that when the power goes off, I can hold the input voltage for a few ms and trigger an interrupt so it saves everything to EEPROM before it shuts down?

Maybe...but it's very risky. EEPROMs need a lot of power to write.

Why do you have to press a special "save" button? Why not just save the values every time the potentiometers have moved (and stabilized)?

I now predict there will be a bunch of replies pointing out that EEPROM wears out. That's true, but only after a very, very long time. If this is truly important then just get a new Arduino every six months or implement a "wear levelling" scheme.

ie. Write to the EEPROM sequentially (wrapping around at 512 bytes) and add a checksum+counter to the data. When you boot up you look through the EEPROM for the data with the highest counter value and a valid checksum.

You also want to avoid re-saving a value that hasn't changed:

  if (EEPROM.read (addr) != data)
    EEPROM.write (addr, data) ;

Since that can be a common case and you avoid wearing that location unnecessarily.
100,000 writes is the spec I believe, which rules out saving every few seconds, but
saving after every human interaction is plausible.

Thanks.

fungus:

capicoso:
Would it be possible that when the power goes off, I can hold the input voltage for a few ms and trigger an interrupt so it saves everything to EEPROM before it shuts down?

Maybe...but it's very risky. EEPROMs need a lot of power to write.

Why do you have to press a special "save" button? Why not just save the values every time the potentiometers have moved (and stabilized)?

I now predict there will be a bunch of replies pointing out that EEPROM wears out. That's true, but only after a very, very long time. If this is truly important then just get a new Arduino every six months or implement a "wear levelling" scheme.

ie. Write to the EEPROM sequentially (wrapping around at 512 bytes) and add a checksum+counter to the data. When you boot up you look through the EEPROM for the data with the highest counter value and a valid checksum.

Well, that may be a good one. I have a save and load button because it has various memory banks, so if you load preset 1, and you changed it but you don't want to save it, you just don't press save... If it's always saving automatically it'll overwrite the bank. But i could make an extra bank so it saves there in realtime like you said, but without overwriting the original preset unless you press the save button.
The only thing I would have to test is the write time. It's a sequencer, so it's always running(unless it's stopped) and time is an important factor. When I write the whole memory bank(about 24 bytes) It takes a while, a few ms. I didn't measure it, but it's not good to write in the middle of a performance, it feels glitchy. In the arduino reference it says it takes 3,3ms for a write cycle. Does this mean that writing 24 bytes would take 79,2ms?
This is the sequencer :

It's driving my modular synth.
So, as you see, it's a continous sequence, and jumps, glitches, stops or anything that messes up the timing(timing doesn't need to be so tight tough) aren't allowed. I prefer to save the sequence when I finished something and it's stopped. I wonder if constantly saving the movement of a potentiometer would affect the performance... i'll have to try
thanks

MarkT:
You also want to avoid re-saving a value that hasn't changed:

  if (EEPROM.read (addr) != data)

EEPROM.write (addr, data) ;



Since that can be a common case and you avoid wearing that location unnecessarily.
100,000 writes is the spec I believe, which rules out saving every few seconds, but
saving after every human interaction is plausible.

Yeah I was reading some post about the EEPROM life time and someone suggested the same. I'll implement it, it's smart.
thanks

capicoso:
Well, that may be a good one. I have a save and load button because it has various memory banks, so if you load preset 1, and you changed it but you don't want to save it, you just don't press save... If it's always saving automatically it'll overwrite the bank. But i could make an extra bank so it saves there in realtime like you said, but without overwriting the original preset unless you press the save button.

Sounds good...

capicoso:
The only thing I would have to test is the write time. It's a sequencer, so it's always running(unless it's stopped) and time is an important factor. When I write the whole memory bank(about 24 bytes) It takes a while, a few ms. I didn't measure it, but it's not good to write in the middle of a performance, it feels glitchy. In the arduino reference it says it takes 3,3ms for a write cycle. Does this mean that writing 24 bytes would take 79,2ms?

A write takes a couple of milliseconds, yes, but you can set it going then go away and do something else. The chip lets you know when the write is complete (the "EEPROM Ready" bit will go from 0 to 1 in the EECR register).

Writing to EEPROM is easy. Set the address, set the data then do a 'write' command. See the "AVR memories" section of the datasheet.