MicroPython: Watchdog-Timer (WDT)

Ein Watchdog-Timer, kurz WDT, ist ein interner Countdown-Timer im Mikrocontroller, der automatisch einen Reset auslöst, wenn er nicht nach einer bestimmten Zeit zurückgesetzt wird. Er sorgt dafür, dass sich ein System nach Ablauf einer festgelegten Zeit automatisch neu startet, wenn das Programm „hängt“ oder nicht mehr korrekt läuft.
Wichtig zu wissen ist, der Watchdog-Timer ist ein integrierter Bestandteil des Mikrocontrollers. Er läuft unabhängig vom Programmcode. MicroPython unterstützt einen verfügbaren Watchdog-Timer.

In Systemen ohne Benutzeraufsicht (z. B. IoT-Geräte, Sensoren, Roboter) kann ein Systemfehler zu einem Ausfall führen, der wegen fehlender menschlicher Überwachung nicht oder erst spät bemerkt wird. Selbst wenn ein Ausfall bemerkt wird, ist dann ein manueller Neustart erforderlich. Mit einem Watchdog-Timer startet sich das System selber neu, ohne dass jemand von außen eingreifen muss.

Dabei erkennt der Watchdog keinen Fehler ansich, sondern ein Countdown läuft ab, wenn der nicht zurückgestellt oder „gefüttert“ wird. Dann löst der Watchdog einen Reset aus.

Watchdog-Timer mit Timeout starten

In MicroPython wird der Watchdog-Timer mit einem Timeout in Millisekunden (ms) initialisiert. Im folgenden Beispiel wird der Watchdog mit einem Timeout von 8 Sekunden (8000 ms) gestartet.

import machine
wdt = machine.WDT(timeout=8000) # ms

Der Timeout ist so zu wählen, dass innerhalb des Programms genug Zeit ist, um seine Hauptfunktion abzuschließen. Denn, der Watchdog muss „gefüttert“ werden.
Der höchste Timeout-Wert ist 8333 (Milisekunden) in MicroPython.

Watchdog-Timer zurückstellen (füttern)

Das „Füttern“ muss erfolgen, bevor der Timeout abläuft.

wdt.feed()

Watchdog-Timer deaktivieren?

Nein. Der Watchdog-Timer kann nicht deaktiviert werden. Das darf nicht möglich sein und ist auch nicht sinnvoll. Sobald er aktiviert ist und abgeschaltet werden soll, ist ein Neustart ohne das Starten des Watchdogs nötig.

Woher weiß der Watchdog, dass ein Programm beendet wurde und kein Reset ausgelöst werden soll?

Diese Frage zielt direkt auf den Kern der Watchdog-Logik. Der Watchdog kann nicht unterscheiden, ob ein Programm „sauber“ beendet wurde oder ob es hängen geblieben ist. Er weiß nur: Wurde ich rechtzeitig gefüttert (Countdown startet neu) oder nicht (Coutdown läuft ab und Reset)?

Was heißt das? Wenn man einen Programmcode schreibt und einen Watchdog-Timer verwenden will, dann sollte man den zum Schluss implementieren, weil der Watchdog unabhängig vom Programmcode in der Hardware läuft und nicht deaktiviert werden kann. Das heißt, er löst auch dann einen Reset aus, wenn man den Programmcode in der Entwicklungsumgebung manuell beendet hat. Der Watchdog kann nicht regulär beendet werden.

Beispiel: Wenn in einem Autostart-Programm der Watchdog-Timer initialisiert wird, dann löst der im Fehlerfall einen Reset aus, der zu einem Neustart führt, der den Watchdog-Timer wieder initialisiert. Wenn der Fehlerfall erneut auftritt, dann läuft der Mikrocontroller in einer Fehler-Reset-Neustart-Schleife, die man nur beendet bekommt, wenn man es schafft, den Autostart zu unterbinden.

Tipp: Es kann sinnvoll sein, eine Möglichkeit vorzusehen den Autostart abbrechen zu können oder eine Breakout-Funktion vorzusehen.

Programmcode mit Watchdog

Der folgende Programmcode startet den Watchdog-Timer mit einem Timeout von 8000 Millisekunden bzw. 8 Sekunden. Anschließend wird er in einer Schleife regelmäßig gefüttert. Innerhalb der Schleife wird die Onboard-LED ein- und ausgeschaltet. Wenn die Schleife nach etwa 10 Sekunden beendet wird, läuft der Watchdog im Hintergrund für 8 Sekunden weiter. Bleibt die „Fütterung“ aus, löst der Watchdog einen Reset aus, der den Mikrocontroller neu startet.

Achtung, wenn man diesen Programmcode mit der Autostart-Datei „main.py“ ausführt, dann wird der Watchdog gestartet, er löst irgendwann einen Reset aus, der zu einem Neustart führt, der den Watchdog erneut startet. Unter Umständen bekommt man das Programm zwar beendet, es wird aber wegen dem Watchdog immer wieder neu gestartet!

# Bibliotheken laden
import machine
import time

# Watchdog-Timer starten
wdt = machine.WDT(timeout=8000)

# Onboard-LED
led_onboard = machine.Pin('LED', machine.Pin.OUT, value=1)

# Hauptprogramm
for _ in range(10):
    # Fütterung
    wdt.feed()
    time.sleep(1)
    led_onboard.toggle()

Das der Watchdog-Timer einen Reset ausgelöst hat erkennt man in der Thonny Python IDE an der Fehlermeldung „Connection lost -- read failed: [Errno 6] Device not configured“ in der Kommandozeile. Der Reset führt zum Verbindungsverlust der Thonny Python IDE. Das ist normal. Die logische Verbindung muss mit STOP manuell hergestellt werden.

Programmcode mit Watchdog und manuellem Abbruch

Bei einem Autostart-Programm (main.py) mit Watchdog hat man das Problem, dass der Mikrocontroller bei jedem Reset neu gestartet wird und auch der Watchdog jedes mal erneut aktiviert wird. Das heißt, man bekommt ihn nicht beendet und auch nicht deaktiviert. Das kann unter Umständen zu einer Reset-Neustart-Schleife führen

Der folgende Programmcode sieht vor, dass der Watchdog nur dann gestartet wird, wenn der GPIO 0 (Pin 1) als Eingang unbeschaltet ist und damit den Zustand logisch 1 oder „True“ hat.
Wenn bei einem Neustart der Pin 1 (GPIO 0) mit GND verbunden ist (Drahtbrücke oder gedrückter Taster), dann wird der Start des Watchdog-Timers unterbunden.
Damit das „Füttern“ des nicht gestarteten Watchdogs keinen Fehler verursacht, ist die „Fütterung“ mit einer Fehlerbehandlung ausgeklammert.

# Bibliotheken laden
import machine
import time

# GPIO 0 (Pin 1) für manuellen Abbruch (PULL_UP=1/True)
WDT = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)

# Initialisierung des GPIOs abwarten!
time.sleep(1)

# Watchdog-Timer starten
if WDT():
    wdt = machine.WDT(timeout=8000)

# Onboard-LED
led_onboard = machine.Pin('LED', machine.Pin.OUT, value=1)

# Hauptprogramm
for _ in range(10):
    try:
        wdt.feed() # Fütterung
    except:
        pass
    time.sleep(1)
    led_onboard.toggle()

Hinweis: Normalerweise sollte es keine Möglichkeit geben, den Start des Watchdog-Timers zu unterbinden. Das Ziel des Watchdogs ist es, immer aktiv zu sein. Deshalb gibt es softwareseitig keine Möglichkeit ihn bedarfsweise zu deaktivieren. Es kann aber in der Entwicklungsphase sinnvoll sein, den Start des Watchdog-Timers von Anfang an vorzusehen, weil das nachträgliche Einbauen problematisch sein kann. Doch gerade dann braucht man eine Möglichkeit, den Watchdog bei einem Neustart abgeschaltet zu lassen.

Weitere verwandte Themen:

Frag Elektronik-Kompendium.de

Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython

Elektronik-Set Pico Edition

Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.

  • LED: Einschalten, ausschalten, blinken und Helligkeit steuern
  • Taster: Entprellen und Zustände anzeigen
  • LED mit Taster einschalten und ausschalten
  • Ampel- und Lauflicht-Steuerung
  • Elektronischer Würfel
  • Eigene Steuerungen programmieren

Elektronik-Set jetzt bestellen Online-Workshop buchen

Online-Workshop: Programmieren mit dem Raspberry Pi Pico

Programmieren mit dem Raspberry Pi Pico

Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.

Online-Workshop buchen

Besuchen Sie unser fast monatlich stattfindendes Online-Meeting PicoTalk und lernen Sie uns kennen. Die Teilnahme ist kostenfrei.

Termine und Newsletter-Anmeldung

 

Elektronik-Sets für das Hardware-nahe Programmieren