Le code ci-dessous, tout simple, fonctionne parfaitement avec une UNO
#include <avr/wdt.h>
void setup()
{
wdt_disable();
Serial.begin(9600);
Serial.println("\nProgramme demo watchdog");
Serial.print("Attente 10 secondes");
for (uint8_t i=0; i<10; i++)
{
delay(1000);
Serial.print('.');
}
Serial.println();
Serial.println("Activation du watchdog");
wdt_enable(WDTO_8S);
Serial.print("Fonctionnement normal 10 secondes");
for (uint8_t i=0; i<10; i++)
{
delay(1000);
Serial.print('.');
wdt_reset();
}
Serial.println();
Serial.print("Declenchement watchdog");
for (uint8_t i=0; i<10; i++)
{
delay(1000);
Serial.print('.');
}
Serial.println();
Serial.println("Ceci ne doit pas s'afficher");
}
void loop() {}
Mais sur une Mega, rien à faire.
Le premier reboot() se déclenche, puis la carte devient "muette" : impossible d'y téléverser un nouveau code. La fermeture / ouverture du terminal série de l'IDE ne la réinitialise pas.
Seule la mise hors tension permet de la réinitialiser.
Résolution
Si le programme ci-dessus fait planter votre arduino mega, c'est qu'elle vous a probablement été livrée avec un bootloader obsolète, incompatible avec le watchdog.
La solution consiste à remettre à niveau le bootloader de la carte.
Méthode proposée :
prendre une carte UNO
y téléverser le programme ArduinoISP qui se trouve dans les exemples de l'IDE
débrancher la carte
cabler la UNO -> MEGA comme suit :
GND -> GND
5V -> 5V
10 -> RST
11 -> 51
12 -> 50
13 -> 52
Rebrancher la UNO au PC, puis dans l'IDE :
changer le type de carte : arduino mega
changer le graveur : Arduino as ISP
graver la séquence d'initialisation
Le programme ci-dessus peut à présent être à nouveau téléversé dans la MEGA, et devrait fonctionner normalement
bricoleau:
Et avec le tout premier programme ci-dessus, elles fonctionnent ?
et bien non, même pb que toi >:(
j'ai l'impression que si le watchdog pète pendant une com sur le port série ça le plante sérieusement (j'ai du changer de port pour ne pas redemarrer mon pc)
il faudrait essayer en supprimant les Serial.print dans la boucle de déclenchement
J'y crois moyen au conflit avec la liaison série.
D'abord parce que je n'envoie qu'un caractère '.' par seconde au moment du déclenchement du watchdog, donc la probabilité du reset pendant la milliseconde de sollicitation de la liaison série me semble très faible.
Ensuite ça fonctionne très bien sur une uno. Il devrait y avoir le même conflit.
Apparemment, l'explication (un peu étonnante) serait :
Lorsque le watchdog se déclenche :
la réinitialisation des registres de l'atmega induit une réinit du délai associé au watchdog, qui passe à 15 ms
le bootloader ne désactive pas le watchdog, et n'a pas le temps de terminer son traitement avant expiration du délai de 15 ms et nouveau déclenchement du watchdog.
La mega passe alors son temps à se réinitialiser toutes les 15 ms, sans jamais atteindre la fonction setup()
La solution propre serait de flasher un nouveau bootloader, à partir d'une version alternative compatible watchdog (optiboot).
Si c'est bien ça, cela veut dire qu'il est impossible d'uploader un programme utilisant le watchdog sur une mega "sortie d'usine", sans un minimum de manips préalables.
Ce qui ne m'arrange pas du tout, notamment pour ma bibliothèque ordonnanceur.h qui devient alors nettement moins facile à mettre en œuvre avec une mega.
Du coup, je pense me rabattre sur la solution de contournement qui utilise le timer2.
ça parait très étonnant car je l'utilise sur ma ruche de 2 manières :
en automatique sur blocage de je ne sais quoi de temps en temps (2 ou 3 jours) ...
en manuel par une commande spécifique passée par le moniteur série ou même a distance par le serveur web, je le fait rentrer dans une boucle while(1) et le watchdog déclenche
il est déclaré en fin de setup et la raz est faite dans la loop
par contre je me suis fait avoir sur le DUE, le fait de déclarer le watchdog (void watchdogSetup(void)) le met en fonction avec un temps de 16s (sans faire de watchdogEnable(...)) si la raz est faite uniquement dans la loop et si le setup dure plus de 16s et bien le DUE redémarre sans arrêt
Tu utilises bien les mêmes primitives wdt_disable(), wdt_enable() et wdt_reset() que dans mon programme initial ?
Quelle valeur passes-tu à wdt_enable() ?
Et évidemment tu as bien une arduino mega pour ta ruche, sans avoir bidouillé le bootloader?
Quelle version de l'IDE ?
Je me demande comment peut-on vérifier la version de bootloader installée sur une carte arduino.
C'est peut-être la mienne qui m'a été fournie avec un bootloader ante-diluvien.
J'imagine qu'il faudrait passer par l'ICSP pour extraire le contenu intégral de la flash, bootloader inclus.
Ca risque d'être pénible.
Ou alors, avec du bol, peut-être qu'un dump du contenu de la flash sur le terminal Série ferait apparaître une signature. Je vais essayer ça.
déclarations :
...
#include <avr/wdt.h> // watchdog
fin du setup ():
...
wdt_enable(WDTO_8S); // watchdog 8s
début de loop ():
wdt_reset(); // watchdog démarré on le raz a chaque passage sinon reboot
...
c'est bien 3 méga (clones Chinois achetés en 3 fois dans des boutiques différentes) non modifiés
j'utilise l'IDE 1.0.6 pour les méga
et ton code me plante le méga qui me sert pour le développement
L'hypothèse était la bonne : le problème venait bien du bootloader préinstallé sur ma mega, incompatible avec le watchdog.
J'ai regravé le bootloader via l'IDE et une carte uno (arduino as ISP), et le watchdog fonctionne à présent normalement.
Comme quoi, avec les imports chinois, il vaut mieux commencer par remettre le bootloader à niveau avant de jouer.
Je suppose que ta carte de dev souffre du même problème.
Merci pour le coup de main.