2

I'm building a digital watch just like in this post, except I'm using an ATTiny84. However, the ATTiny84 doesn't have an asynchronous Timer2 like the ATMega328 and does not have a power save mode, so it cannot wake up from the Timer2 interrupt as is suggested in that post.

I need to increment my 'seconds' counter every second, and I need to do it precisely so I don't lose/gain time (so I can't use the watchdog timer which, as I understand, does not use the crystal oscillator but rather its own imprecise clock). I was planning on just keeping the CPU on and using an external crystal, but it seems that that takes a lot of power (~3mA). Even with the SLEEP_MODE_IDLE, I could only get the current draw down to around (~1.2mA).

Like Nick Gammon suggested in that post, I feel like the real solution is to sleep when not changing the counter. Is there any way to wake up after a precise amount of time in the POWER_DOWN or STAND_BY modes?

1 Answer 1

3

Is there any way to wake up after a precise amount of time in the POWER_DOWN or STAND_BY modes?

I'm afraid not. You will have to use a timer. Since the ATtiny84 does not have an asynchronous timer, you will have to keep your timer clocked. This means the clkIO clock domain has to stay active. Now, take a look at the table “Active Clock Domains and Wake-up Sources in Different Sleep Modes”, on page 33 of the ATtiny84 datasheet. It shown that “Idle” is the only sleep mode that keeps this clock domain active.

Even with the SLEEP_MODE_IDLE, I could only get the current draw down to around (~1.2mA).

There are ways to bring this down. First, there is a collection of functions named power_*_disable() in the avr-libc. You can use these to power down every single peripheral except the one timer that you will be using.

Most importantly, you can save power by reducing the clock speed. Since these devices have extremely little leakage current, the current draw is roughly proportional to the clock frequency. You can then achieve huge power savings by drastically reducing that frequency. Obviously, your processing power will also suffer, but this may not be an issue for a simple binary clock.

I think the best option for you is to clock your ATtiny84 off a 32.768 kHz watch crystal. See the section 6.2.4 – Low-Frequency Crystal Oscillator in the datasheet. These crystals can be very accurate, as they are specifically designed for time keeping. And the frequency is so low that the current draw from the MCU will likely be negligible compared to whatever other components are in your clock.

Edit: answering the question in the comment.

Wouldn't waking from idle still use the watchdog timer though? Or is there a way to wake up based on the 32.768 kHz crystal?

As the watchdog timer is way too inaccurate, it is of no use to you. Instead, you would use either Timer 0 or Timer 1, and configure it to deliver an interrupt every 32,768 CPU cycles. This interrupt will be your 1 Hz wakeup source.

You can do this with either timer, in either CTC or fast PWM mode. You have to configure the prescaler and the TOP value such that

prescaler_factor × (TOP + 1) = 32,768

Then, enable the relevant interrupt, and define the corresponding ISR that will advance your clock by one second.

2
  • Thanks, it looks like the power used by a 32.768 kHz crystal is low enough for me if running in idle. Wouldn't waking from idle still use the watchdog timer though? Or is there a way to wake up based on the 32.768 kHz crystal?
    – Anubhav
    May 6, 2020 at 15:36
  • @AnubhavSrivastava: see expanded answer. May 6, 2020 at 17:56

Your Answer

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

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