Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Watchdog Timer Arduino: Prevent Program Freeze and Auto-Reset

Watchdog Timer Arduino: Prevent Program Freeze and Auto-Reset

March 11, 2026 /Posted byJayesh Jain / 0

Your Arduino sketch worked perfectly during testing. But after 3 days running unattended, it froze — the display went blank, the sensors stopped updating, and a remote reset was impossible. This is one of the most frustrating problems in embedded development, and the watchdog timer (WDT) is the hardware solution that’s been on your Arduino all along, waiting to be used.

The watchdog timer is a simple but powerful mechanism: a hardware countdown timer that automatically resets the microcontroller if the software fails to periodically signal that everything is still running. Think of it as a deadman switch for your Arduino — if your program doesn’t regularly check in, the hardware assumes something has gone wrong and restarts the system.

This guide covers everything from the fundamentals of how the WDT works to production-ready code patterns for reliable, self-recovering Arduino applications.

Table of Contents

  1. How the Watchdog Timer Works
  2. Setting Up the Watchdog Timer
  3. Basic Implementation with wdt.h
  4. Common Pitfalls and Bootloader Issues
  5. Advanced Patterns for Production Code
  6. Watchdog Timer and Sleep Mode
  7. Detecting and Logging Watchdog Resets
  8. Frequently Asked Questions

How the Watchdog Timer Works

The ATmega2560 and ATmega328P (used in Mega and Uno respectively) contain an independent hardware watchdog timer driven by a separate internal oscillator — not the main system clock. This is crucial: even if your main clock fails or the CPU gets stuck in an infinite loop, the watchdog timer continues counting.

The WDT operates on a simple principle:

  1. You configure the watchdog with a timeout period (ranging from 15ms to 8 seconds on AVR Arduinos)
  2. Your program must call wdt_reset() — commonly called “kicking” or “petting” the watchdog — before the timeout expires
  3. If the timer reaches zero without being reset, the WDT triggers a system reset
  4. After the reset, your program starts from the beginning as if power was just applied

The watchdog can be configured in three modes:

  • Interrupt mode — triggers an ISR instead of a reset, useful for saving state before restart
  • Reset mode — directly resets the MCU when the timer expires
  • Interrupt + Reset mode — fires the ISR first, then resets if ISR doesn’t disable the WDT

For most applications, Reset mode is what you want. The WDT is always operating from its own 128kHz internal oscillator (on AVR), making it immune to any software or main clock failure.

Recommended: Arduino Uno R3 Beginners Kit — Perfect for learning watchdog timer fundamentals. The ATmega328P’s WDT is well-documented and easy to experiment with safely.

Setting Up the Watchdog Timer

Arduino’s avr/wdt.h library provides three key functions for AVR-based boards (Uno, Mega, Nano, Leonardo, etc.):

  • wdt_enable(timeout) — enables the WDT with a specified timeout period
  • wdt_disable() — disables the WDT (requires a timed sequence for security)
  • wdt_reset() — resets the watchdog counter (“pet” the dog)

The timeout constants available are:

Constant Timeout Period
WDTO_15MS 15 milliseconds
WDTO_30MS 30 milliseconds
WDTO_60MS 60 milliseconds
WDTO_120MS 120 milliseconds
WDTO_250MS 250 milliseconds
WDTO_500MS 500 milliseconds
WDTO_1S 1 second
WDTO_2S 2 seconds
WDTO_4S 4 seconds
WDTO_8S 8 seconds

Choose a timeout that is comfortably longer than your worst-case main loop execution time. If your loop normally completes in 100ms but could take up to 500ms during a slow SD card write, set the watchdog to 2S or 4S to give adequate margin.

Basic Implementation with wdt.h

Here is a minimal working watchdog implementation:

#include <avr/wdt.h>

void setup() {
    Serial.begin(9600);
    
    // Disable WDT first (safe practice during setup)
    wdt_disable();
    
    // Your normal setup code here
    Serial.println("System starting...");
    delay(2000);  // Long delays are safe before WDT is enabled
    
    // Enable watchdog with 4 second timeout
    wdt_enable(WDTO_4S);
    Serial.println("Watchdog enabled. 4 second timeout.");
}

void loop() {
    // Pet the watchdog at the start of each loop iteration
    wdt_reset();
    
    // Your main program logic
    readSensors();
    updateDisplay();
    handleCommunication();
    
    // If any of the above block for more than 4 seconds,
    // the watchdog will reset the Arduino
}

void readSensors() {
    // Sensor reading code...
}

void updateDisplay() {
    // Display update code...
}

void handleCommunication() {
    // Network/serial communication code...
}

The critical rule: never call delay() for more than a fraction of your WDT timeout. A delay(5000) with a 4-second watchdog will guarantee a reset. Use millis()-based non-blocking timing instead.

Here’s the non-blocking pattern that works safely with the watchdog:

#include <avr/wdt.h>

unsigned long lastSensorRead = 0;
unsigned long lastDisplayUpdate = 0;

void setup() {
    Serial.begin(9600);
    wdt_disable();
    // ... setup code ...
    wdt_enable(WDTO_2S);
}

void loop() {
    wdt_reset();  // Always first thing in loop
    
    unsigned long now = millis();
    
    // Read sensors every 500ms (non-blocking)
    if (now - lastSensorRead >= 500) {
        lastSensorRead = now;
        readSensors();
    }
    
    // Update display every 200ms (non-blocking)
    if (now - lastDisplayUpdate >= 200) {
        lastDisplayUpdate = now;
        updateDisplay();
    }
    
    // Loop returns quickly — WDT stays happy
}
Recommended: Arduino Mega 2560 R3 Board — For complex, long-running projects where program reliability is critical. The Mega’s large memory accommodates the logging and state management needed for robust WDT usage.

Common Pitfalls and Bootloader Issues

The watchdog timer has several gotchas that trip up even experienced developers.

The Bootloader Reset Loop Problem

This is the most notorious WDT issue on Arduino. When the WDT triggers a reset, the WDTON fuse bit may remain set, meaning the WDT is still active when the bootloader starts running. If the bootloader takes longer than the WDT timeout to hand control to your sketch, the WDT fires again — triggering another reset — creating an infinite reset loop where your Arduino never successfully boots.

The solution for older bootloaders is to disable the WDT immediately at the start of your sketch using a special technique:

#include <avr/wdt.h>

// This runs BEFORE setup() — must be placed at global scope
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));
void wdt_init(void) {
    MCUSR = 0;         // Clear reset source flags
    wdt_disable();     // Disable watchdog immediately
}

void setup() {
    Serial.begin(9600);
    // Now safely enable WDT with your desired timeout
    wdt_enable(WDTO_4S);
}

Modern Arduino bootloaders (Optiboot, used in most current Uno R3 and Mega R3 boards) handle the WDT reset correctly and don’t require this workaround, but adding it is harmless and makes your code more portable across different board revisions.

Long Operations Inside Loops

Watch out for these WDT-killers in your loop:

  • WiFi/Ethernet connections that can time out (add wdt_reset() inside retry loops)
  • SD card operations on slow cards
  • Waiting for serial data without a timeout
  • Blocking library calls (some sensor libraries have internal delays)

Interrupts and the WDT

The WDT timer continues to count during interrupt service routines. If an ISR takes longer than the WDT timeout (unlikely but possible with a short timeout), a reset will occur during the ISR. Use the longest practical timeout for your application.

Advanced Patterns for Production Code

Task Monitoring with Per-Task Timeouts

For complex applications with multiple subsystems, you can implement software watchdogs at the task level, with the hardware WDT as the final backstop:

#include <avr/wdt.h>

// Software task watchdog
struct TaskWatchdog {
    unsigned long lastKick;
    unsigned long timeout;
    const char* name;
    bool triggered;
};

TaskWatchdog tasks[] = {
    {0, 5000, "SensorTask", false},
    {0, 10000, "NetworkTask", false},
    {0, 3000, "DisplayTask", false}
};

void kickTask(int taskIndex) {
    tasks[taskIndex].lastKick = millis();
    tasks[taskIndex].triggered = false;
}

void checkTasks() {
    unsigned long now = millis();
    for (int i = 0; i < 3; i++) {
        if (now - tasks[i].lastKick > tasks[i].timeout) {
            if (!tasks[i].triggered) {
                tasks[i].triggered = true;
                Serial.print("WARN: Task ");
                Serial.print(tasks[i].name);
                Serial.println(" overdue!");
                // Log to EEPROM, then let hardware WDT catch it
            }
        }
    }
}

void loop() {
    wdt_reset();  // Hardware WDT - 8 second backstop
    checkTasks(); // Software task monitoring
    
    runSensorTask();
    runNetworkTask();
    runDisplayTask();
}
Recommended: Arduino Nano Every with Headers — The ATmega4809 has an improved WDT implementation with more reliable reset behavior, making it excellent for standalone deployed projects.

Watchdog Timer and Sleep Mode

The WDT has a special role in low-power Arduino designs: it can be used as a wake-up timer even in the deepest sleep modes. This is entirely separate from its reset function.

#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

volatile bool wdt_fired = false;

// WDT interrupt service routine (interrupt mode, not reset mode)
ISR(WDT_vect) {
    wdt_fired = true;
}

void setupWDTInterrupt(uint8_t timeout) {
    cli();                        // Disable interrupts during setup
    MCUSR &= ~(1 << WDRF);       // Clear WDT reset flag
    // Set WDT in interrupt mode (WDIE bit, not WDE bit)
    WDTCSR |= (1 << WDCE) | (1 << WDE);  // Enable change sequence
    WDTCSR = (1 << WDIE) | timeout;       // Interrupt only, no reset
    sei();                        // Re-enable interrupts
}

void sleepForSeconds(int seconds) {
    int wakes = 0;
    int target = (seconds + 7) / 8;  // WDTO_8S = ~8 second wakes
    
    while (wakes < target) {
        wdt_fired = false;
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        sleep_cpu();          // CPU stops here
        sleep_disable();      // Resumes here after WDT fires
        if (wdt_fired) wakes++;
    }
}

This pattern lets you sleep for extended periods (hours, days) while waking periodically for sensor readings — with the WDT serving as an alarm clock rather than a reset trigger. Battery-powered sensor nodes use this technique to achieve months of operation on a single cell.

Important: When using WDT for sleep wakeup, configure it in interrupt mode (WDIE bit), not reset mode (WDE bit). Using both simultaneously enables the interrupt+reset mode — the ISR fires first, and if it doesn’t clear the WDT, a reset follows.

Detecting and Logging Watchdog Resets

Knowing that a WDT reset happened is crucial for diagnosing why your program froze. The MCU Status Register (MCUSR) stores the cause of the last reset, including a specific bit for WDT resets:

#include <avr/wdt.h>
#include <EEPROM.h>

#define EEPROM_RESET_COUNT_ADDR 0
#define EEPROM_RESET_CAUSE_ADDR 2

void setup() {
    uint8_t resetCause = MCUSR;  // Read reset cause BEFORE clearing
    MCUSR = 0;                   // Clear all reset flags
    wdt_disable();               // Disable WDT immediately
    
    Serial.begin(9600);
    delay(500);
    
    // Report reset cause
    if (resetCause & (1 << WDRF)) {
        Serial.println("ALERT: Reset caused by Watchdog Timer!");
        
        // Increment WDT reset counter in EEPROM
        uint16_t count;
        EEPROM.get(EEPROM_RESET_COUNT_ADDR, count);
        if (count == 0xFFFF) count = 0;  // First use after flash
        count++;
        EEPROM.put(EEPROM_RESET_COUNT_ADDR, count);
        
        Serial.print("Total WDT resets: ");
        Serial.println(count);
    } else if (resetCause & (1 << EXTRF)) {
        Serial.println("INFO: External reset (reset button)");
    } else if (resetCause & (1 << PORF)) {
        Serial.println("INFO: Power-on reset");
    }
    
    // Now enable WDT for normal operation
    wdt_enable(WDTO_4S);
}

By logging WDT resets to EEPROM, you can connect your Arduino via USB days later and read out exactly how many times it recovered itself — invaluable data for reliability engineering on deployed projects.

Recommended: Arduino Nano RP2040 Connect with Header — For IoT projects needing reliable autonomous operation, the RP2040’s dual-core architecture and hardware watchdog make it excellent for always-on deployed applications.

Frequently Asked Questions

Will the watchdog timer interfere with the Arduino bootloader during programming?

On modern Arduinos using the Optiboot bootloader (most current Uno R3 and Mega R3 boards), the bootloader correctly handles WDT resets and the WDT is disabled during the bootloader phase. On older boards with the original bootloader, rapid WDT resets could interfere with programming. If you have trouble uploading sketches to a board with WDT enabled, use the .init3 technique described in this article to disable the WDT before the bootloader can be affected, or simply power-cycle while holding reset to trigger normal programming mode.

What is the minimum watchdog timeout I should use?

Choose the shortest timeout that your worst-case loop execution time safely fits within, with at least 50% margin. If your loop can take up to 300ms in extreme conditions, use WDTO_1S or WDTO_2S. Extremely short timeouts (15ms, 30ms) are only appropriate for simple, very fast control loops. In general, WDTO_2S or WDTO_4S are good defaults for most projects. Setting the timeout too short causes frequent false resets; too long means it takes too long to recover from a genuine freeze.

Does the watchdog timer work if the Arduino is stuck in an interrupt service routine?

Yes. The WDT operates from its own independent oscillator and continues counting even when the CPU is inside an ISR or when global interrupts are disabled. This is one of the key advantages of hardware watchdog timers over software timeout mechanisms. If your ISR hangs or takes too long, the WDT will fire and reset the system. This is why it’s important to keep ISRs short and to not do long operations inside them.

Can I use the watchdog timer on ESP32 or ESP8266 Arduino boards?

Yes, but the API is different. ESP32 and ESP8266 have their own WDT implementations through the Arduino-ESP32 framework. ESP32 has both a hardware WDT and a task WDT managed by FreeRTOS. The esp_task_wdt_reset() function is used to pet the task WDT on ESP32, while ESP.wdtFeed() is used on ESP8266. The avr/wdt.h library is AVR-specific and won’t work on these boards.

Can I use the watchdog timer to make my Arduino reboot every 24 hours for a fresh start?

Yes, though it’s a bit of a workaround. The WDT maximum timeout is 8 seconds on AVR Arduinos. To achieve a daily reboot, use the WDT interrupt mode to wake from sleep periodically, count the wakeups, and after 24 hours’ worth of intervals, deliberately avoid calling wdt_reset() — the next WDT expiry then triggers a full reset. However, this is better handled with proper software state management so reboots aren’t needed. If you need daily reboots, it usually means there’s a memory leak or resource management issue worth fixing properly.

Build more reliable, self-recovering Arduino projects with the right hardware from Zbotic.in’s Arduino & Microcontrollers collection — explore our range of Arduino boards, sensor modules, and development kits with fast delivery across India.

Tags: Arduino programming, arduino reset, Arduino WDT, avr watchdog, embedded reliability, watchdog timer
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino Nano vs Pro Mini: Whic...
blog arduino nano vs pro mini which small board to buy in india 594911
blog arduino pwm tutorial analogwrite frequency duty cycle 594922
Arduino PWM Tutorial: Analogwr...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

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

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now