sommeil-watchdog.ino

Arduino Nano (Classic, ATmega328P) · Fichier : sommeil-watchdog.ino · Langage : Arduino · Usage : Réveil périodique sobre avec watchdog et sleep

Le Nano classique sait descendre à quelques microampères : ce programme dort en PWR_DOWN et se réveille toutes les 8 secondes via le watchdog, sans jamais réinitialiser le programme. Le patron des capteurs sur pile qui durent des mois.

Matériel requis

Un Arduino Nano classique (ATmega328P à 16 MHz, brochage DIL 30 broches sur breadboard, USB mini-B, logique 5 V, broche RESET en bas à gauche). Arduino Nano (de préférence avec le régulateur sobre — les clones chinois varient), LED débranchée de préférence.

Câblage

Retirez la LED d'alimentation ou alimentez directement en 3,3 V pour viser le courant minimal ; sinon le régulateur domine la consommation.

Fonctionnement

Le watchdog configuré en mode interruption (WDIE) génère WDT_vect qui réveille le CPU ; SLEEP_MODE_PWR_DOWN coupe horloges et SRAM. Le réveil reprend juste après sleep_cpu().

Exécution

Dans l'IDE Arduino, sélectionnez la carte Arduino Nano et le processeur ATmega328P, choisissez le port série puis téléversez. L'alimentation 5 V de la carte convient aux capteurs 5 V ; sinon utiliser le 3,3 V des broches adaptées.

Variantes

Réveillez aussi sur une broche (PCINT sur un bouton) pour un réveil événementiel, ou coupez l'ADC avec power_adc_disable() entre deux mesures.

sommeil-watchdog.ino

// Nano en veille profonde reveillee par le watchdog (~8 s).
// Courant ~12 uA en sleep contre ~15 mA eveille : la cle sur pile.
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/power.h>

volatile bool reveille = false;

ISR(WDT_vect) {   // le watchdog reveille sans reinitialiser
  reveille = true;
}

void setup() {
  Serial.begin(9600);
  MCUSR &= ~(1 << WDRF);      // efface la cause reinitialisation
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  WDTCSR = (1 << WDP1) | (1 << WDP0)  // 8 s environ
           | (1 << WDIE);              // mode interruption seule
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // veille la plus profonde
}

void loop() {
  reveille = false;
  mesure();
  sleep_enable();
  sleep_cpu();        // coupe tout jusqu'au watchdog
  sleep_disable();
}

void mesure() {
  Serial.begin(9600);
  Serial.println(F("reveil : mesure"));
  // ... lecture capteur, envoi serie ou radio ...
  Serial.end();
  // attendre que le TX en cours se vide avant de dormir
  while (UCSR0A & (1 << TXC0)) {}
  UCSR0A = (1 << TXC0);
}

← Retour à la fiche