Example 8

Back to Arduino Interrupts

#include <avr/wdt.h>      // Watchdog timer
 
const byte LED = 13;
const byte DURATION = WDTO_500MS;

uint8_t led = LOW;
ISR (WDT_vect) { // ISR
    // The datasheet says we should not set WDIE from within this ISR, but we are going to ignore that
    wdt_setup(DURATION);
    digitalWrite(LED, led);
    led ^= (HIGH^LOW);
}

void handleOtherStuff() {
    delay(250);
}

void wdt_setup(uint8_t duration)
{
    // We assume interrupts are disabled for the duration of this routine
    wdt_reset(); // make sure the wdt does not expire while we are configuring it
    uint8_t v1 = (1<<WDCE)  // set the Watchdog Change Enable bit (HW will clear this bit in 4 cycles)
               | (1<< WDE)  // you have to set WDE in order to clear it in the next instruction
               | (1<<WDIF); // clear the Watchdog Interrupt Flag by writing '1' to the bit

    uint8_t v2 = (0<< WDE)  // clear the Watchdog Reset Enable (we don't want to reset the chip when the watchdog expires)
               | (1<<WDIE)  // set Watchdog Interrupt Enable           
               |  duration&0x7
               | ((duration&0x8)<<2);
    MCUSR = 0; // specifically, clear the WDRF bit
    // These next two writes have to happen within 4 cycles
    WDTCSR = v1;
    WDTCSR = v2;           
}

void setup() {
    wdt_disable();
  
    // configure the pins
    pinMode(LED, OUTPUT);

    noInterrupts();
    wdt_setup(DURATION);
    interrupts();
}

void loop() {
    handleOtherStuff();
} 

In this example, we use the watch dog timer to blink the LED at 1 Hz.

Leave a Reply

Your email address will not be published. Required fields are marked *