• Post category:Nano
  • Post comments:0 commentaire
  • Post last modified:mars 12, 2022
  • Temps de lecture :7 min de lecture

Mode sleep Arduino nano avec Watchdog Timer interruption *

 

 

    Prérequis :

Matériel :

  • 1 x Carte Arduino Nano
  • 1 x Led
  • 1 x Résistance 220 ohms
  • 1 x Multimètre
  • Fils de connexion
  • 1 x Breadboard
  • 1 x Alimentation 5V

 

 

Vidéo de démonstration :

 

Schéma de câblage :

 

Code :

#include "Arduino.h"
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

#define LED_PIN (13)
#define LED_PINverte (4)

//On utilise une variable volatile car elle est modifiée à l'intérieur
//d'une fonction d'interruption
volatile int etat_wdt = 1;
int cpt;
// Service d'interruption de chien de garde. Ceci est exécuté lorsque le chien de garde a expiré.
ISR(WDT_vect) {
  if (etat_wdt == 0) {
    etat_wdt = 1;
  }
}

// Met l'arduino en mode veille.
void enterSleep(void)
{
  // Il existe cinq modes de veille différents par ordre d'économie d'énergie :
  // SLEEP_MODE_IDLE - le mode d'économie d'énergie le plus bas
  // SLEEP_MODE_ADC
  // SLEEP_MODE_PWR_SAVE
  // SLEEP_MODE_STANDBY
  // SLEEP_MODE_PWR_DOWN - le mode d'économie d'énergie le plus élevé
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  // Entrez maintenant en mode veille.
  sleep_mode();

  // Le programme continuera à partir d'ici après le délai d'attente WDT.

  // La première chose à faire est de désactiver le sommeil.
  sleep_disable();

  // Réactiver les périphériques.
  power_all_enable();
}

// Configurer la minuterie Watch Dog (WDT)
void setupWatchDogTimer() {
  // Le registre d'état du MCU (MCUSR) est utilisé pour faire la distinction de la cause de la dernier
  // réinitialisation, telle que la réinitialisation des baisses de tension, la réinitialisation du chien de garde, etc.
  // REMARQUE : pour des raisons de sécurité, il existe une séquence chronométrée pour effacer le
  // WDE et modifier la configuration du délai d'attente. Si vous n'utilisez pas la
  // séquence correctement, vous obtiendrez des résultats inattendus.

  // Efface l'indicateur de réinitialisation sur le MCUSR, le bit WDRF (bit 3).
  MCUSR &= ~(1 << WDRF);
  //Désactiver les interruptions afin que nous ne soyons pas interrompus lors de la séquence chronométrée
  cli();
  // Configurer le registre de contrôle de la minuterie Watchdog (WDTCSR)
  // Le WDTCSR est utilisé pour configurer le time-out, le mode de fonctionnement, etc.

  // Afin de changer WDE ou le prescaler, nous devons définir WDCE (cela
  // autorise les mises à jour pendant 4 cycles d'horloge).

  // Réglez le bit WDCE (bit 4) et le bit WDE (bit 3) du WDTCSR. Le WDCE
  // le bit doit être défini pour modifier WDE ou les prescalers de surveillance.
  // La définition du bit WDCE permettra les mises à jour des prescalers et WDE pour 4
  // cycles d'horloge, puis il sera réinitialisé par le matériel.
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  /**
      Réglage de la valeur de pré-scaler du chien de garde avec VCC = 5,0 V et 16 mHZ
      WDP3 WDP2 WDP1 WDP0 | Nombre de WDT | Délai d'attente typique aux cycles d'oscillateur
      0    0    0    0    |   2K cycles   | 16 ms
      0    0    0    1    |   4K cycles   | 32 ms
      0    0    1    0    |   8K cycles   | 64 ms
      0    0    1    1    |  16K cycles   | 0.125 s
      0    1    0    0    |  32K cycles   | 0.25 s
      0    1    0    1    |  64K cycles   | 0.5 s
      0    1    1    0    |  128K cycles  | 1.0 s
      0    1    1    1    |  256K cycles  | 2.0 s
      1    0    0    0    |  512K cycles  | 4.0 s
      1    0    0    1    | 1024K cycles  | 8.0 s
  */
  WDTCSR  = (1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (1 << WDP0);
  //active les interruptions globales
  sei();
  // Active l'interruption WD (remarque : pas de réinitialisation).
  WDTCSR |= _BV(WDIE);
}

// Configuration pour les communications série et les autres choses
void setup() {
  Serial.begin(9600);
  Serial.println("Initialising..."); delay(100);
  pinMode(LED_PIN, OUTPUT);
  pinMode(LED_PINverte, OUTPUT);
  setupWatchDogTimer();
  Serial.println("Initialisation complete."); delay(100);
}

// Boucle principale
void loop() {
  // Attend que le chien de garde ait déclenché un réveil.
  if (etat_wdt != 1) {
    return;
  }
  // Allume la LED
  digitalWrite(LED_PIN, 1);
  digitalWrite(LED_PINverte, 1);
  // Temporise 20 ms
  delay(1000);
  // Eteint la LED
  digitalWrite(LED_PIN, 0);
  digitalWrite(LED_PINverte, 0);
  delay(200);
  // Remise a 0 de la variable volatile pour exécuter à nouveau le code ci-dessus après le réveil du MCU
  etat_wdt = 0;

  // Revenez en mode veille.
  enterSleep();
}

 


 

Laisser un commentaire