sommeil-watchdog.ino

Arduino Nano (Classic, ATmega328P) · Archivo : sommeil-watchdog.ino · Lenguaje : Arduino · Uso : Réveil périodique sobre avec watchdog et sleep

El Nano clásico sabe bajar a unos microamperios: este programa duerme en PWR_DOWN y despierta cada 8 segundos vía el watchdog, sin reiniciar nunca el programa. El patrón de sensores a pila que duran meses.

Hardware

Un Arduino Nano clásico (ATmega328P a 16 MHz, formato DIL de 30 patillas para breadboard, USB mini-B, lógica de 5 V, pin RESET abajo a la izquierda). Arduino Nano (mejor con el regulador sobrio; los clones chinos varían), LED mejor desconectada.

Cableado

Retira el LED de alimentación o alimenta directo a 3,3 V para buscar la corriente mínima; si no, el regulador domina el consumo.

Funcionamiento

El watchdog en modo interrupción (WDIE) genera WDT_vect que despierta la CPU; SLEEP_MODE_PWR_DOWN corta relojes y SRAM. El despertar continúa justo tras sleep_cpu().

Ejecución

En el IDE de Arduino, selecciona la placa Arduino Nano y el procesador ATmega328P, elige el puerto serie y carga. El rail de 5 V de la placa conviene a sensores de 5 V; si no, usa 3,3 V en pines compatibles.

Variantes

Despierta también con un pin (PCINT en un botón) para despertar por evento, o corta el ADC con power_adc_disable() entre medidas.

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

← Volver a la ficha