This is an example of what I am talking about:
#include <avr/sleep.h>
volatile unsigned long ms;
ISR (TIMER2_COMPA_vect)
{
++ms;
digitalWrite (9, !digitalRead (9));
} // end of TIMER2_COMPA_vect
void setup () {
// reset Timer 2
TCCR2A = 0;
TCCR2B = 0;
// Timer 2 - gives us our 1 mS counting interval
// 16 MHz clock (62.5 nS per tick) - prescaled by 128
// counter increments every 8 uS.
// So we count 125 of them, giving exactly 1000 uS (1 mS)
TCCR2A = _BV (WGM21) ; // CTC mode
OCR2A = 124; // count up to 125 (zero relative!!!!)
// Timer 2 - interrupt on match (ie. every 1 mS)
TIMSK2 = _BV (OCIE2A); // enable Timer2 Interrupt
TCNT2 = 0;
// Reset prescalers
GTCCR = _BV (PSRASY); // reset prescaler now
// start Timer 2
TCCR2B = _BV (CS20) | _BV (CS22) ; // prescaler of 128
pinMode (9, OUTPUT);
} // end of setup
void loop () {
set_sleep_mode (SLEEP_MODE_PWR_SAVE);
sleep_enable();
sleep_cpu ();
sleep_disable ();
// should be here after 1 mS
} // end of loop
This uses an average of around 1.7 mA. However it behaves in a slightly strange way. According to my calculations it should wake up (and leave "loop") every 1 mS, but it actually does it every 2 mS.
With the sleep_cpu() line commented out, it does it every 1 mS. So somehow sleep is causing the clock to run slower. I'm not sure why at this stage. However even as it is, it shows how you can be in low power mode most of the time, but still count elapsed time accurately.