Aller au contenu

Watchdog Arduino : explication de fonctionnement, et exemples de code (mode reset, timer interruption, et réveil après sleep)

Watchdog arduino tutorial avec explication fonctionnement et exemple de code programme, détail du chien de garde du microcontrôleur ATmega328P

Connaissez-vous le Watchdog Arduino ? Savez-vous à quoi il peut servir, ou comment le piloter à partir d’un programme arduino ? C’est ce que je vous propose de découvrir ici ! Ainsi, nous allons voir ensemble son intérêt pratique, son fonctionnement « détaillé », et son pilotage logiciel, au travers de plusieurs exemples de code.

Aussi, je vais essayer de vous présenter tout ceci graduellement, en vulgarisant un maximum de choses. Car apprendre à dompter le watchdog (littéralement « chien de garde », en français) n’est pas forcément chose facile, au premier abord. Surtout lorsqu’on s’aperçoit que le « bootloader » des plaquettes Arduino (Uno, Nano, Mega, …) peut venir altérer le bon fonctionnement de celui-ci. Mais rassurez-vous, car nous allons voir tout ceci pas à pas, une chose après l’autre 😉

Ce contenu vous plaît ? Alors abonnez-vous à la Newsletter pour ne rien louper !

À noter que chaque microcontrôleur a son watchdog « bien à lui », si je puis dire. C’est pourquoi le paramétrage du celui-ci peut différer d’un µC à l’autre. Du coup, je vais parler de manière très générale au début, puis rapidement passer sur un microcontrôleur en particulier (en l’occurrence : l’ATmega328P, qui équipe nos classiques Arduino Uno et Nano). Du reste, n’hésitez pas à poser vos questions en zone commentaire, si besoin est ! Je vous aiderais au possible, mais comme toujours, dans la limite du temps dont je dispose, et bien évidemment, dans les limites de mes connaissances et compétences !

Intro : qu’est-ce qu’un chien de garde (watchdog) ? et à quoi ça sert ?

S’il y a bien une chose surprenante avec les microcontrôleurs, lorsqu’on les découvre, c’est la notion de « chien de garde ». Car on ne voit pas vraiment le rapport entre l’animal, … et l’électronique 😉

En fait, si je devais en donner une définition simple, je vous dirais que le chien de garde (aussi appelé « Watch Dog », en anglais) est tout simplement un dispositif intégré à la plupart des microcontrôleurs, qui permet d’effectuer des opérations particulières, au bout d’un certain temps, lorsqu’il est activé. En somme, il ne s’agit ni plus ni moins que d’un compteur temps, qui compte jusqu’au point de déclencher une action particulière ; mais cela, uniquement lorsqu’il est actif. À noter que la plupart du temps, le chien de garde est désactivé au démarrage des microcontrôleurs (attention, ce n’est pas du tout une généralité).

Mais quel rapport avec l’animal, me direz-vous ? En fait, si on a donné un tel nom à un tel compteur, c’est tout simplement parce qu’il permet de surveiller ce qui se passe (tel un « chien de garde »), et d’agir en cas de « problème » (comme le fait d’aboyer). On a donc choisi ce nom, car il était représentatif de sa fonction « principale ».

Cela étant dit, son rôle ne se limite pas à de la surveillance, et le chien de garde n’agit pas nécessairement en fonction de la présence ou non d’un problème (mais comme tel était son usage courant au début, il a gardé ce nom là). En fait, voici à quoi peut servir un chien de garde, et dans quels cas on l’utilise en pratique, couramment :

  • Réinitialiser le microcontrôleur, en cas de plantage logiciel (ou boucle infinie)
  • Déclencher une interruption au bout d’un certain temps, pour effectuer des opérations particulières, telles que :
    • la mise à l’arrêt de moteurs électriques en cas de problème, par exemple
    • la sauvegarde de données après « bug » logiciel
    • l’exécution de tâches programmées, à intervalles réguliers

À présent, attention à ce qui suit ! Car c’est sans doute le plus important, mais aussi ce qui peut le plus vous gêner au début : dans les applications courantes de surveillance par le chien de garde, on active le compteur temps du chien de garde (le « Watch Dog Timer », en anglais), puis on va tout faire pour qu’il n’arrive jamais à compter jusqu’au bout ! Absurde ? Pas du tout, en fait !

Pour bien comprendre la mise en pratique de la phrase précédente, je vais vous prendre un exemple : imaginons que vous ayez une sonde à interroger ; et qu’en temps normal, celle-ci vous réponde en 200 ms, maximum. Eh bien, l’intérêt ici serait d’activer le watchdog juste avant (avec un déclenchement au bout de 1 seconde, par exemple), et de couper le watchdog une fois que la sonde aura répondu. Ici, il y a 2 cas de figure :

  • soit la sonde a répondu en moins d’une seconde : dans ce cas, le watchdog n’aura pas pu compter jusqu’au bout, car le programme a mis moins d’une seconde pour s’exécuter (ce qui correspond au fonctionnement normal, en fait, ici)
  • soit la sonde n’a pas répondu au bout d’une seconde, alors qu’elle aurait dû le faire en moins de 200 ms, ce qui signifie un problème. Dans ce cas, le watchdog aura eu le temps d’atteindre ses « 1 seconde » programmées, et donc, de déclencher une action (une alerte qui dirait par exemple : « attention, erreur lecture sonde »)

En clair, on active le plus souvent le watchdog pour vérifier qu’un bout de code programme ne mette pas plus d’un certain temps pour s’exécuter. C’est pourquoi on le met à zéro très régulièrement (à chaque boucle « loop » sur un arduino, par exemple), car si jamais le chien de garde arrive à compter jusqu’au bout, cela signifie que notre programme a « planté » en cours de route 😉

Ah oui, chose importante à savoir aussi : l’horloge qui fait avancer le watchdog est généralement indépendante de celle du microcontrôleur. Du coup, quelle que soit la fréquence de fonctionnement de son µC, le chien de garde comptera toujours à la même vitesse. Au final, le watchdog est donc un « sous-système » à la fois intégré au microcontrôleur, et indépendant du reste.

Du coup, voilà ce qu’il faut retenir :

  • un chien de garde (watchdog) est un compteur perpétuel qui, si activé, peut exécuter certaines opérations au bout d’un certain temps
  • les opérations qu’il peut faire sont soit un RESET du microcontrôleur, soit le déclenchement d’une INTERRUPTION logicielle (permettant d’exécuter du code particulier)
  • une fois arrivé au bout, le compteur temps du chien de garde (aussi appelé Watch Dog Timer, ou WDT) repart à zéro, et reprend son comptage
  • un plantage logiciel n’affecte la plupart du temps en rien le fonctionnement du watchdog, qui possède sa propre horloge interne (ce qui lui permet d’agir en conséquence, le cas échéant)

Par contre, il faut savoir que la « durée avant déclenchement » d’un chien de garde n’est pas paramétrable avec n’importe quelle valeur. En fait, vous devrez choisir parmi toutes les durées que nous met à disposition le fabricant, … et rien d’autre ! Pour connaître toutes les durées possibles (appelées « Time Out », en anglais), il suffira simplement d’aller les retrouver dans le datasheet du fabricant.

Le saviez-vous ? le watchdog a une autre utilité bien particulière, et qui vous parlera très certainement, j’en suis sûr ! Il s’agit du redémarrage du microcontrôleur en mode « sans échec », après un plantage logiciel (mode à coder soi-même, bien entendu). Ainsi, on pourrait imaginer faire exécuter du code particulier au redémarrage du µC, en fonction du cas où le reset proviendrait de la mise sous tension « normale » du microcontrôleur, ou d’une anomalie détectée par le watchdog. Pour illustrer cela : imaginez un système hydraulique ou motorisé, qui rencontre un problème imprévu ; s’il est judicieusement programmé, le chien de garde générerait le RESET du µC, et ce dernier, remarquant que ce reset est issu du watchdog, mettrait en sécurité tous les éléments (hydrauliques, électriques, …), puis enverrait un SMS d’alerte au technicien d’astreinte, pour qu’il vienne jeter un coup d’œil à l’installation en défaut ! Avouez que ça ouvre pas mal de perspectives, non ?

Le Watchdog de l’ATmega328P (Arduino Uno, Nano, …)

À présent, prenons le cas du Watchdog de l’ATmega328P (microcontrôleur embarqué sur les Arduino Uno, Nano, …), histoire de pouvoir vous parler plus précisément du chien de garde !

Pour commencer, voyons comment le chien de garde s’intègre au reste du microcontrôleur (exemple d’un ATmega328P « classique », fonctionnant sur quartz externe) :

Indépendance chien de garde vis à vis du microcontrôleur, exemple avec ATmega328P, horloge externe 16 MHz et oscillateur RC interne à 128 kHz

Comme vous le remarquez, le chien de garde a sa propre horloge de fonctionnement interne. Ceci permet au watchdog de fonctionner indépendamment du reste, et donc, quelle que soit la vitesse de fonctionnement du µC (1MHz, 8 MHz, 16 MHz, …).

Autre remarque que l’on peut faire ici : le watchdog peut à tout moment enclencher le RESET du microcontrôleur, ou générer une interruption particulière, qui sera « prioritaire » sur l’exécution du programme arduino. Et comme le chien de garde fonctionne de manière autonome et « indépendante », aucun bug ou plantage logiciel ne saurait « perturber » le fonctionnement du watchdog (c’est d’ailleurs là tout son intérêt !).

Le saviez-vous ? le RESET logiciel est en fait une interruption, au même titre que les autres. Mais à ceci près que cette interruption est prioritaire sur toutes les autres.

Maintenant, examinons le watchdog arduino d’un peu plus près, afin de mieux comprendre son fonctionnement :

Fréquence watchdog arduino dans ATmega328P, prescaler du timer WDT avec division des 128 kHz par 2K à 1024K, généré par horloge interne RC

Tout d’abord, on voit que le signal de 128 kHz, cadençant le chien de garde, est ralenti selon un facteur prédéterminé (allant de 2.048 à 1.048.576, ici). Ceci permet d’obtenir des temps de déclenchement du watchdog suffisamment long, pour pouvoir les comparer au temps d’exécution du code, qui se trouve par exemple dans notre « boucle principale arduino ».

Pour être plus explicite, voici au bout de combien de temps se déclencherait le watchdog, une fois lancé, selon le rapport de division de fréquence choisi :

Fréquence de baseRapport de divisionDivision réelle de fréquence parFréquence obtenueTemps au bout duquel se déclenche le watchdog (1/freq)
128 kHz2K204862,5 Hz0,016 s (soit 16 ms)
128 kHz4K409631,25 Hz0,032 s
128 kHz8K819215,62 Hz0,064 s
128 kHz16K163847,812 Hz0,128 s
128 kHz32K327683,906 Hz0,256 s
128 kHz64K655361,953 Hz0,512 s
128 kHz128K1310720,976 Hz1,024 s (~1 sec)
128 kHz256K2621440,488 Hz2,048 s
128 kHz512K5242880,244 Hz4,096 s
128 kHz1024K10485760,122 Hz8,192 s

Du coup, selon le rapport de division de fréquence que vous choisirez, vous pourrez faire déclencher le Watchdog Arduino au bout de 16 ms à 8 secondes, environ. En clair, si vos lignes de code arduino mettent plus de temps à s’exécuter que le temps que vous aurez préalablement choisi dans le watchdog, alors cela signifiera qu’il y aura eu une anomalie de fonctionnement. Et donc, cela nécessitera par exemple l’exécution d’une procédure de mise en sécurité (l’arrêt de moteurs en cas d’anomalie, par ex).

Le paramétrage du temps de déclenchement du watchdog (nommé « timeout », en anglais) se définit dans le registre WDTCSR de l’ATmega328P, qui est en fait le registre de contrôle du chien de garde. Ici, ce sont les bits WDP3, WDP2, WDP1, et WDP0, qui permettent de choisir un délai de déclenchement, parmi tous ceux possibles :

Registre WDTCSR arduino watchdog atmega328p, avec bits WDIF et WDIE pour interruption, WDP3 WDP2 WDP1 et WDP0 pour programmation fréquence

Au passage, ce registre permet bien d’autres choses encore, notamment en touchant aux bits WDE et WDIE :

  • le watchdog peut être activé ou désactivé, au besoin (inactif par défaut, avec l’ATmega328P) ; cela se fait en mettant les bits WDE et WDIE à 0
  • la watchdog peut déclencher une interruption, un RESET, ou bien une interruption suivie d’un reset (suivant nos besoins), en jouant sur les bits WDE (qui gère le « reset ») et WDIE (qui gère les « interruptions »)

À noter que la modification de ces bits ne se fait pas n’importe comment, et qu’il y a un « protocole » à respecter. En effet, il sera nécessaire de mettre tout d’abord les bits WDE et WDCE à 1, pour demander la permission au microcontrôleur de pouvoir modifier ces bits. Puis on pourra modifier les bits qui nous intéressent, parmi ceux modifiables. Mais il faudra faire cela dans un délai maximal correspondant à 4 coups d’horloge processeur, pour que ce soit pris en compte. Du reste, nous verrons cela plus en détail ensemble, dans les exemples 2 et 3, présentés plus bas.

Enfin, il y a un second registre à connaître, mais qui lui est plus d’intérêt pratique : le registre MCUSR. Il s’agit en fait du registre de statut du microcontrôleur ATmega328P. Ce registre indique en fait qui est à l’origine du RESET du µC. Il se présente sous la forme suivante :

Registre MCRUSR de l'ATmega328P, montrant les bits WDRF BORF EXTRF et PORF, pour origine reset, par exemple chien de garde du timer watchdog arduino

Ce registre permet donc de dire :

  • si le RESET provient du Watchdog Arduino (dans ce cas, le bit WDRF sera à 1)
  • si le RESET provient d’un Brown-Out, c’est-à-dire d’une tension d’alimentation qui est devenue trop faible (dans ce cas, le bit BORF sera à 1)
  • si le RESET provient du bouton RESET externe, ou équivalent (dans ce cas, le bit EXTRF sera à 1)
  • si le RESET provient d’un Power-On reset, c’est-à-dire du reset normal qui s’opère à la mise sous tension de l’arduino (dans ce cas, le bit PORF sera à 1)

Remarque importante : à noter que le fonctionnement de ce registre MCUSR peut être altéré si votre microcontrôleur dispose d’un bootloader (petit programme inséré à la fin de la mémoire programme d’un arduino, permettant le téléchargement « simplifié » d’autres programmes, au démarrage du µC). En effet, si vous faites des essais, vous constaterez que ce registre est toujours à 0, ou ne correspond en rien à la réalité. Toutefois, si vous utilisez un microcontrôleur ATmega328P en dehors d’une carte arduino, et sans bootloader chargé dessus, le registre MCUSR devrait être 100% fonctionnel !

Librairie WDT (Watch Dog Timer) de l’IDE Arduino

Pour contrôler le Watchdog, il suffit de manipuler les registres vus précédemment. Ceci peut se faire de 2 manières :

  • soit en manipulant directement les bits du registre WDTCSR, relatif au Watchdog
  • soit en utilisant, par exemple, la librairie WDT (Watch Dog Timer), fournie nativement dans l’IDE Arduino

Je vous montrerai d’ailleurs comment vous servir de l’un et l’autre, dans les exemples qui suivent, un peu plus bas. Mais pour l’heure, voyons ensemble la librairie WDT, qui est selon moi très pratique, si vous débutez avec le watchdog arduino !

Initialisation de la librairie wdt.h

Comme toujours, afin de pouvoir accéder aux fonctions d’une librairie, il est indispensable de l’inclure à son projet. Pour cela, il suffit d’écrire la ligne suivante, en tête de votre programme arduino :

#include <avr/wdt.h>

Ainsi, vous pourrez avoir accès à toutes les fonctionnalités qu’offre cette bibliothèque (qui, pour rappel, est nativement fournie avec l’IDE Arduino ; donc nul besoin de chercher à l’installer, via le gestionnaire de bibliothèque, ou autre !).

Activation du « compteur temps » du chien de garde (via la fonction « wdt_enable »)

Pour activer le timer du watchdog (compteur du chien de garde), la librairie wdt.h nous met à disposition la fonction « wdt_enable ». Cette fonction prend en argument la durée avant déclenchement d’une action, une fois le watchdog « démarré ».

La durée spécifiable ici correspond à l’une des valeurs possibles, spécifiées par le fabricant (en arrondissant quelque peu ces valeurs dans le code, pour que ce soit plus explicite). D’ailleurs, les voici :

Argument possible (fonction wdt_enable)Durée du Timeout correspondant
WDTO_15MS16 ms
WDTO_30MS32 ms
WDTO_60MS64 ms
WDTO_120MS128 ms
WDTO_250MS256 ms
WDTO_500MS512 ms
WDTO_1S1,024 s
WDTO_2S2,048 s
WDTO_4S4,096 s
WDTO_8S8,192 s
Nota : WDTO = Watch Dog Time Out (soit, le délai avant déclenchement d’une action par le chien de garde, une fois lancé)

Du coup, au niveau du code arduino, voici comment activer le timer du watchdog arduino, avec cette librairie :

wdt_enable(WDTO_15MS);         // Pour un time-out à 16 ms
wdt_enable(WDTO_30MS);         // Pour un time-out à 32 ms
wdt_enable(WDTO_60MS);         // Pour un time-out à 64 ms
wdt_enable(WDTO_120MS);        // Pour un time-out à 128 ms
wdt_enable(WDTO_250MS);        // Pour un time-out à 256 ms
wdt_enable(WDTO_500MS);        // Pour un time-out à 512 ms
wdt_enable(WDTO_1S);           // Pour un time-out à 1 seconde
wdt_enable(WDTO_2S);           // Pour un time-out à 2 secondes
wdt_enable(WDTO_4S);           // Pour un time-out à 4 secondes
wdt_enable(WDTO_8S);           // Pour un time-out à 8 secondes

Bien sûr, il ne faut mettre qu’une seule de ces lignes, en fonction du temps à partir duquel vous souhaitez que le watchdog déclenche une action particulière 😉

Reset du watchdog, pour remettre à zéro son timer (via la fonction « wdt_reset »)

Une des choses les plus importantes, lorsqu’on utilise un chien de garde, c’est bien évidemment son « reset » (remise à zéro de son « compteur temps »). Car on souhaite presque toujours pouvoir le remettre à zéro le plus souvent possible, afin que celui-ci n’arrive jamais « au bout de son comptage », sans raison (sinon, cela signifierait qu’il y aurait eu une « erreur », qu’il faudrait donc traiter).

Pour remettre à zéro le Watch Dog Timer (WDT) à chaque fois qu’on le souhaite, il suffit d’utiliser la fonction « wdt_reset ». Ainsi, le timer du chien de garde est remis à zéro, et recommence à compter. Et ce, jusqu’au moment où le programme rencontrerait un problème, et que la remise à zéro n’aurait pas pu se faire avant que le timer n’atteigne sa limite de durée, signalant ainsi un « problème » à considérer.

Cette fonction ne prend pas d’argument, et s’appelle tout simplement de la manière suivante :

wdt_reset();

Elle peut être utilisée n’importe où dans le code, du moment où vous avez inclus la librairie wdt.h dans votre programme arduino.

Désactivation du timer du watchdog (via la fonction « wdt_disable »)

Enfin, si vous souhaitez arrêter le comptage du watchdog (pour qu’il ne déclenche ni reset ni interruption), il suffit pour cela de le désactiver, grâce à la fonction « wdt_disable ». Cela se fait en une ligne, via la commande suivante :

wdt_disable();

Ainsi, votre programme arduino continuera à tourner, mais désormais, sans plus la moindre « surveillance » du chien de garde (ce qui peut être nécessaire, si par exemple vous exécutez des tâches de longue durée, qui n’indiquent pas forcément un problème de fonctionnement).

Pour plus d’infos sur cette librairie, vous pouvez consulter cette page, au sujet des librairies AVR.

Exemple de code #1 : provoquer le RESET du microcontrôleur, grâce au chien de garde

En guise de premier exemple, je vous propose de découvrir un code arduino permettant de forcer le RESET du microcontrôleur, si jamais le temps d’exécution de la boucle « loop » prend plus d’une seconde. Au passage, ce genre d’application est très couramment utilisé au niveau des automates programmables, afin que ceux-ci puissent redémarrer, si jamais quelque chose venait à planter (et ce, afin de ne pas rester bloqué, dans une « mauvaise posture »).

Pour cela, nous allons bien évidemment nous servir du watchdog arduino, en calibrant son timeout sur 1 seconde. Ainsi, un RESET sera demandé au microcontrôleur par le chien de garde, si jamais on arrive à ces 1 seconde de délai. Et pour que cela n’arrive jamais, « en temps normal », nous allons périodiquement remettre le timer du watchdog à zéro (c’est-à-dire effectuer un reset du timer du chien de garde).

Aussi, pour simuler un problème logiciel, nous allons volontairement allonger, petit à petit, le délai d’exécution de la boucle « loop », de notre programme. Ce faisant, le watchdog détectera une anomalie au bout d’un certain temps, et plus précisément, dès lors que la durée du temps d’exécution de cette partie du code excède nos 1 seconde.

Nota : attention de ne pas mélanger « RESET du watchdog », qui correspond à la remise à zéro de son compteur de temps (son timer, donc), avec le « RESET du microcontrôleur », qui correspond au redémarrage complet du µC. Car on emploie souvent le même terme pour désigner 2 choses différentes, et il s’agit de ne pas se mélanger les pinceaux ici 😉

Au niveau du code de programmation, voici ce que cela donne :

/*
   ______               _                  _///_ _           _                   _
  /   _  \             (_)                |  ___| |         | |                 (_)
  |  [_|  |__  ___  ___ _  ___  _ __      | |__ | | ___  ___| |_ _ __ ___  _ __  _  ___  _   _  ___
  |   ___/ _ \| __|| __| |/ _ \| '_ \_____|  __|| |/ _ \/  _|  _| '__/   \| '_ \| |/   \| | | |/ _ \
  |  |  | ( ) |__ ||__ | | ( ) | | | |____| |__ | |  __/| (_| |_| | | (_) | | | | | (_) | |_| |  __/
  \__|   \__,_|___||___|_|\___/|_| [_|    \____/|_|\___|\____\__\_|  \___/|_| |_|_|\__  |\__,_|\___|
                                                                                      | |
                                                                                      \_|
  Fichier :       prgTestWatchDogArduino-1-modeReset.ino
  
  Description :   Programme permettant de tester le chien de garde d'un ATmega328P, équipant par exemple un Arduino Uno,
                  et plus particulièrement le "mode reset"
                  
  Auteur :        Jérôme TOMSKI (https://passionelectronique.fr/)
  Créé le :       09.01.2021

*/

// Librairies utiles
#include <avr/wdt.h>      // Librairie indispensable ici, mais ne nécessitant pas la moindre installation (fournie avec l'IDE arduino)

// Variables
int tempsDePauseProgramme = 100;      // On définit un "temps de pause" de 100 ms, qui sera exécuté à chaque passage dans la boucle loop de notre programme
int multiplicateurDePause = 1;        // … et un "coefficient multiplicateur", qui rallongera ce temps de pause, à chaque passage en boucle loop également
                                      // -------> Ainsi : on aura 100ms d'attente au 1er passage dans la boucle loop, puis 200ms, puis 300ms, etc…

// ========================
// Initialisation programme
// ========================
void setup() {

  // Initialise la liaison série (Arduino -> PC)
  Serial.begin(9600);
  Serial.println("");
  Serial.println(F("======================================================================================================="));
  Serial.println(F("PRG1 - Test du 'mode reset' du chien de garde (WatchDog) d'un ATmega328P (Arduino Uno, par exemple)"));
  Serial.println(F("       avec déclenchement du RESET du µc si délai d'exécution programme supérieur à 1 seconde dans loop"));
  Serial.println(F("======================================================================================================="));
  Serial.println(F("Démarrage du programme…"));

  // ************************************************************************************
  // ACTIVATION DU CHIEN DE GARDE
  // (avec déclenchement au bout de 1 seconde, dans cet exemple)
  // ************************************************************************************
  // Pour cela, on utilise la fonction "wdt_enable", qui prend en argument le "temps voulu",
  // parmi ces 10 valeurs possibles (issue de la librairie arduino "/avr/wdt.h") :
  //    WDTO_15MS
  //    WDTO_30MS
  //    WDTO_60MS
  //    WDTO_120MS
  //    WDTO_250MS
  //    WDTO_500MS
  //    WDTO_1S
  //    WDTO_2S
  //    WDTO_4S
  //    WDTO_8S
  delay(1000);
  wdt_enable(WDTO_1S);

  // *****************************************************************************************************
  // Reset du chien de garde, pour mettre son "compteur temps" à zéro, avant d'attaquer la "fonction loop"
  // *****************************************************************************************************
  wdt_reset();
}

// =================
// Boucle principale
// =================
void loop() {
  
  // Calcul du délai de mise en pause du programme (au début 1x100 ms, puis 2x100ms, puis 3x100ms, etc.)
  int delaiDeMiseEnPause = tempsDePauseProgramme * multiplicateurDePause;

  // Affichage du temps de pause qui va s'exécuter, sur le moniteur série de l'IDE arduino
  Serial.print("→ durée de pause lancée = ");
  Serial.print(delaiDeMiseEnPause);
  Serial.println(" ms");

  // Exécution de la "pause programme"
  delay(delaiDeMiseEnPause);

  // À chaque bouclage de la fonction loop, on augmente la valeur de la variable "multiplicateurDePause", pour rallonger la durée de "pause programme" précédente
  multiplicateurDePause++;

  // Enfin, juste avant chaque rebouclage, on remet à zéro le "compteur temps" du chien de garde
  // ------> ici, 2 cas de figure possibles :
  //              - soit le temps d'exécution de cette "fonction loop entière" a été plus rapide que le comptage du chien de garde,
  //                et donc le programme s'est déroulé normalement jusqu'ici ; ainsi, on remet à zéro le compteur du chien de garde, et on reboucle
  //              - soit le chien de garde a déclenché un reset du µC entre temps, car la pause au sein du programme a été trop longue,
  //                et donc on a eu un RESET du microcontrôleur entre temps
  wdt_reset();

}

Et une fois ce code uploadé dans votre arduino, vous n’aurez plus qu’à ouvrir le moniteur série de votre IDE arduino pour voir le résultat. D’ailleurs, voici ce que j’obtiens de mon côté :

Exemple code reset arduino via watchdog programmé toutes les secondes, pour redémarrage microcontrôleur par chien de garde du ATmega328P

Comme vous pouvez le constater : dès lors que la durée d’exécution de la boucle loop dépasse 1 seconde, l’arduino est réinitialisé, et le programme redémarre. Ceci montre bien qu’il y a eu un « RESET » qui s’est opéré, à un moment bien précis. Et comme nous avons programmé le watchdog timer en ce sens, cela prouve bien qu’il surveille le bon fonctionnement du programme, et agit en cas d’anomalie. Car tant que le temps d’exécution des boucles loop durent moins d’une seconde, tout se déroule normalement !

Pour rappel, ce genre de programme est particulièrement intéressant dans le cas où l’exécution du code pourrait se « figer » en quelque part (dans l’attente d’un retour de valeur d’un capteur, par exemple). Car en provoquant un RESET, on peut potentiellement débloquer une situation anormale. Bien entendu, ceci n’est pas parfait en l’état, car si un blocage a eu lieu à un moment donné, il est fort probable qu’il revienne dans le futur. Du coup, l’intérêt serait plutôt d’exécuter du code particulier, en cas de « plantage » du programme principal. C’est d’ailleurs ce que nous allons voir à présent, avec les interruptions watchdog !

Important : le code ci-dessus ne fonctionnera pas sur tous les arduino. Car comme évoqué plus haut, le « bootloader » arduino (petit programme « d’aide » à la programmation du microcontrôleur) peut altérer le fonctionnement du watchdog. C’est pourquoi le programme ci-dessus pourrait fonctionner avec certains Arduino, et pas d’autres. Pour vous donner quelques repère (là où ça marche, et là où ça ne marche pas), voici quelques exemples :
ce programme exemple ne fonctionnera pas avec un « Arduino Nano (old bootloader) » (car ici, le fichier bootloader est un « atmega/ATmegaBOOT_168_atmega328.hex »)
ce programme exemple fonctionnera sur les « Arduino Nano » plus récents, et « Arduino Uno » (dans ce cas, le fichier bootloader est un « optiboot/optiboot_atmega328.hex »)

Pour info : pour connaître le bootloader « normalement logé » dans votre carte arduino, il suffit de jeter un coup d’œil à ce fichier, pour être renseigné (même si, bien évidemment, cela ne vous dira pas précisément ce que votre vendeur vous aura « refourgué » !)

Exemple de code #2 : générer une INTERRUPTION logicielle, grâce au watchdog

Ici, nous allons voir quelque chose qui, selon moi, est bien plus utile qu’un simple reset. Il s’agit du mécanisme d’interruption, que peut piloter le watchdog. En effet, le chien de garde peut parfaitement être « programmé » afin qu’il déclenche une interruption, au bout d’un certain temps. Ainsi, on peut exécuter tout un tas de lignes de code, en cas, par exemple, d’anomalie au niveau de la durée d’exécution de notre programme.

Et si vous cherchez un exemple typique d’application d’une telle sécurité, en voici une : la mise à l’arrêt de moteur électrique, en cas de plantage logiciel. Dans ce cas, par exemple, le microcontrôleur pourra exécuter une série d’actions, visant à couper l’alimentation des moteurs, plutôt que « bêtement » les laisser tourner à fond !

Ici, je vais vous présenter un exemple de code arduino qui boucle indéfiniment, et va permettre de mettre en évidence les interruptions régulières du watchdog, lorsqu’elles sont activées. Pour cela, nous allons simplement activer le chien de garde en début de programme, lui indiquer un temps au bout duquel il devra provoquer une interruption, et laisser la boucle « loop » vide, pour qu’elle se répète indéfiniment. Ce faisant, vous verrez une interruption survenir, et même, se répéter au fil du temps ! Car tant que le watchdog est actif, son timer continue à compter (et ce, jusqu’à ce qu’il soit désactivé). Du coup, comme le timer du watchdog n’est jamais remis à zéro, l’interruption se répètera indéfiniment, elle aussi.

Pour réaliser tout cela, voici le code de programmation que je vous propose d’exécuter :

/*
   ______               _                  _///_ _           _                   _
  /   _  \             (_)                |  ___| |         | |                 (_)
  |  [_|  |__  ___  ___ _  ___  _ __      | |__ | | ___  ___| |_ _ __ ___  _ __  _  ___  _   _  ___
  |   ___/ _ \| __|| __| |/ _ \| '_ \_____|  __|| |/ _ \/  _|  _| '__/   \| '_ \| |/   \| | | |/ _ \
  |  |  | ( ) |__ ||__ | | ( ) | | | |____| |__ | |  __/| (_| |_| | | (_) | | | | | (_) | |_| |  __/
  \__|   \__,_|___||___|_|\___/|_| [_|    \____/|_|\___|\____\__\_|  \___/|_| |_|_|\__  |\__,_|\___|
                                                                                      | |
                                                                                      \_|
  Fichier :       prgTestWatchDogArduino-2-modeInterrupt.ino
  
  Description :   Programme permettant de tester le "mode d'interruption" du chien de garde d'un ATmega328P,
                  d'un Arduino Uno branché sur le moniteur série d'un PC
                  
  Auteur :        Jérôme TOMSKI (https://passionelectronique.fr/)
  Créé le :       18.01.2021

*/


// Remarque : aucune librairie utilisée ici !

// =========================================
// Routine d'interruption (liée au watchdog)
// =========================================
ISR(WDT_vect) {
  Serial.println("→ Interruption logicielle, déclenchée par le Watchdog !");
}

// ========================
// Initialisation programme
// ========================
void setup() {

  // Initialisation de la liaison série
  Serial.begin(9600);
  Serial.println(F("======================================================================================="));
  Serial.println(F("PRG2 - Test du 'mode interruption' du chien de garde d'un ATmega328P (Arduino Uno, ici)"));
  Serial.println(F("======================================================================================="));
  Serial.println(F("Démarrage du programme…"));
  Serial.println("");

  // ******************************************************************************************************************
  // TABLEAU DE CORRESPONDANCE ENTRE BITS WDP3..0 ET DÉLAI AVANT INTERRUPTION
  // ******************************************************************************************************************
  //  WDP3  | WDP2  | WDP1  | WDP0  | Nombre de cycles (oscillateur 128kHz du WDT) | Délai avant activation du WatchDog
  //    0   |   0   |   0   |   0   |    2K (soit    2048 cycles)                  | 16 ms
  //    0   |   0   |   0   |   1   |    4K (soit    4096 cycles)                  | 32 ms
  //    0   |   0   |   1   |   0   |    8K (soit    8192 cycles)                  | 64 ms
  //    0   |   0   |   1   |   1   |   16K (soit   16384 cycles)                  | 125 ms
  //    0   |   1   |   0   |   0   |   32K (soit   32768 cycles)                  | 250 ms
  //    0   |   1   |   0   |   1   |   64K (soit   65536 cycles)                  | 500 ms
  //    0   |   1   |   1   |   0   |  128K (soit  131072 cycles)                  | 1 sec
  //    0   |   1   |   1   |   1   |  256K (soit  262144 cycles)                  | 2 sec
  //    1   |   0   |   0   |   0   |  512K (soit  524288 cycles)                  | 4 sec
  //    1   |   0   |   0   |   1   | 1024K (soit 1048576 cycles)                  | 8 sec
  // ******************************************************************************************************************

  // -------> donc si on veut par exemple une interruption toutes les 4 secondes, il faudra alors mettre le bit WDP3 à 1, et les autres à 0
  
  
  // *******************************************************************************
  //  BITS DE CONFIGURATION DU WATCHDOG
  //                           (cf. page 47 du datasheet de l'ATmega328P)
  // *******************************************************************************
  //  Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
  //  WDIF  | WDIE  | WDP3  | WDCE  |  WDE  | WDP2  | WDP1  | WDP0
  // *******************************************************************************
  WDTCSR = (1 << WDCE) | (1 << WDE);          // Déverrouille les bits de configuration du Watchdog (procédure spécifiée par le fabricant)
  WDTCSR = 0b01100000;                        // Mise à 1 des bits WDP3 et WDIE, pour activer les interruption toutes les 4 secondes

      // Nota : on effectue cette modification de tous les bits à la fois, car cette modif doit se faire rapidement.
      //        En effet, le bit WDCE sera automatiquement remis à 0 par le microcontrôleur après 4 coups d'horloge
  
}

// =================
// Boucle principale
// =================
void loop() {

  // Bouclage infini !

}

Au passage, je vous montre ici une autre façon de prendre le contrôle du watchdog arduino. En effet, dans ce programme, ce sont les bits des registres de contrôle du watchdog qui sont directement manipulés. D’où le fait qu’aucune librairie n’est appelée ici.

Pour être plus précis, ce sont les bits du registre WDTCSR qui sont manipulés, avec l’ATmega328P. Car ce sont ces bits qui permettent de paramétrer le chien de garde à notre guise (ou presque !). À noter, au passage, que cela se passe en 2 temps (car il y a une subtilité ici, « imposée » par le fabricant) :

  • tout d’abord, il est indispensable de mettre les bits WDCE et WDE à 1, au niveau du registre WDTCSR, pour « déverrouiller » le registre WDTCSR en entier (sinon, les modifications de bits ne seront pas pris en compte)
  • ensuite seulement, nous pouvons configurer les bits qui nous intéressent (dans cet exemple, j’ai seulement mis à 1 les bits WDIE et WDP3, pour respectivement autoriser les interruptions du watchdog, et définir un timeout de 4 secondes)
  • enfin, la modif précédente doit se faire avant 4 coups d’horloge du microcontrôleur, car au-delà, le registre se « reverrouille » automatiquement, si je puis dire

Du reste, voici ce que l’on obtient une fois le programme uploadé et lancé, tel que visible sur le moniteur série de l’IDE Arduino :

Exemple interruption watchdog arduino toutes les 4 secondes, depuis moniteur série de l'IDE Arduino, avec visualisation chien de garde interrupt logiciel

Comme vous le voyez, les interruptions du watchdog arduino se répètent toutes les 4 secondes environ.

Ah oui, une remarque, au passage : vous avez sûrement dû remarquer que les « 4 secondes » d’intervalles ne correspondent pas exactement à 4 « vraies » secondes ! En fait, ceci est principalement dû au fait que l’horloge à 128 kHz de l’ATmega328P est obtenue via un « simple » oscillateur RC. Du coup, cela implique un défaut de précision, pouvant parfois atteindre plus ou moins 10%, suivant la tension d’alimentation qu’on utilise, et la température d’utilisation du µC. Donc ne cherchez pas à obtenir quelque chose d’ultra précis avec le watchdog arduino, car de par sa conception, il ne peut pas être précis par nature.

À présent, voyons un dernier exemple d’application du watchdog arduino : le réveil automatique du microcontrôleur à intervalles réguliers, pour faire des économies d’énergie !

Exemple de code #3 : mettre l’Arduino en mode sommeil (sleep), et le réveiller à intervalle régulier

Ici, je vais vous présenter quelque chose de vraiment différent. En ce sens où, le watchdog ne fera pas de « surveillance », à proprement parler, mais simplement un réveil périodique du microcontrôleur, qui sera mis le reste du temps en sommeil (pour économiser de l’énergie, par exemple).

Outre le fait de pouvoir vous montrer comment mettre en sommeil un Arduino, le but de cet exemple est aussi de vous montrer « l’indépendance » du timer du Watchdog, vis-à-vis du reste du microcontrôleur. Ainsi, vous verrez qu’on peut parfaitement mettre le µC en sommeil, puis le réveiller un peu plus tard, « de l’intérieur », via une interruption générée par le chien de garde.

Ceci est d’ailleurs un autre exemple typique d’application du watchdog : l’économie d’énergie. Car cela permet de laisser le microcontrôleur au repos la majeure partie du temps, et de le réveiller seulement de temps en temps, pour effectuer des tâches « brèves », avant de le rendormir. Ainsi, la consommation moyenne du µC sera vraiment abaissée, ce qui est idéal si vous travaillez par exemple sur batterie, et voulez que ces dernières durent le plus longtemps possible !

Pour illustrer tout cela, je vous propose le programme suivant, qui exécutera les tâches suivantes, de manière cyclique (perpétuel) :

  • allumage d’une LED pendant 10 secondes (histoire de symboliser les tâches qu’on peut faire, en temps « normal »)
  • activation du chien de garde (avec timeout fixé à 8 sec), afin de pouvoir déclencher une interruption 8 secondes plus tard
  • mise en sommeil du microcontrôleur (via la librairie « sleep »)
  • gestion de l’interruption du watchdog, qui réveillera le µC environ 8 secondes après sa mise en sommeil
  • et répéter cela indéfiniment !

Voici comment j’ai codé tout ça, au niveau du programme arduino (à noter que j’ai utilisé ici un Arduino Uno) :

/*
   ______               _                  _///_ _           _                   _
  /   _  \             (_)                |  ___| |         | |                 (_)
  |  [_|  |__  ___  ___ _  ___  _ __      | |__ | | ___  ___| |_ _ __ ___  _ __  _  ___  _   _  ___
  |   ___/ _ \| __|| __| |/ _ \| '_ \_____|  __|| |/ _ \/  _|  _| '__/   \| '_ \| |/   \| | | |/ _ \
  |  |  | ( ) |__ ||__ | | ( ) | | | |____| |__ | |  __/| (_| |_| | | (_) | | | | | (_) | |_| |  __/
  \__|   \__,_|___||___|_|\___/|_| [_|    \____/|_|\___|\____\__\_|  \___/|_| |_|_|\__  |\__,_|\___|
                                                                                      | |
                                                                                      \_|
  Fichier :       prgTestWatchDogArduino-3-sortieSleepMode.ino
  
  Description :   Programme permettant de sortir d'un état de mise en veille programmé, à intervals réguliers,
                  pour faire des économies d'énergie sur un Arduino Nano/Uno (microcontrôleur ATmega328P),
                  en utilisant le WatchDog interne au µC
                  
  Auteur :        Jérôme TOMSKI (https://passionelectronique.fr/)
  Créé le :       19.01.2021

*/

// Librairies utilisées
#include <avr/wdt.h>      // Librairie fournie avec l'IDE arduino (Watch Dog Timer)
#include <avr/sleep.h>    // Librairie fournie avec l'IDE arduino (Sleep)

// Variable qui mémorisera le fait qu'il y a eu une "interruption watchdog", et que le code de la routine associée a été exécuté
volatile bool routineInterruptionExecutee = false;    // Nota : on déclare cette variable en "volatile", pour pouvoir y accéder aussi bien
                                                      //        dans le programme, que dans la partie interruption (ISR)


// ========================
// Initialisation programme
// ========================
void setup() {

  // Initialisation de la liaison série
  Serial.begin(9600);
  Serial.println(F("================================================================================================="));
  Serial.println(F("PRG3 - Test d'interruptions watchdog pour sortir du sommeil un Arduino Uno, toutes les 8 secondes"));
  Serial.println(F("================================================================================================="));
  Serial.println(F("Démarrage du programme…"));
  Serial.println("");

}

// =================
// Boucle principale
// =================
void loop() {

  // À chaque passage dans cette boucle, on check l'état de la variable "routineInterruptionExecutee"
  //    --> si elle est égale à FALSE, alors cela veut dire qu'aucune interruption n'a encore été déclenchée par le chien de garde
  //    --> si elle est égale à TRUE, alors cela veut dire qu'une interruption watchdog a eu lieu
  
  if (!routineInterruptionExecutee) {
    allumeLedArduino10secondes();                   // Allumage de la LED embarquée sur l'Arduino, pendant 10 secondes
    activationDuWatchdog();                         // Configuration du Watch Dog Timer (WDT), pour qu'il produise une interruption au bout de 8 secondes
    miseEnSommeilDuMicrocontroleur();               // Mise du µC en sommeil (il sera réveillé ultérieurement, par l'interruption du watchdog)    
  } else {
    routineInterruptionExecutee = false;            // Si interruption exéctuée, on efface cette info
  }

}


// =========================================
// Routine d'interruption (liée au watchdog)
// =========================================
ISR(WDT_vect) {
  Serial.println("→ Réveil du µC, 8 secondes plus tard (par interruption Watchdog)");     // On affiche un message sur le moniteur série
  desactivationDuWatchdog();
  routineInterruptionExecutee = true;
}

// ================================
// Routine d'activation du Watchdog
// ================================
void activationDuWatchdog() {

  Serial.println("Activation du Watchdog (avec programmation d'une interruption, qui se déclenchera au bout de 8 secondes)");
  
  __asm__ __volatile__ ("wdr");           // On (re)met à zéro le compteur du watchdog, pour être "au plus juste"
                                          // (instruction écrite ici en assembleur, histoire de varier !)

  // *******************************************************************************
  //  BITS DE CONFIGURATION DU WATCHDOG
  //                           (cf. page 47 du datasheet de l'ATmega328P)
  // *******************************************************************************
  //  Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
  //  WDIF  | WDIE  | WDP3  | WDCE  |  WDE  | WDP2  | WDP1  | WDP0
  // *******************************************************************************

  WDTCSR = (1 << WDCE) | (1 << WDE);          // Déverrouille les bits de configuration du Watchdog (procédure spécifiée par le fabricant)

  // ******************************************************************************************************************
  // TABLEAU DE CORRESPONDANCE ENTRE BITS WDP3..0 ET DÉLAI AVANT INTERRUPTION
  // ******************************************************************************************************************
  //  WDP3  | WDP2  | WDP1  | WDP0  | Nombre de cycles (oscillateur 128kHz du WDT) | Délai avant activation du WatchDog
  //    0   |   0   |   0   |   0   |    2K (soit    2048 cycles)                  | 16 ms
  //    0   |   0   |   0   |   1   |    4K (soit    4096 cycles)                  | 32 ms
  //    0   |   0   |   1   |   0   |    8K (soit    8192 cycles)                  | 64 ms
  //    0   |   0   |   1   |   1   |   16K (soit   16384 cycles)                  | 125 ms
  //    0   |   1   |   0   |   0   |   32K (soit   32768 cycles)                  | 250 ms
  //    0   |   1   |   0   |   1   |   64K (soit   65536 cycles)                  | 500 ms
  //    0   |   1   |   1   |   0   |  128K (soit  131072 cycles)                  | 1 sec
  //    0   |   1   |   1   |   1   |  256K (soit  262144 cycles)                  | 2 sec
  //    1   |   0   |   0   |   0   |  512K (soit  524288 cycles)                  | 4 sec
  //    1   |   0   |   0   |   1   | 1024K (soit 1048576 cycles)                  | 8 sec          <----- mode choisi
  // ******************************************************************************************************************
  
  WDTCSR = 0b01100001;          // Mise à 1 du bit WDIE (autorisant les "interruptions watchdog")
                                // ainsi que les bits WDP3 et WDP0, pour une interruption toutes les 8 secondes
}

// ====================================
// Routine de désactivation du Watchdog
// ====================================
void desactivationDuWatchdog() {

  Serial.println("Désactivation du Watchdog");
  
  // *******************************************************************************
  //  BITS DE CONFIGURATION DU WATCHDOG
  //                           (cf. page 47 du datasheet de l'ATmega328P)
  // *******************************************************************************
  //  Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
  //  WDIF  | WDIE  | WDP3  | WDCE  |  WDE  | WDP2  | WDP1  | WDP0
  // *******************************************************************************

  WDTCSR = (1 << WDCE) | (1 << WDE);      // Déverrouille les bits de configuration du Watchdog (procédure spécifiée par le fabricant)
  WDTCSR = 0b00000000;                    // Mise à 0 des bits WDIE et WDE, pour désactiver le timer du chien de garde
  
}

// ==========================================
// Routine de mise en sommeil de l'ATmega328P
// ==========================================
void miseEnSommeilDuMicrocontroleur(void) {
  // Au passage, il y a 5 différents modes de mise en sommeil d'un arduino, pour économiser de l'énergie :
  //   - le mode SLEEP_MODE_IDLE (celui qui économise le moins d'énergie)
  //   - le mode SLEEP_MODE_ADC
  //   - le mode SLEEP_MODE_PWR_SAVE
  //   - le mode SLEEP_MODE_STANDBY
  //   - le mode SLEEP_MODE_PWR_DOWN (celui qui économise le plus d'énergie)

  // Ici, on active la mise en sommeil "SLEEP_MODE_PWR_DOWN"
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  // Et on met le µC en sommeil maintenant
  Serial.println("Mise en sommeil du µC");
  Serial.println("");
  Serial.flush();         // On attend la fin de la transmission des données séries, avant de mettre le microcontrôleur en sommeil
  sleep_mode();

  // …
  // le programme va reprendre à partir d'ici, une fois le microcontrôleur réveillé par le Watchdog (et après avoir exécuté l'interruption correspondante)
  // …

  // Puise on désactive le mode sommeil, et on continue le programme
  Serial.println("Suite du programme arduino…");     // On affiche un message sur le moniteur série
  sleep_disable();
  
}

// ==============================================
// Routine d'allumage de la LED embarquée arduino
// ==============================================
void allumeLedArduino10secondes(void) {
  
  Serial.println("Allumage de la LED embarquée sur l'arduino (pendant 10 secondes)");

  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(10000);
  digitalWrite(LED_BUILTIN, LOW);

  Serial.println("Extinction de la LED");

}

Une fois que vous aurez téléversé ce code de programmation dans votre arduino, et que vous aurez ouvert votre moniteur série, vous devriez obtenir quelque chose qui ressemble à cela :

Exemple réveil sleep arduino avec watchdog atmega328p à intervalle régulier, grâce à interruption logicielle depuis programme codé avec script fonctionnement

Au passage, j’ai activé l’horodatage du moniteur série, afin que vous puissiez bien voir comment se déroulent les choses, dans le temps.

Comme vous le remarquez, le microcontrôleur « s’endort » environ 8 secondes, avant d’être réveillé par le chien de garde. Et comme vu tout à l’heure, ces 8 secondes sont approximatives, du fait que l’horloge du chien de garde de l’ATmega328P n’est pas si précise que ça !

Nota : j’ai mis 10 secondes d’allumage pour la LED, histoire d’avoir un temps d’occupation du µC qui soit supérieur aux 8 secondes du timeout du watchdog. Ainsi, vous pourrez constater que les interruptions du chien de garde sont ici bien désactivées, pendant le fonctionnement « hors sommeil » du microcontrôleur.

Voilà qui conclue les exemples que j’avais à vous partager ici, afin de pouvoir faire vos premiers pas avec le watchdog arduino 😉

Watchdog Arduino : conclusion !

J’espère tout d’abord que toutes les explications que je vous ai fournies ici, au sujet du watchdog arduino, étaient suffisamment claires et limpides, pour vous ! Et si ce n’est pas le cas, je vous prie de bien vouloir m’en excuser. En fait, le « chien de garde » est quelque chose de simple, et paradoxalement compliqué à expliquer. Cela étant dit, dès que vous aurez « pigé » son principe de fonctionnement, tout deviendra clair !

Dans tous les cas, l’utilisation d’un watchdog n’est pas quelque chose de fondamental. Je dirais même que cela est optionnel, en un certain sens. Car à moins d’avoir à mettre des choses en sécurité, en cas de défaillance logicielle, ou pour faire des économies d’énergie, il ne vous sera peut-être d’aucune utilité. Maintenant, je pense que le watchdog arduino est un dispositif intéressant à connaître, afin de pouvoir y avoir recours au besoin !

C’est pourquoi j’espère que tout ceci pourra vous servir, un jour ou un autre, dans vos propres applications arduino ! Du reste, amusez-vous bien, et à bientôt 😉

Jérôme.

À découvrir aussi : tous les articles au sujet des arduino, publiés sur ce site !

Ce contenu vous plaît ? Alors abonnez-vous à la Newsletter pour ne rien louper !

(*) Mis à jour le 06/03/2022

4 commentaires sur “Watchdog Arduino : explication de fonctionnement, et exemples de code (mode reset, timer interruption, et réveil après sleep)”

  1. Merci beaucoup pour toutes ces explications fort intéressantes.

    J’ai suivi au mieux, du début à la fin, mais je dois avouer que : autant j’aime beaucoup bricoler en électronique, autant je ne gère pas du tout ces réalisations de microprocesseurs et autres montages qui m’échappent sévèrement. Cependant, je reste captivé par ces démonstrations détaillées et n’exclus pas de m’y mettre un jour.

    1. Salut Patrick !

      En fait, le watchdog est vraiment quelque chose d’optionnel. Et il ne faut pas se forcer à l’utiliser, lorsqu’on en a pas besoin. Cela étant dit, il faut au moins savoir qu’il existe, et comment il fonctionne « dans les grandes lignes » (pour le jour où on en a besoin !).

      Du reste, si c’est le genre de chose qui ne te t’intéresse pas plus que ça, ne t’inquiète pas ! Car l’univers de l’électronique est suffisamment vaste, pour trouver des choses plus passionnantes, ou qui te plairont davantage !

      À bientôt 😉
      Jérôme.

  2. Bonjour Jérôme,
    Merci pour ces informations très utiles.
    Toutefois, j’ai une difficulté en transférant sur une NANO un programme développé sur UNO (qui fonctionne bien aussi sur MEGA).
    J’ai testé les trois exemple décrits dans ce tuto. Le premier (Reset) ne fonctionne pas.
    Après le timeout, je n’est même plus accès au load d’un autre programme et je dois débrancher l’usb pour ce faire.
    Cordialement.
    Rudy

    1. Salut Rudy !

      C’est que tu dois être dans le cas que j’ai précisé « en rouge », à la fin de l’exemple #1.

      En fait, le programme fonctionnera bien que si ton Arduino Nano a un bootloader de type « optiboot ».
      Sauf erreur de ma part, c’est le cas de tous les Arduino Nano officiels vendus actuellement.

      Par contre, ce n’est pas le cas avec les clones d’arduino nano qu’on trouve aujourd’hui en vente un peu partout sur le net, qui eux, fonctionnent avec le « Old Bootloader » (ATmegaBOOT_168_atmega328).

      Voilà !
      Jérôme.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Symbole danger point d'exclamation site PSE, triangle jaune avec contour noir, texte noir alerte au milieu Afin de filtrer au maximum les messages de type "spam" ou "inappropriés", chaque commentaire est soumis à modération, et validé manuellement. Du coup, il se peut que certains commentaires ne soient pas publiés, ou sinon, avec un peu de retard.

Étiquettes: