DEV Community

Hedy
Hedy

Posted on

How do you implement fail-safes and watchdog timers in Arduino projects?

Implementing fail-safes and watchdog timers(What is a Watchdog?) in Arduino projects is crucial for reliability, especially in robotics, automation, and remote systems. Here's a clear guide on how to do both:

Image description

1. What Are Fail-safes and Watchdog Timers?

  • Fail-safe: A mechanism that puts the system into a safe state when things go wrong (e.g., stopping a motor if sensor input is lost).
  • Watchdog Timer (WDT): A timer that resets the microcontroller if the software hangs or crashes.

2. Using a Watchdog Timer (WDT)
On AVR-based Arduinos (Uno, Nano, Mega)
Step-by-Step:
1. Include the Watchdog library:

cpp

#include <avr/wdt.h>
Enter fullscreen mode Exit fullscreen mode

2. Enable the watchdog in setup():

cpp

void setup() {
  wdt_enable(WDTO_2S);  // Reset if no signal in 2 seconds
}
Enter fullscreen mode Exit fullscreen mode

3. Reset it regularly in loop():

cpp

void loop() {
  wdt_reset();  // Reset the timer
  // Your normal code here
}
Enter fullscreen mode Exit fullscreen mode

If wdt_reset() is not called in time, the Arduino will reboot.

Available Timeout Options:

Image description

Tip: Avoid long delays without wdt_reset(), or you’ll trigger an unwanted reset.

3. Implementing Fail-safes
Fail-safes depend on your application, but here are common techniques:

Example 1: Sensor Timeout

cpp

unsigned long lastSensorRead = 0;
const unsigned long timeout = 3000; // 3 seconds

void loop() {
  if (readSensor()) {
    lastSensorRead = millis();
  }

  if (millis() - lastSensorRead > timeout) {
    enterFailSafe(); // e.g., stop motors or blink LED
  }

  wdt_reset();  // Keep watchdog alive
}
Enter fullscreen mode Exit fullscreen mode

Example 2: Communication Loss (e.g., Serial, RF)

cpp

unsigned long lastPacket = millis();

void loop() {
  if (Serial.available()) {
    lastPacket = millis();
    processData();
  }

  if (millis() - lastPacket > 5000) {
    // Communication lost
    digitalWrite(LED_BUILTIN, HIGH); // Signal failure
  }

  wdt_reset();
}
Enter fullscreen mode Exit fullscreen mode

4. Testing the Watchdog
To simulate a lock-up:

cpp

void loop() {
  while (true) {
    // Infinite loop, watchdog will reset the Arduino
  }
}
Enter fullscreen mode Exit fullscreen mode

You’ll see the board reboot every few seconds (watchdog kicks in).

Best Practices

  • Always combine watchdog with fail-safe logic, not as a replacement.
  • Avoid delay() in watchdog code unless necessary.
  • For advanced needs (external WDT, ESP32), use dedicated libraries or hardware.

Top comments (0)