====== Arduino Watchdog ======
===== Funktion des Watchdogs =====
Alle ATmega Chips von Atmel verfügen über einen sogenannten [[wpde>Watchdog]] welcher die Stabilität des Systems bei unvorhersehbaren Problemen gewährleisten soll (vorhersehbare Probleme sollten idealerweise in der Programmierung gelöst werden).
Der Watchdog ist in Wirklichkeit ein Zähler der vom System laufend erhöht wird und (falls er nicht vorher zeitig von der Software zurückgesetzt wird) bei Erreichen eines festgesetzten Zählstands gewisse Aktionen durchführt um so ein //Hängenbleiben// der Software zu verhindern.
Der Watchdog kann bei Auslösung, also bei Erreichen des gesetzten Zählstandes, entweder einzelne Aktionen ausführen, wie z.B. einen unansprechbaren Sensor neu initialisieren oder auch das System resetten resp. Neustarten.
Wird der Watchdog aber falsch konfiguriert kann dies dazu führen, dass der Mikrokontroller bis zur Neuinstallation des Bootloaders unansprechbar wird - dann nämlich wenn der Watchdog vor dem Bootloader schon anspricht/auslöst.
Wenn Du also Experimente mit dem Watchdog durchführst, ist es zu empfehlen, einen [[http://shop.boxtec.ch/programmer-c-59_152.html|ISP Programmierer]] oder ein Arduino Board mit [[http://arduino.cc/en/Tutorial/ArduinoISP|ArduinoISP]] zur Hand zu haben um Chips mit krumm konfigurierten Watchdog wieder zum Leben zu Erwecken.
===== Verwendung des Arduino Watchdogs =====
Die Verwendung des Watchdogs ist recht einfach, als erstes muss die AVR Watchdog Library inkludiert werden:
#include
Damit können nun diese zwei Funktionen aufgerufen werden:
wdt_enable(t)
zum Aktivieren des Watchdog Zählers mit Zeitkonstante t
und
wdt_reset()
zum Rücksetzen des Watchdogs (und damit Verhindern, dass der Zähler aufläuft und der Watchdog anspringt), also z.B. am Ende oder Anfang des Hauptprogramms.
==== Watchdog Zeitkonstanten ====
Die Watchdog Zeitkonstanten können dem [[http://cdn.boxtec.ch/pub/atmega/ATmega328.pdf|ATmega328 Datenblatt]] ab Seite 50 entnommen werden, möglich sind folgende Werte:
^ Zeit ^ Name der Konstanten ^ gesetzte Prescaler Bits:^ WDP0 ^ WDP 1 ^ WDP2 ^ WDP3 ^
| 16ms | WDTO_15MS || | | | |
| 32ms | WDTO_30MS || X | | | |
| 64ms | WDTO_60MS || | X | | |
| 0.125s | WDTO_120MS || X | X | | |
| 0.25s | WDTO_250MS || | | X | |
| 0.5s | WDTO_500MS || X | | X | |
| 1s | WDTO_1S || | X | X | |
| 2s | WDTO_2S || X | X | X | |
| 4s | WDTO_4S || | | | X |
| 8s | WDTO_8S || X | | | X |
===== Watchdog Beispiele =====
**Achtung**: Bitte beachte bei der Verwendung der nachfolgenden Beispiele, dass ein zu früh einsetzender Watchdog das Board scheinbar unprogrammierbar machen kann. In diesem Fall kann es nötig werden, das Board über den ICSP Anschluss zu resetten (z.B. den Bootloader neu zu installieren).
==== Beispiel 1 ====
Um einfach mal die Funktion des Watchdogs zu verdeutlichen hilft folgender Sketch:
#include
void setup() {
Serial.begin(9600);
Serial.println("Sketch gestartet");
//Aktiviere Watchdog mit 4s Zeitkonstante
wdt_enable(WDTO_4S);
}
void loop() {
Serial.println("Warte einen Moment");
delay(5000);
Serial.println("Bin wieder da, aber das wirst Du nie zu sehen bekommen, vorher beisst der Watchdog zu.");
// Setze Watchdog Zähler zurück
wdt_reset();
}
Wie erwartet ist die Ausgabe des Sketchs dann:
Sketch gestartet
Warte einen Moment
Sketch gestartet
Warte einen Moment
Sketch gestartet
Warte einen Moment
...
Wenn Du das Delay auf z.B. 1000 setzt wird sich das natürlich ändern.
Natürlich macht obenstehender Sketch nicht wirklich Sinn, aber er verdeutlicht die Funktion sehr schön.
==== Beispiel 2 ====
Ein bisschen realer ist folgendes Beispiel, hier reagieren wir auf einen nicht mehr reagierenden Sensor mit einem Reset:
#include
unsigned long measure_val;
void setup() {
Serial.begin(9600);
Serial.println("Sketch gestartet");
//Aktiviere Watchdog mit 2s Zeitkonstante
wdt_enable(WDTO_2S);
}
void loop() {
Serial.println("Lese Sensor aus");
measure_val = readSensor();
// Setze Watchdog Zähler zurück
wdt_reset();
}
unsigned long readSensor() {
pinMode(5, OUTPUT);
pinMode(6, INPUT);
// Verlange Messung vom Sensor:
digitalWrite(5, HIGH);
delay(10);
digitalWrite(5, LOW);
while (digitalRead(6) == LOW) {
//Warte auf Sensorkommunikation
}
// Sensorkommunikation...
Serial.println("Sensor ausgelesen.");
}
Der Sketch wird ebenfalls immer wieder neu starten, ausser der eingebildete Sensor an D5 und D6 sendet Daten, deren Anfang er mit einem HIGH Puls auf D6 signalisiert. Um dies zu testen, verbinde testweise D6 mit 5V und der Watchdog kann nicht mehr zuschlagen.
=== Referenzen ===
* [[http://cdn.boxtec.ch/pub/atmega/ATmega328.pdf|Datenblatt ATmega328]]
* [[http://tushev.org/articles/arduino/item/46-arduino-and-watchdog-timer|Arduino and watchdog timer]]