• Post category:Nano
  • Commentaires de la publication :0 commentaire
  • Dernière modification de la publication :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