Arduino watchdog

arduino watchdog

Watchdog w Arduino to niezwykle przydatna funkcja, zwłaszcza po zakończeniu testów programu i przygotowaniu go do użycia w warunkach rzeczywistych. Weźmy na przykład układ zamka szyfrowego do mieszkania, który zaprogramowaliśmy i zainstalowaliśmy na drzwiach wejściowych. Co jednak, jeśli z jakiegoś powodu procesor na płytce Arduino zawiesi się? Może to być spowodowane zakłóceniami elektromagnetycznymi lub nieprzewidzianym błędem w kodzie.

W takim przypadku nie będziemy w stanie dostać się do mieszkania…

Aby temu zapobiec, włączamy funkcję watchdog w kodzie programu. Watchdog monitoruje działanie programu i, jeśli wykryje zawieszenie systemu, automatycznie resetuje Arduino, przywracając jego normalną pracę.

Użycie wachdog jest bardzo proste, co zademonstrowano na poniższym przykładzie.

Przykład 1

Kod_001

// Włączamy bibliotekę watchdog do programu:
#include 

void setup() {
    // Aktywujemy watchdog z argumentem czasu - w tej sytuacji 1 sekunda
    wdt_enable(WDTO_1S);

    // Wstawiamy w dowolnym miejscu w setup...
    // Od tego momentu watchdog już działa ;)
}

void loop() {
    // Reset zegara watchdog
    wdt_reset();
    // Jeśli w ciągu jednej sekundy program nie wywoła funkcji wdt_reset(),
    // Arduino zresetuje się automatycznie.
}

Użycie funkcji wdt_reset() musi być dokładnie przemyślane. W powyższym przykładzie reset zegara watchdog, wywołany funkcją wdt_reset(), musi nastąpić w ciągu maksymalnie jednej sekundy. Jeśli to się nie wydarzy, płytka Arduino zostanie zresetowana (tak, jakbyśmy nacisnęli przycisk „reset”). Dlatego nie możemy wprowadzać w tym konkretnym przykładowym programie komend takich jak delay(2000), ponieważ watchdog wykryje brak resetu i zresetuje płytkę, zanim program odczeka te 2000 ms.

Należy również zachować ostrożność przy używaniu pętli for i while, ponieważ program może utknąć w jednej z tych pętli na dłużej. W takim przypadku warto wielokrotnie wywoływać wdt_reset() w kodzie, zwłaszcza wewnątrz pętli, aby zapewnić, że watchdog będzie resetowany na czas.

Jeśli jednak z jakiegoś powodu Arduino zawiesi się, a program nie wywoła funkcji wdt_reset() w ciągu jednej sekundy, nastąpi automatyczny reset.

Aby śledzić liczbę resetów wywołanych przez watchdog, można zapisać je w pamięci EEPROM. Dzięki temu, po dłuższym czasie użytkowania urządzenia, będzie można sprawdzić, czy program lub układ elektroniczny jest stabilny, odczytując dane z pamięci EEPROM.

Tabela dostępnych argumentów funkcji wdt_enable, określających czas, w którym funkcja sprawdza, czy Arduino się nie zawiesiło:

Czas oczekiwaniaArgument funkcji wdt_enable
15msWDTO_15MS
30msWDTO_30MS
60msWDTO_60MS
120msWDTO_120MS
250msWDTO_250MS
500msWDTO_500MS
1sWDTO_1S
2sWDTO_2S
4sWDTO_4S
8sWDTO_8S

Na przykład, jeśli chcemy sprawdzać stan Arduino co ćwierć sekundy, w sekcji setup wpisujemy:
wdt_enable(WDTO_250MS);

Uwaga praktyczna: Czasami watchdog może być w konflikcie z bootloaderem płytki, szczególnie na płytce Nano. W takim przypadku, aby poprawnie wykorzystać watchdog, należy zaprogramować płytkę przez SPI, a nie przez USB. Wtedy wszystko działa prawidłowo.


Przykład 2

Poniższy przykład demonstruje zastosowanie funkcji watchdog w praktyce. Celem programu jest miganie diody na płytce co 1 sekundę. Zdefiniowaliśmy, że watchdog będzie sprawdzał, czy płytka prawidłowo wykonuje kod co 0,25 sekundy. Gdybyśmy zdecydowali się na podejście z użyciem polecenia delay(1000), program nie działałby poprawnie. Zamiast tego, program został zaimplementowany przy użyciu funkcji millis(), co zapewnia prawidłowe działanie watchdog.

Kod_003

#include //włączamy bibliotekę do programu

const int nr_pinu = 13;  //definicja numer pinu do którego podłączona jest dioda
int stan_diody = LOW;  //definicja zmiennej stanu diody (HIGH-świeci, LOW-nie świeci)
unsigned long ostatni_czas = 0;  //definicja zmiennej pomocniczej, do której przypisana będzie ostatnia wartość czasu zmiany staniu diody
const long okres_czasu = 1000;  //definicja okresu migania diody (500 to znaczy 0,5s)

void setup() {
  pinMode(nr_pinu, OUTPUT);
  digitalWrite(nr_pinu, LOW);
  ostatni_czas  = millis(); // przypisanie aktualnej wartości czasu do zmiennej
  wdt_enable(WDTO_250MS);//od tego miejsca watchdog sprawdza co 0,25 sekundy czy arduino nie zawiesiło się
}

void loop() {
  if (millis() - ostatni_czas  >= okres_czasu) 
  {
    stan_diody =!stan_diody ;//zmiana stanu zmiennej diody na przeciwny
    digitalWrite(nr_pinu, stan_diody);
    ostatni_czas  = millis(); // przypisanie aktualnej wartości czasu do zmiennej
  }
  wdt_reset(); //reset zegara watchdog
}

Resetowanie zegara watchdog, można również wykonać za pomocą przerwań zegara.




Asystent Arduinowo_AI




Dziękujemy za przeczytanie naszego artykułu. Jeśli doceniasz naszą pracę, prosimy o zapisanie się do bezpłatnego newslettera.

Więcej informacji o watchdog można uzyskać na oficjalnej stronie Arduino: link do strony

Przetestuj nasz generator przerwań typu PCINT (https://arduinowo.pl/generatory/pin_int/)