Dans ce didacticiel, vous apprendrez à réveiller l’ESP32 à partir d’un sommeil profond à l’aide d’une alarme planifiée externe. Le module RTC DS3231 déclenchera une alarme à un moment spécifié qui déclenchera une sortie pour réveiller l’ESP32 (en utilisant un réveil externe).

Avant de poursuivre ce tutoriel, nous vous recommandons de regarder notre guide de sommeil profond ainsi que notre guide démarré pour le module RTC DS3231:
Condition préalable
Ce tutoriel se concentre sur la programmation de l’ESP32 à l’aide du noyau Arduino. Avant de continuer, vous devriez avoir le noyau Arduino ESP32 installé dans votre IDE Arduino. Suivez le prochain tutoriel pour installer l’ESP32 sur l’ide Arduino, si vous ne l’avez pas déjà fait.
Aperçu du projet
L’ESP32 peut être éveillé du sommeil à l’aide de différentes sources de réveil. L’une de ces sources de réveil comprend un réveil externe. Ce réveil externe permet à l’ESP32 d’être éveillé lorsque l’état d’un ou plusieurs GPIO change.
D’un autre côté, le DS3231 peut être configuré avec des alarmes. Lorsqu’une alarme est tirée, le module modifie l’état de la broche SQW de haut à bas.

En connectant la broche SQW à l’ESP32 et en surveillant son état pendant le sommeil profond, nous pouvons utiliser le réveil de l’ESP32 lorsque l’alarme est déclenchée.

Installation de la bibliothèque RTCLIB
Il y a plusieurs bibliothèques pour s’interfacer avec le module RTC DS3231. Nous utiliserons le RTCLIB à partir d’AdaFruit qui est compatible avec les modules RTC DS1307, DS3231 et PCF8523.
Dans le Arduino IDE, allez dans Sketch> Inclure la bibliothèque> Gérer les bibliothèques. Recherchez RTCLIB et installez la bibliothèque par AdaFruit. Nous utilisons la version 2.1.4.

Câblage du circuit
Pour tester l’exemple de ce tutoriel, vous devez connecter le module RTC DS3231 à l’ESP32. Il communique à l’aide du protocole de communication I2C.
Voici une liste des pièces nécessaires:
Tirez le DS3231 à l’ESP32 en suivant le tableau suivant ou le diagramme schématique comme référence.
| Module DS3231 RTC | ESP32 |
| SQW | Gpio 4 * |
| SCL | GPIO 22 |
| SDA | GPIO 21 |
| VCC | 3V3 |
| GND | GND |
* Vous pouvez utiliser n’importe quelle autre broche numérique tant qu’il s’agit d’un RTC GPIO – consultez le Pinout ESP32 ici.

Lecture recommandée: ESP32 PINOOUT RÉFÉRENCE: Quelles broches GPIO devriez-vous utiliser?
Réveiller l’ESP32 à l’aide d’une alarme externe
Le code suivant configure une alarme avec le module RTC DS3231. L’ESP32 passe en mode de sommeil profond. Lorsque l’alarme est tirée, l’ESP32 se réveille, clignote la LED embarquée et augmente le numéro de démarrage (nous avons donc une idée du nombre de fois que l’ESP32 s’est réveillé). Ensuite, l’ESP32 se rendormir jusqu’à ce qu’il soit à nouveau éveillé par l’alarme.
/*********
Rui Santos & Sara Santos - Raspberryme.com
Complete instructions at https://Raspberryme.com/esp32-wake-up-deep-sleep-external-alarms-ds3231/
*********/
#include
#include "driver/rtc_io.h"
// Define the DS3231 Interrupt pin (will wake-up the ESP32 - must be an RTC GPIO)
#define CLOCK_INTERRUPT_PIN GPIO_NUM_4 // Only RTC IO are allowed
// LED for visual indication
const int ledPin = 2;
// Save how many times the ESP32 woke-up
RTC_DATA_ATTR int bootCount = 0;
// Instance for the RTC
RTC_DS3231 rtc;
// Set the alarm
DateTime alarm1Time = DateTime(2024, 12, 18, 12, 25, 0);
// Method to print the reason by which ESP32 has been awaken from sleep
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}
void onAlarm(){
Serial.print("Alarm occurred!");
}
void setup() {
Serial.begin(115200);
pinMode (ledPin, OUTPUT);
//Print the wakeup reason for ESP32
print_wakeup_reason();
// Blink the LED when the ESP32 wakes-up
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
// Initialize the RTC
if(!rtc.begin()) {
Serial.println("Couldn't find RTC!");
Serial.flush();
while (1) delay(10);
}
if(rtc.lostPower()) {
// this will adjust to the date and time at compilation
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Uncomment if you need to define the time of the RTC
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// We don't need the 32K Pin, so disable it
rtc.disable32K();
// The alarm will trigger an interrupt
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
// Set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
// if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
rtc.clearAlarm(1);
rtc.clearAlarm(2);
// Stop oscillating signals at SQW Pin otherwise setAlarm1 will fail
rtc.writeSqwPinMode(DS3231_OFF);
// Turn off alarm 2 (in case it isn't off already)
// again, this isn't done at reboot, so a previously set alarm could easily go overlooked
rtc.disableAlarm(2);
// Schedule an alarm
if(!rtc.setAlarm1(alarm1Time, DS3231_A1_Minute)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
}else {
Serial.println("Alarm will happen at specified time");
}
// Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount));
// Configure external wake-up
esp_sleep_enable_ext0_wakeup(CLOCK_INTERRUPT_PIN, 0); //1 = High, 0 = Low
// Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
// The RTC SQW pin is active low
rtc_gpio_pulldown_dis(CLOCK_INTERRUPT_PIN);
rtc_gpio_pullup_en(CLOCK_INTERRUPT_PIN);
//Go to sleep now until an alarm fires
Serial.println("Going to sleep now");
esp_deep_sleep_start();
}
void loop() {
// The code never reaches the loop, because the ESP32 goes to sleep at the end of setup
Serial.print("This will never be printed!");
}
Afficher le code brut
Comment fonctionne le code?
Incluez d’abord la bibliothèque RTCLIB pour communiquer avec le module RTC DS3231.
#include
Vous devez également inclure le RTC_IO pour configurer les résistances de traction et de traction du RTC GPIO utilisées comme source de réveil.
#include "driver/rtc_io.h"
Configurez le GPIO qui sera connecté à la broche SQW horloge en temps réel. Cette broche doit être définie comme suit car elle sera responsable du réveil de l’ESP32. Vous pouvez choisir n’importe quelle autre broche tant qu’il s’agit d’un RTC GPIO.
#define CLOCK_INTERRUPT_PIN GPIO_NUM_4 // Only RTC IO are allowed
Nous définissons un GPIO pour une LED externe pour nous donner une indication visuelle du moment où l’ESP32 se réveille. Dans ce cas, nous contrôlons la LED embarquée (GPIO 2 sur la plupart des planches ESP32).
const int ledPin = 2;
Nous créons une variable appelée BootCount qui sera enregistrée dans RAM (RTC_DATA_ATTR – elle persistera à travers un sommeil profond, mais pas après une réinitialisation) pour compter combien de fois TE ESP32 s’est éveillé.
RTC_DATA_ATTR int bootCount = 0;
Créez une instance pour le DS3231 appelé RTC.
RTC_DS3231 rtc;
Définissez un objet DateTime pour définir l’heure de l’alarme. L’objet Date Heure accepte ces éléments de temps dans l’ordre: année, mois, jour, heure, minute, deuxième.
DateTime alarm1Time = DateTime(2024, 12, 18, 12, 59, 0);
Créez une fonction qui détectera et imprimera la cause du réveil ESP32.
// Method to print the reason by which ESP32 has been awaken from sleep
void print_wakeup_reason() {
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch (wakeup_reason) {
case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
}
}
Créez une fonction (ISR) qui sera appelée lorsqu’une interruption se produit (lorsque l’alarme tire). Dans ce cas, nous imprimons simplement un message au moniteur série, mais vous pouvez le modifier en fonction de vos besoins.
void onAlarm(){
Serial.print("Alarm occured!");
}
Vous pouvez en savoir plus sur les interruptions avec les fonctions ESP32 et ISR dans ce tutoriel: ESP32 avec le capteur de mouvement PIR en utilisant des interruptions et des minuteries.
Dans la configuration (), définissez le LEDPIN en tant que sortie.
pinMode (ledPin, OUTPUT);
Imprimez la raison de réveil ESP32 en appelant la fonction print_wakeup_reason () définie précédemment.
print_wakeup_reason();
Clignote la LED lorsque l’ESP32 se réveille / réinitialise.
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
Initialisez le module RTC.
if(!rtc.begin()) {
Serial.println("Couldn't find RTC!");
Serial.flush();
while (1) delay(10);
}
Ajustez le temps du RTC s’il a perdu le pouvoir.
if(rtc.lostPower()) {
// this will adjust to the date and time at compilation
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
Si vous devez régler le temps malgré tout, vous pouvez décommenter la ligne suivante. Il définira le temps pour le RTC comme le temps de compilation de l’esquisse.
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Nous devons désactiver la broche 32k car nous ne l’utiliserons pas.
rtc.disable32K();
Ensuite, définissez le GPIO qui est connecté à la broche RTC SQW comme interruption. La broche SQW ira bas lorsqu’une alarme se déclenche, nous devons donc utiliser le mode de chute (déclencher l’interruption lorsque le niveau de la broche passe de haut à bas).
// The alarm will trigger an interrupt
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), onAlarm, FALLING);
Ensuite, effacez toutes les alarmes avant d’en définir une nouvelle.
rtc.clearAlarm(1);
rtc.clearAlarm(2);
Nous n’utiliserons pas la fonctionnalité de la sortie des ondes carrées sur la broche SQW, alors désactivez-la comme suit.
rtc.writeSqwPinMode(DS3231_OFF);
Désactivez l’alarme 2 au cas où il est activé à partir de tout projet précédent car vous ne pouvez avoir qu’une seule alarme activée à la fois.
rtc.disableAlarm(2);
Finnally, planifiez votre alarme à l’aide de la fonction setalarm1 () sur l’objet RTC. Passer comme arguments le temps de l’alarme 1 et le mode d’alarme. Dans ce cas, nous le définissons sur DS3231_A1_MINUTE, ce qui signifie que l’alarme se déclenchera lorsque les minutes correspondent.
// Schedule Alarm1 to fire when the minutes match
if(!rtc.setAlarm1(alarm1Time, DS3231_A1_Minute)) { // this mode triggers the alarm when the minutes match
Serial.println("Error, alarm wasn't set!");
}else {
Serial.println("Alarm 1 will happen at specified time");
}
Vous pouvez utiliser tous les modes suivants pour l’alarme 1 (pour plus de détails, consultez notre guide DS3231 pour l’ESP32):
| Alarme | Mode | Signification (déclenchez l’alarme…) |
| Alarme 1 | DS3231_A1_PERSECOND | chaque seconde |
| Alarme 1 | Ds3231_a1_second | Quand les secondes correspondent |
| Alarme 1 | DS3231_A1_MINUTE | Quand les minutes correspondent |
| Alarme 1 | Ds3231_a1_hour | Quand l’heure correspond |
| Alarme 1 | Ds3231_a1_date | Lorsque la date correspond |
| Alarme 1 | Ds3231_a1_day | Quand la journée correspond |
Incrémentez et imprimez le numéro de démarrage à chaque réveil.
++bootCount;
Serial.println("Boot number: " + String(bootCount));
Définissez l’interruption GPIO connectée au SQW du module RTC comme source de réveil à l’aide de la fonction ESP_SLOEEP_ENABLE_EXT0_WAKEUP (). La broche SQW est active bas. Cela signifie qu’il changera son état en bas lorsque l’alarme tirera. Pour éviter tout faux positif / négatif, nous permetons sa résistance de traction interne et désactivant la résistance interne interne.
// Configure external wake-up
esp_sleep_enable_ext0_wakeup(CLOCK_INTERRUPT_PIN, 0); //1 = High, 0 = Low
// Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep.
// The RTC SQW pin is active low
rtc_gpio_pulldown_dis(CLOCK_INTERRUPT_PIN);
rtc_gpio_pullup_en(CLOCK_INTERRUPT_PIN);
En savoir plus sur ESP32 Sleep profond avec le réveil externe: ESP32 Wake Up externe du sommeil profond.
Enfin, nous appelons la fonction ESP_DEEP_SLOEPL_START () pour mettre l’ESP32 en mode de sommeil profond.
esp_deep_sleep_start();
Lorsqu’il est temps de tirer l’alarme, la broche SQW changera son état en bas, cela réveillera l’ESP32 et déclenchera la fonction onalarm (). Lorsque l’ESP32 se réveille du sommeil profond, il commencera à exécuter le code dès le début.
L’ESP32 n’atteint jamais la boucle () car elle s’endort avant cela.
void loop() {
// The code never reaches the loop, because the ESP32 goes to sleep at the end of setup
Serial.print("This will never be printed!");
}
Et c’est à peu près ainsi que le code fonctionne.
Démonstration
Téléchargez le code sur votre ESP32. Assurez-vous de configurer une alarme près du moment où vous testez ce projet afin que vous puissiez le voir en action.
Après le téléchargement, ouvrez le moniteur série à un taux de bauds de 115200 et appuyez sur le premier bouton.

Attendez que l’alarme soit déclenchée. Il imprimera un message sur le moniteur série et la LED embarquée clignote. L’ESP32 restera en mode de sommeil profond jusqu’à ce que l’alarme tire à nouveau.

Emballage
Dans ce didacticiel, vous avez appris à configurer des alarmes avec le module RTC DS3231 pour réveiller l’ESP32 du sommeil profond. Cette fonctionnalité peut être extrêmement utile dans les projets dans lesquels la consommation d’énergie est une préoccupation. Vous pouvez réveiller l’ESP32 à des moments spécifiés tout au long de la journée, puis le réveiller avec une alarme pour effectuer une tâche souhaitée.
Nous espérons que vous avez trouvé ce guide utile.
En savoir plus sur l’ESP32 avec nos ressources.
Merci d’avoir lu.
Cette vidéo vous emmène dans l’histoire de Raspberry Pi :

