Arduino Watchdog Timer Tutorial with Example

In this guide, we will introduce you to Arduino watchdog timer. The ATmega328P chip is used to operate the Arduino UNO board. The Watchdog Timer on the ATmega328P is a crucial tool for helping the system recover from instances where the system hangs or freezes due to faults in the code or conditions caused by hardware difficulties. Let us discuss this briefly.

Arduino Watchdog Timer Tutorial with Example

Arduino Watchdog

As we mentioned before, the ATmega328P chip features a useful watchdog timer that helps in the prevention of system failures by resetting the system or calling an assigned function to the watchdog. The watchdog can be triggered as a reset or as an interrupt. In case of a watchdog interrupt, it can also work as a system timer.

A separate on-chip oscillator clocks the watchdog. The watchdog reset timer may be configured from 16ms to 8s using a Prescaler. Temperature and operating voltage affect the clock frequency generated by the on-chip oscillator, therefore expectations of consistency must be maintained to a minimum. As a result, the watchdog is less suited to time-sensitive duties.

The block diagram below shows the watchdog in ATmega328P:

Block Diagram of Arduino Watchdog
ATMega238P Watchdog Timer

Watchdog Timer Control Registers

The watchdog timer is managed by the WDTCSR register as shown below. All the bits except bit 7 (read only) are readable and writable. The watchdog timer with all the register and controls bits are shown below.

Bit76543210
(0x60)WDIFWDIEWDP3WDCEWDEWDP2WDP11WDP0WDTCSR
Read/WriteRR/WR/WR/WR/WR/WR/WR/W
Initial Value00000000

To find the time-out period, refer to the table below to set the WDP3, WDP2, WDP1 and WPD0 bits.

WDP3WDP2WDP1WDP0Oscillator CycleTime-out
00002K16ms
00014K32ms
00108K64ms
001116K0.125s
010032K0.25s
010164K0.5s
0110128K1s
0111256K2s
1000512K4s
10011024K8s
Watchdog Time-out Period

To configure the watchdog, follow the table below:

WDTON FuseWDEWDIEModeAction
100StopNo
101InterruptInterrupt
110System ResetSystem Reset
111Interrupt + System ResetInterrupt -> System Reset
0xxSystem ResetSystem Reset
Watchdog Configuration

Arduino Watchdog Interrupt Sketch

Open your Arduino IDE and go to File > New to open a new file. Copy the code given below in that file.

This sketch demonstrates the watchdog interrupt which toggles the onboard LED of Arduino that is connected with pin13.

// Title : Watchdog
// Author : Claus Kuehnel <ckuehnel@gmx.ch>
// Date : 2017-05-10
// Id : watchdog.ino
// Tested w/ : Arduino 1.8.0
//
// DISCLAIMER:
// The author is in no way responsible for any problems or damage caused by
// using this code. Use at your own risk.
//
// LICENSE:
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
// Definition of interrupt names
#include <avr/io.h>
// ISR interrupt service routine
#include <avr/interrupt.h>
#define wdt_reset() __asm__ __volatile__ ("wdr")
const int pLED = 13; // LED at Pin13
int idx;

// Install the interrupt routine for Watchdog Interrupt
ISR(WDT_vect)
{
flash();
}
void setup()
{
Serial.begin(9600);
pinMode(pLED, OUTPUT);
digitalWrite(pLED, LOW);
cli();
wdt_reset();
WDTCSR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1); // Set new prescaler = 128K cycles(~1 s)
sei();
Serial.print("WDTCSR: ");
Serial.println(WDTCSR, HEX);
Serial.println("Setup finished.");
}
void loop()
{
Serial.println(idx++); // do anything
delay(1500); // change argument to 1500 -> watchdog will be active
wdt_reset();
}
void flash()
{
static boolean output = HIGH;
digitalWrite(pLED, output);
output = !output;
}

How the Code Works?

Firstly, include the definition of the interrupt names and the ISR interrupt service routine.

#include <avr/io.h>
#include <avr/interrupt.h>

The watchdog reset is specified as an inline assembler statement by the macro wdt_reset(). This must be executed by the application before the configured watchdog period has ended.

#define wdt_reset() __asm__ __volatile__ ("wdr")

Create two variables. ‘pLED’ to hold the Arduino pin connected with the onboard LED and ‘idx’ will be incremented inside the main program.


const int pLED = 13; // LED at Pin13
int idx;

This is the interrupt service routine for the watchdog interrupt:

ISR(WDT_vect)
{
flash();
}

The flash() function is used to toggle the LED when an interrupt is triggered.

void flash()
{
static boolean output = HIGH;
digitalWrite(pLED, output);
output = !output;
}

Inside the setup() function, open the serial communication at the set baud rate. Configure the led pin as an output pin and set its value to LOW. Call the wdt_reset() function, to reset the watchdog timer. Next, an approximate time-out period of 1s is set by initializing the watchdog register WDTCSR according to the table given previously.

void setup()
{
Serial.begin(9600);
pinMode(pLED, OUTPUT);
digitalWrite(pLED, LOW);
cli();
wdt_reset();
WDTCSR |= (1<<WDCE) | (1<<WDE); // Start timed sequence
WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1); // Set new prescaler = 128K cycles(~1 s)
sei();
Serial.print("WDTCSR: ");
Serial.println(WDTCSR, HEX);
Serial.println("Setup finished.");
}

Inside the loop() function, we increment the variable ‘idx.’ Next, add a delay of 1500ms. As the watchdog reset can not occur during the watchdog period that we set, hence the watchdog triggers the interrupt that causes the onboard LED to toggle. After that, reset the timer watchdog timer again.

Note: If a delay less than the watchdog time-out (1 second in our case) was set, then the LED would not have toggled.

void loop()
{
Serial.println(idx++); // do anything
delay(1500); // change argument to 1500 -> watchdog will be active
wdt_reset();
}

Demonstration

To see the demonstration of the above code, upload the code to Arduino. But, before uploading code, make sure to select the Arduino board from Tools > Board and also select the correct COM port to which the Arduino board is connected from Tools > Port.

select Arduino uno

Once the code is uploaded to Arduino, open your serial monitor and set its baud rate.

Arduino Watchdog Serial Monitor demo

You may also like to read:

Leave a Comment