Time between 2 impulses with lowest power (watchdog, external pin interrupts)

Hello,
I am looking to minimize the power consumption while measuring the time between 2 push on a button.

I plan to do the following:

  • after startup, arduino goes in SLEEP_MODE_PWR_DOWN (everything disabled)
  • Only a pin interrupt can wake it at this point
  • if this pin interrupt occurs, watchdog timer is started as well as a 1ms base timer to measure time elapsed between 2 pin interrupts > I can't use millis() as timers are disabled in SLEEP_MODE_PWR_DOWN mode. What option could I have to retrieve a timestamp in ms? I thought on using another timer (2) and use the overflow interupt, but this will end up with the same problem...

After this, there are 2 choices:

  • either a new pin interrupt occurs > depending on how many times the watchdog time occured + the 1ms timer occured > new timestamp is given and I have the time elapsed between the last press
  • if after 10 watchdog interrupts, no new button interrupts > device goes back into initial state again (SLEEP_MODE_POWR_DOWN)

My only problem is that I can't find how to retrieve a valid timestamp. I have the following idea, but didn't try it yet:
Is it possible to:

  • use SLEEP_MODE_PWR_SAVE or SLEEP_MODE_EXT_STANDBY instead of SLEEP_MODE_PWR_DOWN while I need a time base
  • and use timer2 with an external clock from 32kHz + prescaler from 32 (which will generate an interrupt each 1024ms)

Is it possible to somehow remap the millis function to use timer 2 instead of 0 ? Or am I better just using timer 2?
Are there other approach to solve this problem or to minimize further the consumption?

Thanks for your insight :wink:

An interesting question.
If the processor is asleep, the timekeeping has to be maintained by some other component...
You can’t use millis() etc, as they are dependent o. the processor.
You could however use a partial power down mode to keep a timer running, or as mentioned an external clock source to keep track of the elapsed time.

A combination if the above could see the cpu running at 32Khz, and all peripherals turned off (except the timers), then click back up full speed when needed.

ADDED: You could use a WDT event to count slow ticks when the cpu is ‘off’, and then keep track of the count when your next pulse comes in.

If you have to time something (and you don't want an external RTC or other timer) then you must choose a sleep mode which doesn't turn off the timers. That's the solution for the 'lowest power mode which has this capability'.

Thanks for your answers.

I will use the following strategy:

  • if button is pushed > wake-up (interrupt) > Go in SLEEP_MODE_PWR_SAVE so that timer2 is active (1ms timebase from 32kHz clock)
  • maintain a ms counter
  • If button is pushed again > check the time difference with the previous time (timer2 reg)
  • if after a timeout from 5min (processed from timer2 value) no button is pushed > go back in SLEEP_MODE_PWR_DOWN which will stop timer2. System is ready for next operation.

That way, the system is only active when waking up (either from pin interrupt or from timer2 and will allways sleep.

Optimisation: enable watchdog when waiting for next wake-up, to track time between 2 wake-up (but this is not needed for my needs)