1

I am making a counting device, and I would like to be ensure that the count is not lost if the power is lost. As I need to count to many millions I cannot use EEPROM writes as I will trash the nvm after ripping through the 100,000 max write cycles. I also need to ensure the count is accurate, so can't update 'every-so-often' either.

I want to write to EEPROM when the Arduino detects power down. I am reading on an Analogue input pin and am then planning on using a capacitor to hold the power on to complete the write. I have this set up but am having issues testing as I have found that when Ground is connected to GND pins and then when 5v is supplied to any I/O pin the device powers up. I have now tested a Nano and Uno and have found the same thing on both.

I have looked through the arduino site and tried looking for forums where this has been discussed, but to no avail.

Is this damaging to the Arduino if powered in this way? Does this pass the sanity check as a way of achieving my main objective of not loosing the count on power down?

thanks in advance :)

3
  • The name for it is "parasitic power" - it is a well-known phenomenon.
    – Nick Gammon
    Commented Sep 25, 2015 at 6:39
  • when 5v is supplied to any I/O pin the device powers up - why is this an issue anyway? How does this apply if the power is lost?
    – Nick Gammon
    Commented Sep 25, 2015 at 6:51
  • I wasn't sure if this was even an issue or not! I just wasn't expecting this to happen and wanted to know if I would damage the device. Thanks for your help
    – Dan Evans
    Commented Sep 28, 2015 at 7:22

4 Answers 4

3

A more sophisticated version of @MikaelPatel's techique is not to store the individual counts, but to store a derivative:

  1. Reserve a block of storage with (say) 8 counters. Each counter has as many bits as necessary to store the largest value - but see below for what "largest" means.
  2. Each time the count goes up, write into the next counter along (modulo the number of counters).
  3. But don't write the value of the counter, write the value divided by the number of counters - counter/8.
  4. Here's the trick: while that looks like you're losing precision, you're not - because the counter location is information too! In fact you're gaining size.

It's best shown with an example. For ease, I'll assume an 8-bit counter, and only 8 counters:

0000: 03 03 03 03 03 02 02 02

Assuming that everything started at 00, that means that it took 8 counts for them all to get to 01, a further 8 counts for them all to get to 02, and only 5 counts to get the first 5 to 03. That's a total of 8+8+5 or 21.

At boot time, look for where the number sequence goes down. That's your current buffer position for future updates, plus the information for the current value:

CurrentCount = [Smaller number] * [Number counters] + [Number of larger];

Once you've worked it out, keep the current value for incrementing, and the buffer pointer for where to store the next count.

Advantages:

A. You write as often as you would storing a counter - but in different locations, spreading the load.
B. Each location (8, 16 or 32 bits) can store a certain maximum - but the total maximum is a factor of Number of Counters larger than that!

Odometer manufacturers use this exact technique to store the current mileage in digital dashboards - they have a legal requirement to maintain the correct number. They only use 16-bit counters (which would overflow after 65,535 miles), but then they use 16 counters, for a total mileage maximum of over a million. Each location only gets written every 16 miles, and they don't need to use 32-bit locations.

0
1

I would suggest powering it from the 12V input and monitor the 12V with a power supply monitoring chip or circuit which will send an interrupt to your system when the voltage drops to whatever voltage you design it for. This can be accomplished with a few resistors and a comparator.

Your hold up time will be controlled by the amount of capacitance on the 12V side. When the interrupt is tripped write the value to EEPROM and then shut down.

The analog input is a good sounding idea but there is a lot of latency between the time the voltage starts to fail and is detected. The hardware interrupt will be much faster giving you more time to save your counter and the additional capacitance on the 12V side will give you a lot more time then back feeding through the GPIO pins..

1

A typical method of increasing the number of writes to EEPROM is to use a vector of counters instead of a single value. The counter value is written to the EEPROM vector in a cyclic fashion.

On startup the vector is searched for current counter value, i.e. the highest counter in the vector. The write index is restored by locating the lowest counter value.

The number of writes is increased with the length of the vector.

Please read more about this method here.

0

The arduino chips have clamping diodes on all the GPIO pins. So if the voltage on one of the pins is above Vcc (which is 0v is there is no power applied to the chip), the internal diode will 'redirect' this voltage to the Vcc line. This will damage the chip, is too much current is going through the clamping diodes.

Instead, connect the 5v signal via a large resistor (e.g. 100k) to the input pin.

Using a capacitor (plus diode to prevent backfeeding) will work. You just have to be careful if you have connected anything to an output pin that uses current. An led running at 20mA will drain a charged capacitor pretty quickly.

What I've done in the past is use the entire EEPROM space to store a single value. Just write every next value to a higher address. On powerup read the entire EEPROM till you find two adjacent address that don't contain successive numbers. Then you know where the last written value was, and you can read this last value, and continue writing the the address right after that one.

2
  • As you have mentioned, the caps are draining quickly. They need to need to be too big for the space I have available. I am now going to work on using the EEPROM in blocks. Thanks for you help
    – Dan Evans
    Commented Sep 28, 2015 at 7:25
  • Connect all external stuff, that uses power, via transistors. Also make sure signal outputs have resistors on them, as some ICs have clamping diodes, which would result in the external IC being power though the signal pin on the atmega if power is disconnected. Also make sure you have low voltage caps. The lower the maximum voltage the small a cap can be. Also you can parallel to smaller caps together to get double the capacity. I wouldn't dismiss the original idea too soon. But without some wiring diagram I can help you beyond the above hints.
    – Gerben
    Commented Sep 28, 2015 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.