1 Nov 2013 shimniok   » (Journeyer)

AVR Watchdog as Sleep Delay

Use the AVR Watchdog Timer as a sleep delay. Put your ATtiny / ATmega to sleep and the Watchdog Timer will wake it up after a specified interval.

oh no, it's the glowing, blinking eyes of a chupacabra!
This is the technique I used for my lost R/C airplane model alarm. I also used it last night for my Halloween glowing, blinky eyes. Here's how.
Two sources of documentation are your friend. Your AVR's datasheet and App Note AVR132 [pdf], "Using the Enhanced Watchdog Timer". Without these documents you will miss the subtle differences between the Watchdog Timers on different devices.

The Watchdog Timer on newer AVR devices can be configured to either reset, fire an interrupt, or both, upon timeout of the Watchdog Timer. We want interrupt mode, only. Let's talk about implementing the specifics of the ATiny13A [datasheet.pdf] since that's what I've used so far.

Overview

You need a sleep function to put the microcontroller to sleep for a specified time period. The Watchdog Timer runs in interrupt mode so it only wakes up the sleeping microcontroller periodically. And an Interrupt Service Routine keeps track of elapsed time.

To enable interrupt mode and disable reset mode, you must:
  • Disable the WDT Always On fuse on your microcontroller
  • Within software, define a Watchdog Timer interrupt service routine (ISR)
  • Define an init routine to:
  • Disable interrupts
  • Set the Watchdog Change Enable bit and within 4 clock cycles...
  • Set the new Prescaler Select bits 
  • Set Watchdog Timer Interrupt Enable bit and unset Watchdog Enable (WDE) bit
  • Enable interrupts again
The bits to be set are all found in the Watchdog Timer Control Register (WDTCR).

Interrupt Mode

You disable reset mode by clearing the Watchdog Enable (WDE). Enable interrupt mode by setting the Watchdog Timer Iterrupt Enable bit (WDTIE).

WDT Prescaler

The Watchdog Timer's 128kHz internal oscillator can timeout anywhere from every 16ms to every 8 seconds by changing the Watchdog Prescale bits, WDP[3:0].

The ATtiny13A datasheet, table 8-2 lists the prescaler bits and their corresponding prescale values. I chose a /64 value, corresponding to 1 second, with bits WDP2 and WDP1 set. 

Watchdog Change Enable

To prevent accidentally disabling the Watchdog Timer, one must first set the Watchdog Change Enable (WDCE) bit and then make changes to WDE and/or WDP[3:0] within 4 clock cycles.

Code

You can find the full source here.

Please note that, to conserve battery power, I am running the clock at 150kHz scaled down from 9.6MHz. The slow clock will cause problems flashing the chip. In AVR Studio 4, I set the ISP frequency very low so I could continue to flash the chip using my JTAG ICE MkII or AVR Dragon. If you're using avrdude you might be able to use either -B or -i flags. Since originally posting this article I've also added a delay before slowing down the clock which hopefully alleviates the problem but I haven't personally tested it. If you have working solutions please post to the comments.

My WDT initialization is as follows.