sommeil-watchdog.ino

Arduino Nano (Classic, ATmega328P) · File : sommeil-watchdog.ino · Language : Arduino · Use case : Réveil périodique sobre avec watchdog et sleep

The classic Nano can drop to a few microamps: this program sleeps in PWR_DOWN and wakes every 8 seconds via the watchdog, never resetting the program. The pattern of battery sensors lasting months.

Hardware

An Arduino Nano classic (ATmega328P at 16 MHz, 30-pin DIL breadboard footprint, mini-B USB, 5 V logic, RESET pin at the lower-left corner). Arduino Nano (preferably with the sober regulator — Chinese clones vary), LED preferably removed.

Wiring

Remove the power LED or supply 3.3 V directly to target minimal current; otherwise the regulator dominates consumption.

How it works

The watchdog in interrupt mode (WDIE) raises WDT_vect which wakes the CPU; SLEEP_MODE_PWR_DOWN cuts clocks and SRAM. Wake-up resumes right after sleep_cpu().

Running it

In the Arduino IDE, select the Arduino Nano board and ATmega328P processor, pick the serial port, then upload. The board's 5 V rail suits 5 V sensors; otherwise use 3.3 V on compatible pins.

Variants

Also wake on a pin (PCINT on a button) for event-driven wake-up, or cut the ADC with power_adc_disable() between readings.

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);
}

← Back to the board