1
\$\begingroup\$

AVR Watchdog timers. Is there any way to read the watchdog timer from within the code?

Intended use case: To get an approximate idea (very rough, +/- 1sec) of how long it has been since the watchdog timer was last reset. This would allow my code to guess at how long it's been asleep, without an external RTC or similar.

I've tried looking in the attiny85 datasheet, and not found it. Any ideas people?

\$\endgroup\$
4
\$\begingroup\$

Set the watchdog to 1s second, then set it in interrupt mode, when the interrupt happens the watchdog set itself again to Reset mode and then your code has to manually set it to interrupt mode, that way you can use the watchdog timer as a 1 second timer and the still have the watchdog functionally because if after the interrupt execution there is a one second window to set the watchdog to interrupt mode before the timer expires and reset the micro. I have use the watchdog this way in an attiny10

\$\endgroup\$
  • \$\begingroup\$ This is the most straightforward solution. Since the longest time you will be able to measure with the watchdog on a single sleep is 8 seconds anyway, this at most will mean you will wake up 8 times more often. You can make the code that runs on each wake be very very fast, just increment a seconds counter in a register, set WDIE, sleep. You can even probably put this code directly into the vector table to save a jump (assuming you don't need the USI vectors). \$\endgroup\$ – bigjosh Sep 2 '15 at 16:13
  • \$\begingroup\$ This is the best answer here I think. The vector table trick would be a clever showboat too :) \$\endgroup\$ – stefandz Sep 2 '15 at 18:04
1
\$\begingroup\$

From what I understand in the datasheet, the WDT reset is an ANDed signal from a set of divided 128kHz clocks run through the WDT prescaler, and as such is not stored in a register for you to read.

If this were me I would use my own timer which was reset each time the WDT was. I could then poll this to estimate the time elapsed since the last reset. This is more hardware-independent and so more portable.

\$\endgroup\$
  • \$\begingroup\$ Would not the sleep mode also put the timers to sleep? Or, aren't the timers bound to the cpu clock? \$\endgroup\$ – user2702772 Sep 2 '15 at 11:56
  • \$\begingroup\$ If you sleep in Idle mode then Timer1 remains running and can be used to wake the AVR if required, or be polled when some other interrupt wakes the AVR. See Section 7.1.1 of the datasheet. \$\endgroup\$ – stefandz Sep 2 '15 at 13:23
  • \$\begingroup\$ Even at the lowest possible power configuration running off a 128kHz RC clock, idle mode uses on the order of 50-100uA. Power down mode with Watchdog enabled only uses on the order of 3-9uA, so the Watchdog with powerdown is a much more power efficient then a normal timer in idle. \$\endgroup\$ – bigjosh Sep 2 '15 at 17:53
  • \$\begingroup\$ @bigjosh that may be the case, but it's not the question asked - it still doesn't allow you to know how long you have been asleep when woken by another interrupt source \$\endgroup\$ – stefandz Sep 2 '15 at 17:56
1
\$\begingroup\$

Note that I am not advocating this solution - only showing that I think it is possible. I think that Kvegaoro's answer is more practical and even likely to use less power for almost all real-life use cases.

I think you could do something like this...

  1. Set up watchdog interrupt only mode.
  2. Set up the prescaller to the maximum 8s delay.
  3. Start the Watchdog.
  4. Sleep.
  5. Wake due to some external INT other than the Watchdog.
  6. Stop the Watchdog immediately upon waking.
  7. In a loop, step though the prescaller values from highest to lowest.

    d. clear the Watchdog interrupt flag

    a. set the prescaler to the loop value.

    b. check to see if the Watchdog interrupt flag has become set.

    c. shift the bit from the previous test into a shift register.

At the end of all this, the shift register should now have the upper bits of the value inside the prescaller counter.

Note that I have not tested to see if changing the value of the prescaler will asynchronously update the value of WDIF even when the watchdog is not running, but based on this, my guess is that it does. Even if it does not, then this method can still work, you just need to create a watchdog interrupt handler that sets a flag somewhere indicating that it was called. Then just check this flag after each prescaler update to see if the interrupt fired.

If you can convince me that you have one of the unlikely use cases where this actually does make sense, then I'll spin up some code to hammer out the details!

\$\endgroup\$
  • \$\begingroup\$ This would solve my problem. It's a terrible idea, and there is no advantage I can see over Kvegaoro's solution. But it really does answer my question and is an awesome solution. I also think it would be hilarious to see this implemented. Can't justify it in any way though! \$\endgroup\$ – user2702772 Sep 3 '15 at 9:06
0
\$\begingroup\$

Watchdog timer is used to reset the microcontroller if it enters infinite loop. You can only enable WDT with prefered time or disable it. You cannot read the value of watchdog timer.

You could use normal Timer to wakeup you AVR from sleep mode when it overflows.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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