Ich habe folgendes Problem gehabt:
Meine Jalousie automatisierung sollte mit einem Dämmerungsschalter die jalousien hoch und runter fahren. Der sketch war relativ einfach, aber die Dauer, in der es lief war natürlich immens, so dass der controller immer mal wieder angestürzt ist, also habe ich die overflow von millis() versucht raus zu nehmen, was das problem aber noch verschlechtert hat.
Also wollte ich den Watchdog verwenden, um bei so einem Problem einen restart auszuprobieren, allerdings hat der bei mir nicht funktioniert, Da ich scheinbar den alten Bootloader bei meinem Nano verwende.
Der normale Watchdog funktioniert ungefähr so:
#include <avr/wdt.h>
void setup() {
//Die Dauer, bis der Watchdog auslösen soll
//wdt_enable(WDTO_15MS);
//wdt_enable(WDTO_30MS);
//wdt_enable(WDTO_60MS);
//wdt_enable(WDTO_120MS);
//wdt_enable(WDTO_250MS);
//wdt_enable(WDTO_500MS);
//wdt_enable(WDTO_1S);
//wdt_enable(WDTO_2S);
//wdt_enable(WDTO_4S);
wdt_enable(WDTO_8S);
}
void loop() {
// put your main code here, to run repeatedly:
wdt_reset();
}
Dabei wird die WDTO_zeit gewartet, falls in diesem Zeitraum kein wdt_reset() durchgeführt wird, resettet sich der µC. Bei mir fing die Power LED aber nur an zu blinken und ein Manueller Reset hat auch nicht mehr geholfen, weil ich wohl noch den alten Bootloader drauf habe.
Diese Kompatibilitätsprobleme haben mich so gestört, dass ich ab jetzt nur noch Hardware Watchdogs verwenden werde. Das möchte ich hier kurz beschreiben.
Als erstes habe ich für einen Testaufbau einen Sockel an den NANO gelötet:
Damit habe ich dann den Pin 13 überwacht und im eigentlichen sketch eben diesen pin immer wieder geändert, damit mein Hardware Watchdog wusste, dass der haupt Controller noch läuft.
Als Watchdog habe ich den ATTINY85 genommen und folgenden Sketch auf ihn geladen:
int zeit = 0, vorher, jetzt, wartezeit = 5000;
void setup() {
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
pinMode(1, INPUT_PULLUP);
vorher = digitalRead(1);
}
void loop() {
delay(1);
jetzt = digitalRead(1);
if (vorher == jetzt) {
zeit += 1;
}
else {
zeit = 0;
vorher = jetzt;
}
if (zeit >= wartezeit) {
digitalWrite(3, LOW);
delay(100);
digitalWrite(3, HIGH);
zeit = 0;
}
}
Die Dauer kann man dann mit der variable wartezeit einstellen. Bei mir reicht diese grobe Einstellung völlig aus.
Im nachhinein wollte ich aber noch sehen, ob der Watchdog irgendwann mal ausgelöst hat, so habe ich noch eine weitere LED angelötet, die nach einem Auslösen an geht:
Der Code dazu sieht so aus:
int zeit = 0, vorher, jetzt, wartezeit = 5000;
void setup() {
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
delay(1000);
digitalWrite(4, LOW);
pinMode(1, INPUT_PULLUP);
vorher = digitalRead(1);
}
void loop() {
delay(1);
jetzt = digitalRead(1);
if (vorher == jetzt) {
zeit += 1;
}
else {
zeit = 0;
vorher = jetzt;
}
if (zeit >= wartezeit) {
digitalWrite(3, LOW);
delay(100);
digitalWrite(3, HIGH);
zeit = 0;
digitalWrite(4, HIGH);
}
}
Somit bekommt man sehr gute Kontrolle über diese Funktion und kann sogar die interne LED blinken sehen, wenn der Controler noch läuft. wenn sich das so bewährt, wird die richtige Platine mit dem Layout bestellt und fertig.
auf dass die nächsten Googler fündiger werden, als ich.
MfG