Polls

A quale categoria appartienni?

Visualizza risultati

Loading ... Loading ...
Seguimi su Facebook
Seguimi su Twitter
Categorie

Arduino resettare automaticamente la scheda utilizzando il WatchDog Timer

Watchdog, come creare un sistema che auto resetti la scheda in caso di blocchi o attese infinite

Il watchdog è un sistema molto interessante atto a supervisionare il normale ciclo di istruzioni della cpu. L’idea è quella di monitorare l’esecuzione del programma; in caso di blocchi o cicli infiniti, che rischiano di mettere il microcontrollore in uno stato di inutilizzo, il watchdog interviene resettando il microcontrollore e riavviandolo automaticamente.

Questo meccanismo è solitamente implementato in hardware e, anche Arduino, basato sul microcontrollore ATMega328, supporta questa funzionalità

Arduino atmega328 watchdog timer

Se il programma che andiamo a scrivere per la board Arduino è progettato considerando tutti gli aspetti e le variabili che possono bloccare la cpu, non è necessario gestire il Watchdog, che di default è disabilitato.
Capita comunque che si verificano delle particolari condizioni che portano il programma a rimanere in attesa, ad esempio, di un particolare input che per cause esterne, non gestibili, potrebbe non arrivare mai. Il watchdog quindi attende per un certo periodo e se, allo scadere di questo tempo l’input non è arrivato il Watchdog resetta la cpu facendola riavviare. In caso contrario, quando l’input arriva entro questo tempo, è fondamentale che il codice resetti il watchdog per evitare che questo resetti continuamente la cpu.

Il diagramma a blocchi seguente illustra in modo banale il meccanismo del watchdog

Schema esecuzione watchdog

Per utilizzare il Watchdog inseriamo nello sketch il riferimento alla libreria wdt.h

#include <avr/wdt.h>

I tempi di reset del Watchdog sono prestabiliti e possono essere scelti utilizzando i valori specificati nella tabella seguente

Tempo reset Parola Chiave
15mS WDTO_15MS
30mS WDTO_30MS
60mS WDTO_60MS
120mS WDTO_120MS
250mS WDTO_250MS
500mS WDTO_500MS
1S WDTO_1S
2S WDTO_2S
4S WDTO_4S
8S WDTO_8S

Nel blocco setup() decidiamo di abilitare il watchdog specificando il tempo di reset utilizzando la seguente funzione:

//abilito il watchdog e imposto come tempo di reser 2 secondi
wdt_enable(WDTO_2S);

questo significa che se entro 2 secondi non resettiamo il conteggio del watchdog, esso eseguirà automaticamente il reset della cpu.
Per resettarlo impieghiamo la seguente funzione:

//resetto il watchdog
wdt_reset();

Il codice seguente mostra meglio il funzionamento del sistema

#include <avr/wdt.h>

void setup()
{
    //attivo il watchdog e lo imposto
    //per una soglia di tempo di 2 Secondi
    wdt_enable(WDTO_2S);

}

void loop()
{
   //eseguo qualcosa...
   delay(500);

    //resetto il watchdog
    wdt_reset();
}

All’interno del blocco loop() eseguo un delay di 500 ms e poi resetto il watchdog, in questo caso il watchdog non resetterà mai la cpu poiché non arriverà mai a contare i due secondi preimpostati, dato che il reset avviene ogni 500 ms.
Vediamo invece questa situazione:

#include <avr/wdt.h>

void setup()
{
    //attivo il watchdog e lo imposto
    //per una soglia di tempo di 2 Secondi
    wdt_enable(WDTO_2S);

}

void loop()
{
   //eseguo qualcosa...
   delay(3000); //3 secondi

    //resetto il watchdog
    wdt_reset();
}

Il codice precedente mette in funzione il sistema di auto reset in quanto, il delay di 3 secondi, fa in modo che il watchdog arrivi a contare i 2 secondi preimpostati facendo resettare la cpu. Di fatto l’istruzione wdt_reset() non verrà mai eseguita.

Consiglio di utilizzare questo meccanismo in tutte le situazioni critiche che richiedono una certezza che la cpu esegua costantemente il suo compito evitando blocchi che porterebbero all’interruzione del servizio.

10 risposte a Arduino resettare automaticamente la scheda utilizzando il WatchDog Timer

  • giorgio scrive:

    Ciao,
    ho caricato su Arduino Mega 2560 uno sketch con il WDT impostato a 60MS, siccome sembrava non funzionasse ho provato a ricaricare il vecchio sketch senza successo. La procedura di caricamento parte normalmente, esegue la compilazione e poi si pianta, ho provato ad aspettare 10 minuti, ma non si muove. Iled della seriale circa ogni 10 sec. lampeggiano ma non succede di più. Quando si carica uno sketch Arduino blocca l’esecuzione di quello che sta girando? Può essere lo sketch caricato che blocca la seriale? Si può fare un caricamento di “emergenza” o “pulire” la cpu?
    Scusa per la raffica di domande, ma non so più cosa fare.
    Hai qualche idea?
    Grazie
    giorgio

    • Marco scrive:

      Ciao Giorgio
      prova a fare questo tentativo, stacca la board dalla usb , dall’ ide Arduino carica lo sketch e appena vedi la scritta ‘Sto caricando’ ricollega velocemente la board all’usb, Ti serviranno alcuni tentativi prima di riuscire a caricare lo sketch

      a presto
      Marco

      • giorgio scrive:

        Ciao Marco,
        ha funzionato, GRAZIE!
        Ho letto la risposta che hai dato a Rocco, come dovrebbe essere il circuito esterno di cui parli?
        Grazie ancora.
        Ciao

        • Marco scrive:

          Ottimo!
          il circuito esterno puo resettare Arduino tramite il pin /reset. questo circuito resetta la scheda ad esempio ogni 5 secondi (puoi usare un NE555), per avitare il reset devi usare, entro i 5 secondi un’uscita di Arduino per resettare il 555.
          Non so se mi sono spiegato, è un circuito ‘agricolo’ ma funziona!

          a presto

  • Fabrizio scrive:

    Ciao,
    grazie al tuo articolo riesco ad usare benissimo il WDT su Arduino Uno…. ;)
    Ho la necessità di utilizzarlo anche con l’ATmega328, si può fare? Ho cercato su google ma non ho trovato informazioni.
    Tu sai qualcosa?
    Grazie!

    • Marco scrive:

      Ciao Fabrizio
      Arduino UNO monta il chip ATmega328 quindi puoi usare il wdt anche con questo chip.Naturalmente devi aver caricato il bootloader sul chip

      Ciao

    • Marco scrive:

      Ciao
      i valori di reset dipendono dal prescaler e dalla frequenza dell’oscillatore, credo non sia possibile cambiare questi valori, la soluzione più veloce potrebbe essere quella di utilizzare un circuito esterno che resetti il chip.