Bonjour,
J'essaie d'optimiser la consommation électrique de mon horloge et pour cela je souhaite utiliser le Watchdog de l'AVR.
Je suis parti d'un exemple qui fonctionne mais j'ai des soucis pour l'intégrer à mon code.
J'appelle la fonction goToSleep() depuis ma fonction loop() selon certaines conditions. J'ai la trace attendue, mais le sketch ne s'arrête pas.
Il boucle encore un certain nombre de fois, puis l'ensemble se fige. Faut un reset pour le débloquer.
L'idée c'est d'endormir l'AVR et de le faire réveiller par le Watchdog ou une interruption matérielle.
On ne peut l'endormir que pendant 8s maximum alors quand l'horloge est en veille, elle doit se réveiller toutes les 8s, puis se rendormir.
Voici un extrait de code, avec la fonction qui endort l'AVR et qui configure l'ISR utilisée par le Watchdog .
Je ne maitrise pas encore toutes les subtilités des registres de l'AVR (mais je suis familier du dév de plus ou moins bas niveau depuis quelques décenies).
J'imagine que le problème est dans la configuration du watchdog et dans le type de sleep mode. Je souhaiterais utiliser le sleep mode qui consomme le moins.
/*
* Endort l'AVR
*/
void goToSleep(){
#ifdef DEBUG_SERIAL
Serial.println("dodo!");
#endif
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset
WDTCSR = _BV (WDCE) | _BV (WDE);
// set interrupt mode and an interval
WDTCSR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0); // set WDIE, and 8 seconds delay
wdt_reset(); // pat the dog
// Choose our preferred sleep mode:
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// Set sleep enable (SE) bit:
sleep_enable();
// Put the device to sleep:
sleep_cpu();
// Upon waking up, sketch continues from this point.
sleep_disable();
}
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
Serial.println("Réveillé par le watchdog");
}
Si quelqu'un a une piste ou des liens vers des exemples (car je trouve qu'ils se font rares!).