Implementation Question: Really robust multiple countdown timers

Hi All,

I am currently working on a project and wanted to get some advice on the best type of code implementation.

Use case:

  • Customer selects time period they want in hours (1, 3, 6, 9, 12, 24etc)
  • Customer chooses device they want to use this on (8-16 devices)
  • Relay switches on for device selected and countdown starts
  • Relay switches off when countdown (hours) are over
  • Multiple customers can use multiple devices at the same time with different length timers

Important features:

  • Timers must be robust and accurate (~1min in 24hours)
  • Timers must survive reboot/power outage and continue counting down
  • Have ability to survive power outage/reset and continue

I have a basic working implementation with an Uno, a coin acceptor to add credits of hours, a switch to select the device and a single relay. I am currently doing the timer by taking the Millis() when the button is pressed, creating FinishTime in Millis by adding on the hours the user selected and then checking in the loop if the current Millis() is between these 2 numbers (then relay ON, otherwise OFF).

But this approach will not survive resets and is probably not scalable to 8+ concurrent timers. I also need to be able to handle new customers setting new timers (via interrupt from Coin acceptor pulse) and displaying things on LCD at the same time as not compromising the ongoing timers. I am a bit concerned about writing too much to the EEPROM so would be happy to write the countdown state/time remaining maybe every minute?

I have seen lots of different implementations of timers but they all tend to be counting up, using Delays or not working for multiple timers in parallel. I could use a RTC as well and set actual finish times, but concerned this is another thing to go wrong and could cause incorrect timing if it failed.

Priority here is the non-failure of the timers and would be willing to trade off some accuracy (in the customers favour) to achieve this.

Really appreciate any help or advice anyone can give in terms of code implementation, approach or libraries.

Many thanks
Chris

A Real Time Clock seems like an obvious part of any system that needs to keep accurate time for more than an hour.

If you save the start and finish times in the EEPROM memory (or perhaps on an SD Card) they would survive a power outage.

However if the Arduino is turned off the things it controls are likely also to be switched off until it restarts and figures out which items should on and which should be off.

Having an uninterruptible power supply would also seem like an obvious part of any system where reliability is important.

...R

Hi Robin,

Really appreciate your reply.

I had thought about the RTC approach but was concerned for a few reasons:

  • Need to configure the time initially (makes manufacture/setup more challenging)
  • Handling of timezones etc which can cause time to be out of sync with reality
  • I actually don't care about the ending "time" itself, just that the relay has been open for the total elapsed time requested. So if customer wanted 4 hours of time and power is out for 1 hour (including relays) they should still get their full 4 hours not just stopping after 4 hours from the start time. I just want to countdown efficiently to zero with multiple timers in parallel
  • Another component to integrate and possibly go wrong or battery run out without knowing
  • I don't need mega accuracy to the second but within a minutes over 24hours would be great.

Maybe this is still the best approach and I am just missing something. I just want to countdown efficiently to zero with multiple timers in parallel.

Totally take your point on the power backup but again I want something robust that doesn't rely on that. There are plenty of arcade/washing machine/massage chair timer boards available that work without RTC but have other limitations for my use case in terms of user interface meaning I cant use them.

Thanks again for your help. Chris.

You don't ever have to set the RTC if you don't care about its relationship to the actual time.

Just make sure it is battery backed up and make all timing relative. No one will know.

a7

mypi-home:

  • I actually don’t care about the ending “time” itself, just that the relay has been open for the total elapsed time requested. So if customer wanted 4 hours of time and power is out for 1 hour (including relays) they should still get their full 4 hours not just stopping after 4 hours from the start time.

I think that means that if a 4-hour time slot is selected and if the Arduino stops after 1 hour then whenever the Arduino restarts it should give a further 3 hours to make 4 in total.

If that is correct it is very different from what I had in mind.

To achieve that I believe either of two conditions are required - {A} the Arduino has an uninterruptible power supply and the ability to measure how long the power outage lasts (neither of which is difficult).

OR {B} the Arduino records to EEPROM memory the amount of time still due for each task at the moment the power fails. That is not so easy to implement and it also requires that the Arduino can keep operating for (say) 30 seconds after the power fails.

My preference would be for option A

Another thing to keep in mind is whether it would safe for the Arduino to restart appliances immediately after a power outage - somebody might get hurt if they weren’t expecting a restart.

…R

Perhaps one way to keep track of the elapsed time that would take into account the loss of AC power is to get time from the AC line. Use the AC current to generate a 50/60 Hz interrupt to keep track of time. The timer will stop if AC power is lost. You would need a battery backup for the Arduino but you would not need an RTC.

MCP7940N RTC provides a small SRAM with battery backup as well as time stamps for power loss and restore.

However any SRAM with a battery backup or a FRAM would be enough for this of you don't need the real time.

If it were me, I would accept a coin and credit an account with 100 (or whatever) 'time units' and store the account balance in eeprom. Then every time milliseconds gets up to whatever a 'time unit' is, I would grab each account from eeprom and decrement one 'time unit' and store the account balance in eeprom. Whenever an account reaches zero, I would shut off that account.

I am not imaginative enough to think of an alternative to storing account balances in eeprom in order to span power outages without battery backup.

edit - I can think of one alternative that uses more eeprom but fewer updates. Keep a running count of 'time units'. Every time enough milliseconds has passed, increment the running 'time unit' count and save it to eeprom. When a coin is accepted, store the account running 'time unit' ending count in eeprom. When an account is greater than its end time, shut it off. Now you have an eeprom location for each account plus an eeprom location for running 'time unit' count but the accounts are only updated once at coin acceptance and the running time is updated every 'time unit'. (instead of updating every account every time unit)

second edit - perhaps the first eeprom address is the location of the running 'time unit' count and every time the running count is greater than 100,000 and all accounts are offline, you could shift the first eeprom location a few bits higher and save the value = 1 and set the previous location to zero. It could take a very long time before you have shifted the starting location so high that there is not enough room to save all the accounts in the remaining eeprom. Then replace the arduino with a fresh one. Maybe turn on an LED when 80% of eeprom is used up. (also note that the running total should not be incremented if no accounts are active)