4

I'm using the onboard software watchdog facility of an Atmega328 like documented here.
My purpose is to limit to 2 seconds the execution of a portion of code that could lead to endless computation.

This is the pseudo-code scheme:

enable watchdog (2 seconds)
run may-be-endless code
clear watchdog
run the rest

The rest of the code should be run if the may-be-endless code manage to run in the given amount of time, otherwise the whole program must be restarted.

This is the Arduino code I loaded into the board:

#include <avr/wdt.h>

void setup() {

  Serial.begin(9600);

  Serial.println("Started");

  wdt_enable(WDTO_2S);
  Serial.println("watchdog ON");

  wdt_reset();
  Serial.println("watchdog OFF");

}

void loop(){
  Serial.println("loop...");
  delay(1000);
}

At this point, the expected output should be an endless printing of loop... messages, after the ones in the setup (Started, watchdog ON/OFF).

Surprisingly, what I get instead is this:

Started
watchdog ON
watchdog OFF
loop...
loop...
loop...
Started
watchdog ON
watchdog OFF
loop...
loop...
loop...
Started
watchdog ON
watchdog OFF
loop...
loop...
[...]

Appartently the watchdog is being set but can't be cleared. How come?

etuardu
  • 397
  • 3
  • 7
  • 14

2 Answers2

7
wdt_reset() 

does not disable the watchdog, it merely resets its timer, delaying the expiration.

You probably want

wdt_disable()

However, your overall approach may not be the most sound - letting the watchdog expire can be clever, but it is also fairly heavy-handed compared to approaches such as using a normal timer interrupt or having your code limit itself. Normally the watchdog is for unanticipated errors.

Chris Stratton
  • 33,282
  • 3
  • 43
  • 89
  • Thank you... I feel ashamed that I didn't check `wdt_disable` before, it was that easy. I was distracted by several how-tos that I read which stated that `wdt_reset` was the way, and also the documentation was a little bit ambiguos to me. – etuardu Apr 15 '13 at 15:44
5

To disable the watchdog timer call wdt_disable(). All wdt_reset() does is reset the watchdog timeout, which in your case is redundant: you just turn it on two lines above. wdt_reset() does not turn the watchdog timer off (contrary your serial output).

angelatlarge
  • 3,611
  • 22
  • 37