ESP32 Mode de sommeil léger et sources de réveil (Arduino IDE)

ESP32 Mode de sommeil léger et sources de réveil (Arduino IDE)

Le sommeil léger est l’un des modes d’économie d’énergie soutenus par l’ESP32. Dans ce guide, nous examinerons comment implémenter le mode de sommeil léger avec l’ESP32 et les différentes sources de réveil. Nous couvrirons le réveil de la minuterie, différentes méthodes de réveil externe, de réveil GPIO, de réveil et de réveil via UART.

ESP32 Mode de sommeil léger et sources de réveil (Arduino IDE)

Table des matières:

Dans ce tutoriel, nous couvrirons les sujets suivants:

Présentation du sommeil léger

L’ESP32 propose plusieurs modes d’économie d’électricité: sommeil moderne, sommeil léger et sommeil profond. Nous avons couvert un sommeil profond en détail dans un post précédent.

Vous pouvez comparer les différents modes du tableau suivant de la fiche technique ESP32 ESPRESSIF.

consommation d'énergie ESP32

Contrairement au sommeil profond, qui alimente pleinement le processeur et la plupart des périphériques, le sommeil léger conserve l’état du CPU et maintient les données RAM intactes. Cela signifie que les variables de programme et les États sont préservées, permettant à l’ESP32 de reprendre les tâches presque instantanément au réveil.

Cela signifie que lorsque l’ESP32 se réveillera, il reprendra le code où il s’était arrêté avant d’aller dormir (contrairement au sommeil profond qui exécute le code dès le début). De plus, le mode de sommeil léger prend en charge davantage de sources de réveil comme GPIO Wake-up et UART Wake-up.

La fiche technique ESP32 ESPRESSIF fournit également un tableau comparant la consommation d’énergie des différents modes de puissance.

ESP32 Modes de sommeil différents

En termes de consommation d’énergie, le sommeil léger consomme moins que le mode actif, mais plus que le sommeil profond.

Le sommeil léger est idéal pour les applications qui nécessitent des économies de puissance modérées, mais doivent toujours répondre rapidement à certains événements ou interruptions, tels que des capteurs temporairement inactifs qui vérifient périodiquement les données.

Configuration du sommeil léger sur l’ESP32

Mettre l’ESP32 en mode de sommeil léger est super simple. Après avoir configuré la source ou les sources de réveil, il vous suffit d’appeler la fonction ESP_light_sleep_start ().

esp_light_sleep_start();

Après cela, l’ESP32 se réveillera lorsque la ou les sources de réveil requises sont déclenchées. Lorsque l’ESP32 se réveille, il reviendra à l’endroit où il se trouvait dans le code.

Sources de réveil léger

Après avoir mis l’ESP32 en mode de sommeil léger, il existe plusieurs façons de la réveiller.

  • Recou de minuterie: le temporisateur RTC peut être défini pour réveiller l’ESP32 après un intervalle de temps spécifié. Utilisez la fonction ESP_SLEEP_ENABLE_TIMER_WAKEUP ().
  • GPIO Wake-up: GPIOS peut être configuré pour déclencher un réveil sur un signal élevé ou bas. Ceci est utile pour réveiller la planche avec un bouton-poussoir ou un signal de capteurs. Vous pouvez utiliser le ESP_SLEEP_ENABLE_EXT0_WAKEUP (), le ESP_SOepl_enable_EXT1_WAKEUP_IO (), ou le esp_sleep_enable_gpio_wakeup ().
  • Recouchée touchante: Réveillez-vous du sommeil léger lorsqu’une touche est détectée sur les épingles tactiles ESP32. Utilisez la fonction TouchSleepWaKeUpEnable ().
  • UART REALOP: réveil l’ESP32 lorsque les données sont reçues via UART sur un port spécifique à l’aide de la fonction ESP_SOepl_enable_Uart_WAKEUP ().

Désactiver les sources de réveil du sommeil

Pour désactiver les sources de réveil précédemment activées, utilisez la fonction ESP_SLOEPL_DISABLE_WAKEUP_SOURCE () et passez comme argument la source de réveil que vous souhaitez désactiver. Si vous souhaitez désactiver toutes les sources de réveil, passez ESP_SLOPLET_WAKEUP_ALL comme argument.

Une liste des sources de réveil peut être trouvée ici: Argument de la source de réveil du sommeil.


Sommeil léger avec le réveil de la minuterie

Dans cette section, nous vous montrerons comment mettre l’ESP32 en mode de sommeil léger et le réveiller après un intervalle défini.

Pour réveiller l’ESP32 après une période prédéterminée, vous devez configurer un réveil de la minuterie à l’aide de la fonction ESP_SLEELBE_ENABLE_TIMER_WAKEUP (). Passer comme argument le temps en microsecondes.

esp_sleep_enable_timer_wakeup(uint64_t time_in_us)

ESP32 Light Sleep with Timer Remarque Exemple

L’exemple suivant mettra l’ESP32 en mode de sommeil léger. L’ESP32 se réveillera toutes les 10 secondes.

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

int counter = 0;
const int ledPin = 2;           // GPIO pin for onboard LED
uint64_t sleepTime = 10000000;  // Sleep duration in microseconds (10 seconds)

void setup() {
    Serial.begin(115200);
    pinMode(ledPin, OUTPUT);

    // Enable wake-up by timer
    esp_err_t result = esp_sleep_enable_timer_wakeup(sleepTime);

    if (result == ESP_OK) {
        Serial.println("Timer Wake-Up set successfully as wake-up source.");
    } else {
        Serial.println("Failed to set Timer Wake-Up as wake-up source.");
    }
}

void loop() {
    Serial.printf("Counter: %d\n", counter);
    counter++;

    digitalWrite(ledPin, HIGH);  // LED on to indicate wake-up
    delay(2000);
    digitalWrite(ledPin, LOW);   // Turn off LED before going to sleep

    Serial.println("Going into light sleep mode");
    delay(500);
    esp_light_sleep_start();     // Enter light sleep
    Serial.println("Returning from light sleep");
}

Afficher le code brut

Cet exemple allume une LED lorsque l’ESP32 est réveillé et augmente une variable de contre-variable dans chaque boucle. Cet exemple démontre que le RAM ESP32 conserve des données, donc les variables et les états du programme restent intacts lorsque l’ESP32 se réveille.

Quand il se réveille, il revient à l’endroit où il se trouvait dans le code (contrairement au sommeil profond qui commence à exécuter le code depuis le début).

Comment fonctionne le code?

Jetons un coup d’œil aux pièces pertinentes pour le sommeil léger avec le réveil de la minuterie.

Dans la configuration (), nous appelons la fonction ESP_SLOLET_ENABLE_TIMER_WAKEUP () pour activer le réveil de la minuterie. Nous passons comme argument la variable du temps de sommeil (10000000 microsecondes = 10 secondes).

esp_err_t result = esp_sleep_enable_timer_wakeup(sleepTime);

La fonction ESP_SLEELBE_ENABLE_TIMER_WAKEUP () Renvoie ESP_OK si le réveil du minuteur a été configuré avec succès. Nous vérifions cela dans les lignes suivantes.

if (result == ESP_OK) {
    Serial.println("Timer Wake-Up set successfully as wake-up source.");
} else {
    Serial.println("Failed to set Timer Wake-Up as wake-up source.");
}

Dans chaque boucle (), nous augmentons la variable de comptoir.

counter++;

Allumez la LED embarquée pendant deux secondes.

digitalWrite(ledPin, HIGH);    // LED on to indicate wake-up
delay(2000);
 digitalWrite(ledPin, LOW); // Turn off LED before going to sleep

Et nous mettons l’ESP32 en mode de sommeil léger en appelant la fonction ESP_light_sleep_start ().

esp_light_sleep_start();       // Enter light sleep

Lorsque l’ESP32 se réveille du sommeil, il continuera à exécuter le code. Ainsi, après avoir réveillé, il imprimera le message suivant.

Serial.println("Returning from light sleep");

Dans chaque boucle () et cycle de réveil, la contre-variable augmente. Cela prouve que l’ESP32 peut conserver les valeurs des variables pendant le sommeil léger.

ESP32 Mode de sommeil léger avec le moniteur de série de réveil de la minuterie

Sommeil léger avec un réveil externe

Dans cette section, vous apprendrez à mettre l’ESP32 en mode de sommeil léger et à le réveiller avec un réveil externe, dans ce cas, un bouton-poussoir. Tout GPIO qui est un RTC GPIO peut être utilisé pour réveiller l’ESP32.

Il existe trois façons différentes d’utiliser le réveil externe avec un sommeil léger: la méthode EXT0, la méthode EXT1 et le réveil GPIO. Nous allons jeter un œil à chacun d’eux.

extension de réveil externe

Le réveil externe EXT0 vous permet de réveiller l’ESP32 lorsqu’un RTC GPIO est défini sur un état prédéfini. Les périphériques RTC sont maintenus pendant le sommeil si cette source de réveil est demandée.

Pour utiliser cette source de réveil, utilisez la fonction ESP_SLEEP_ENABLE_EXT0_WAKEUP () et passez comme argument le numéro GPIO dans ce format gpio_num_x (dans lequel x correspond au numéro GPIO) et le niveau (0 = Low ou 1 = High).

Par exemple:

esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, level);

Remarque: vous ne pouvez utiliser que des broches qui sont RTC GPIO avec cette source de réveil. Voici une liste des GPIO RTC pour différents modèles de puces ESP32:

  • ESP32-S3: 0-21;
  • ESP32: 0, 2, 4, 12-15, 25-27, 32-39;
  • ESP32-S2: 0-21;

Lecture recommandée: ESP32 PINOOUT RÉFÉRENCE: Quelles broches GPIO devriez-vous utiliser?

Lecture recommandée: ESP32-S3 Guide de référence de Pinout Devkitc: GPIOS expliqué

Sleep léger avec exemple de réveil externe (EXT0)

Voici un exemple simple en utilisant un sommeil léger avec un réveil externe EXT0. Cet exemple réveille l’ESP32 avec la presse d’un bouton-poussoir. Chaque fois qu’il se réveille, il allume une LED pendant cinq secondes et augmente la variable de comptoir.

Pour tester cet exemple, câblez un bouton-poussoir vers l’ESP32 GPIO 27 comme indiqué dans l’image ci-dessous (parce que nous utilisons une résistance de traction interne, nous n’avons pas besoin d’ajouter au circuit).

ESP32 avec bouton-poussoir avec résistance de traction interne

Après avoir câblé le circuit, vous pouvez télécharger le code sur votre carte.

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

int counter = 0;
const int ledPin = 2;            // GPIO pin for onboard LED
#define buttonPin  GPIO_NUM_27   // Connect a pushbutton to GPIO 27

void setup() {
    Serial.begin(115200);
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin, INPUT_PULLDOWN); // pull-down resistor

    // Enable wake-up by EXT0 using the button on GPIO 27
    esp_err_t result = esp_sleep_enable_ext0_wakeup(buttonPin, 1); // 1 = wake up on HIGH signal

    if (result == ESP_OK) {
        Serial.println("EXT0 Wake-Up set successfully as wake-up source.");
    } else {
        Serial.println("Failed to set EXT0 Wake-Up as wake-up source.");
    }
}

void loop() {
    Serial.printf("Counter: %d\n", counter);
    counter++;

    digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
    delay(5000);
    digitalWrite(ledPin, LOW);  // Turn off LED before going to sleep

    Serial.println("Going into light sleep mode");
    delay(500);
    esp_light_sleep_start();    // Enter light sleep
    Serial.println("Returning from light sleep");
}

Afficher le code brut

Comment fonctionne le code?

Tout d’abord, définissez le GPIO qui sera utilisé pour le réveil. Dans cet exemple, c’est GPIO 27.

#define buttonPin  GPIO_NUM_27     // GPIO pin for pushbutton

Dans la configuration (), nous définissons le bouton-poussoir comme une entrée avec une résistance de tirage.

pinMode(buttonPin, INPUT_PULLDOWN); // pull-down resistor

Ensuite, nous activons la source de réveil EXT0 sur GPIO 27. Nous passons 1 pour le niveau, ce qui signifie qu’il réveillera l’ESP32 sur un signal élevé – parce que nous utilisons une résistance de traction, il recevra un signal élevé lorsque vous appuyez sur le bouton-poussoir.

// Enable wake-up by EXT0 using the button on GPIO 27
esp_err_t result = esp_sleep_enable_ext0_wakeup(buttonPin, 1); // 1 = wake up on HIGH signal

Dans la boucle (), nous augmentons la variable de comptoir, allumons la LED embarquée pendant cinq secondes et enfin, appelons l’ESP_light_sleep_start () pour mettre la carte en mode de sommeil léger.

esp_light_sleep_start();    // Enter light sleep

Tester le code

Téléchargez le code sur votre carte. Ouvrez le moniteur en série à un taux en bauds de 115200. Appuyez sur le bouton-poussoir pour réveiller l’ESP32.

Chaque fois que vous appuyez sur le bouton-poussoir, l’ESP32 se réveillera, imprimera et augmentera la variable de contre-variable, allumera la LED embarquée pendant cinq secondes et se rendormit.

ESP32 Sleep léger avec réveil externe

extension de réveil externe

Vous pouvez réveiller l’ESP32 en utilisant plusieurs GPIO avec cette source de réveil. La source de réveil EXT1 est implémentée par le contrôleur RTC. Ainsi, les périphériques RTC et les souvenirs RTC peuvent être éteints dans ce mode.

Utilisez la fonction ESP_SLEEP_ENABLE_EXT1_WAKEUP_IO (). Passez comme arguments le mascage des GPIO utilisé pour le réveil et le mode / logique pour se réveiller.

Vous pouvez utiliser l’une des deux logiques suivantes:

  • ESP_EXT1_WAKEUP_ALL_LOW: Réveillez-vous lorsque tous les gpios deviennent bas;
  • ESP_EXT1_WAKEUP_ANY_HIGH: Réveillez-vous si l’un des GPIO est haut.

Si vous utilisez un ESP32-S2, ESP32-S3, ESP32-C6 ou ESP32-H2, ce sont les modes disponibles:

  • ESP_EXT1_WAKEUP_ANY_LOW: Réveillez-vous lorsque l’un des GPIO sélectionnés est bas
  • ESP_EXT1_WAKEUP_ANY_HIGH: Réveillez-vous lorsque l’un des GPIO sélectionnés est élevé

Remarque: vous ne pouvez utiliser que des broches qui sont RTC GPIOS.

Sleep léger avec réveil externe () Exemple (EXT1)

Dans l’exemple suivant, nous utiliserons deux bouton-poussoirs pour réveiller l’ESP32. L’ESP32 se réveillera lorsque l’un des bouton-poussoirs sera pressé.

Pour tester cet exemple, nous connecterons un bouton-poussoir à GPIO27 et un autre à GPIO26. Nous utiliserons les résistances de traction internes ESP32. Vous pouvez utiliser le diagramme suivant comme référence pour câbler votre circuit.

ESP32 avec deux circuits de bouton-poussoir

Et c’est le code que vous devez télécharger sur votre carte.

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

#include "esp_sleep.h"
#include "driver/rtc_io.h"

int counter = 0;
const int ledPin = 2;                      // GPIO pin for onboard LED
const gpio_num_t buttonPin1 = GPIO_NUM_26; // RTC IO for pushbutton 1
const gpio_num_t buttonPin2 = GPIO_NUM_27; // RTC IO for pushbutton 2
#define BUTTON_PIN_BITMASK(GPIO) (1ULL << GPIO)  // Macro for individual GPIO bitmask

// Create a bitmask for GPIO 26 and GPIO 27
uint64_t bitmask = BUTTON_PIN_BITMASK(buttonPin1) | BUTTON_PIN_BITMASK(buttonPin2);

// Method to print the GPIO that triggered the wakeup
void print_GPIO_wake_up(){
  int GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println((log(GPIO_reason))/log(2), 0);
}

void setup() {
    Serial.begin(115200);
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin1, INPUT_PULLDOWN); // pull-down resistor
    pinMode(buttonPin2, INPUT_PULLDOWN); // pull-down resistor

    // Configure GPIO 26 and GPIO 27 as RTC IOs for EXT1 wake-up
    rtc_gpio_deinit(buttonPin1);
    rtc_gpio_deinit(buttonPin2);

    // Enable EXT1 wake-up source
    esp_err_t result = esp_sleep_enable_ext1_wakeup(bitmask, ESP_EXT1_WAKEUP_ANY_HIGH);

    if (result == ESP_OK) {
        Serial.println("EXT1 Wake-Up set successfully.");
    } else {
        Serial.println("Failed to set EXT1 Wake-Up as wake-up source.");
    }
}

void loop() {
    Serial.printf("Counter: %d\n", counter);
    counter++;

    digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
    delay(2000);
    digitalWrite(ledPin, LOW);  // Turn off LED before going to sleep

    Serial.println("Going into light sleep mode");
    delay(500);
    esp_light_sleep_start();    // Enter light sleep

    // After wake-up, disable the hold function on the RTC GPIOs
    rtc_gpio_hold_dis(buttonPin1);
    rtc_gpio_hold_dis(buttonPin2);

    Serial.println("----------------------");
    Serial.println("Returning from light sleep");
    // Print the GPIO (button) that caused the wake-up
    print_GPIO_wake_up();
}

Afficher le code brut

Lorsque vous appuyez sur l’un des boutons, l’ESP32 se réveillera et imprimera quel gpio / bouton a été appuyé.

ESP32 Démonstration EXT1 ESP32 Sleep Light Sleep

GPIO REAUX EXTERNE

Outre les méthodes EXT0 et EXT1, il existe une autre méthode qui vous permet de configurer les GPIO individuels pour réveiller l’ESP32 sur des signaux élevés ou bas. Avec cette méthode, vous pouvez utiliser n’importe quel GPIO, qu’il s’agisse d’un RTC GPIO ou d’une entrée numérique «régulière».

1) Pour utiliser cette méthode, vous devez d’abord utiliser la fonction GPIO_WAKEUP_ENABLE () pour définir les GPIO que vous souhaitez utiliser comme source de réveil et le niveau correspondant. Le numéro GPIO doit être dans ce format GPIO_NUM_X (x est le numéro du GPIO). Le niveau peut être l’une des options suivantes:

  • Gpio_intr_low_level – réveillez l’ESP32 lorsque le gpio est bas
  • Gpio_intr_high_level – réveillez l’ESP32 lorsque le gpio monte haut

2) Vous pouvez appeler plusieurs fois la fonction gpio_wakeup_enable () pour configurer plusieurs gpios.

3) Après avoir réglé les GPIO qui réveilleront l’ESP32, vous devez appeler la fonction ESP_SLOEEP_ENABLE_GPIO_WAKEUP () pour activer cette source de réveil.

Ensuite, il vous suffit d’appeler la fonction ESP_light_sleep_start () pour mettre l’ESP32 à l’état de sommeil léger.

Sleep léger avec l’exemple de réveil externe GPIO

L’exemple suivant fonctionne exactement comme le précédent, mais nous utilisons cette nouvelle méthode. Nous utilisons des interruptions sur les boutons de poussée pour déterminer lequel était la cause du réveil.

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

#include "esp_sleep.h"
#include "driver/gpio.h"

int counter = 0;
const int ledPin = 2;                      // GPIO pin for onboard LED
const gpio_num_t buttonPin1 = GPIO_NUM_26; // GPIO for pushbutton 1
const gpio_num_t buttonPin2 = GPIO_NUM_27; // GPIO for pushbutton 2

int wakeup_gpio; // Variable to store the GPIO that caused wake-up

// ISR for buttonPin1
void IRAM_ATTR handleInterrupt1() {
    wakeup_gpio = buttonPin1;
}

// ISR for buttonPin2
void IRAM_ATTR handleInterrupt2() {
    wakeup_gpio = buttonPin2;
}

void setup() {
    Serial.begin(115200);
    pinMode(ledPin, OUTPUT);
    pinMode(buttonPin1, INPUT_PULLDOWN); // pull-down resistor
    pinMode(buttonPin2, INPUT_PULLDOWN); // pull-down resistor

    // Configure GPIOs as wake-up source
    gpio_wakeup_enable(buttonPin1, GPIO_INTR_HIGH_LEVEL); // Trigger wake-up on high level
    gpio_wakeup_enable(buttonPin2, GPIO_INTR_HIGH_LEVEL); // Trigger wake-up on high level

    // Enable GPIO wake-up source
    esp_err_t result = esp_sleep_enable_gpio_wakeup();

    if (result == ESP_OK) {
        Serial.println("GPIO Wake-Up set successfully.");
    } else {
        Serial.println("Failed to set GPIO Wake-Up as wake-up source.");
    }

    // Attach interrupts to GPIO pins
    attachInterrupt(digitalPinToInterrupt(buttonPin1), handleInterrupt1, RISING);
    attachInterrupt(digitalPinToInterrupt(buttonPin2), handleInterrupt2, RISING);
}

void loop() {
    Serial.printf("Counter: %d\n", counter);
    counter++;

    digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
    delay(5000);
    digitalWrite(ledPin, LOW);  // Turn off LED before going to sleep

    Serial.println("Going into light sleep mode");
    delay(500);
    esp_light_sleep_start();    // Enter light sleep

    Serial.println("----------------------");
    Serial.println("Returning from light sleep");

    // Print the GPIO that caused the wake-up
    Serial.printf("Wake-up caused by GPIO %d\n", wakeup_gpio);
}

Afficher le code brut

Dans ce code, vous commencez par définir les GPIO connectés aux boutons-poussoirs dans le format suivant:

const gpio_num_t buttonPin1 = GPIO_NUM_26; // GPIO for pushbutton 1
const gpio_num_t buttonPin2 = GPIO_NUM_27; // GPIO for pushbutton 2

Nous créons une variable globale pour enregistrer le GPIO qui a provoqué le réveil.

int wakeup_gpio; // Variable to store the GPIO that caused wake-up

Dans la fonction SETUP (), utilisez la fonction GPIO_WAKEUP_ENABLE () pour définir les GPIO comme sources de réveil et le niveau.

// Configure GPIOs as wake-up source
gpio_wakeup_enable(buttonPin1, GPIO_INTR_HIGH_LEVEL); // Trigger wake-up on high level
gpio_wakeup_enable(buttonPin2, GPIO_INTR_HIGH_LEVEL); // Trigger wake-up on high level

Ensuite, pour activer les GPIO en tant que source de réveil, appelez la fonction ESP_SLEEP_ENABLE_GPIO_WAKEUP ().

// Enable GPIO wake-up source
esp_err_t result = esp_sleep_enable_gpio_wakeup();

Toujours dans la configuration (), nous définissons les bouton-poussoirs sous forme d’interruptions afin qu’ils déclenchent une fonction lorsqu’ils sont poussés. Cela nous permet de vérifier quelle GPIO a provoqué le réveil.

// Attach interrupts to GPIO pins
attachInterrupt(digitalPinToInterrupt(buttonPin1), handleInterrupt1, RISING);
attachInterrupt(digitalPinToInterrupt(buttonPin2), handleInterrupt2, RISING);

Lecture recommandée: interrompt avec l’ESP32 à l’aide d’un capteur de mouvement PIR.

Les fonctions de gestionnaire d’interruption sont définies avant la configuration () et mettent à jour la variable wakeup_gpio.

//ISR for buttonPin1
void IRAM_ATTR handleInterrupt1() {
    wakeup_gpio = buttonPin1;
}

//ISR for buttonPin2
void IRAM_ATTR handleInterrupt2() {
    wakeup_gpio = buttonPin2;
}

Dans la boucle (), comme dans les exemples précédents, nous mettons à jour la variable de comptoir, éclaire la LED embarquée et mettons la planche en mode de sommeil léger.

Serial.printf("Counter: %d\n", counter);
counter++;

digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
delay(5000);
digitalWrite(ledPin, LOW);  // Turn off LED before going to sleep

Serial.println("Going into light sleep mode");
delay(500);
esp_light_sleep_start();    // Enter light sleep

Après s’être réveillé du sommeil, nous imprimons le GPIO qui a provoqué le réveil.

Serial.println("----------------------");
Serial.println("Returning from light sleep");

// Print the GPIO that caused the wake-up
Serial.printf("Wake-up caused by GPIO %d\n", wakeup_gpio);

Sommeil léger avec le réveil du toucher

Il est possible de réveiller l’ESP32 du sommeil léger lorsqu’il touche ses épingles tactiles, en ce qui concerne une interruption de capteur tactile. Pour cela, utilisez la fonction TouchSleepWakeUpEnable () qui accepte comme argument la broche tactile et le seuil pour se réveiller. Par exemple:

touchSleepWakeUpEnable(T3, THRESHOLD);

Les valeurs lues par une épingle tactile diminuent lorsque vous le touchez. La valeur de seuil signifie que l’ESP32 se réveillera lorsque la valeur lue sur la broche tactile est inférieure à 40. Vous pouvez ajuster cette valeur en fonction de la sensibilité souhaitée.

Lecture recommandée: ESP32 Touch Peps avec Arduino IDE.

Important: Cependant, si vous utilisez un modèle ESP32-S2 ou ESP32-S3, les choses fonctionnent un peu différemment. Dans ce cas, plus la valeur est faible, plus la sensibilité est faible.

Remarque: les tacles sont numérotées comme suit (dans le cas de l’ESP32):

  • T0 (GPIO 4)
  • T1 (GPIO 0)
  • T2 (GPIO 2)
  • T3 (GPIO 15)
  • T4 (GPIO 13)
  • T5 (GPIO 12)
  • T6 (GPIO 14)
  • T7 (GPIO 27)
  • T8 (GPIO 33)
  • T9 (GPIO 32)

Si vous utilisez un ESP32-S2 ou ESP32-S3, la numérotation est différente.

Exemple de réveil de sommeil léger

Le code suivant se réveillera l’ESP32 lorsqu’il détecte le contact sur GPIO 15 (T3) ou GPIO27 (T7).

Remarque: j’ai testé cette source de réveil avec un sommeil léger, et dans mon cas, c’était un peu peu fiable. Cela fonctionnait bien parfois, et d’autres, l’ESP32 s’est écrasé après s’être réveillé. Je ne sais pas si c’est à cause de mon matériel ou du code. Essayez-le vous-même et vérifiez vos résultats. (Faites-moi savoir si vous avez des conseils pour rendre cette méthode plus fiable).

Remarque: Si vous utilisez ESP32-S2 ou ESP32-S3, il ne peut détecter que le réveil Touch sur un seul GPIO.

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

#if CONFIG_IDF_TARGET_ESP32
  #define THRESHOLD 40    // Greater the value, more the sensitivity 
#else                     // ESP32-S2 and ESP32-S3 + default for other chips (to be adjusted)
  #define THRESHOLD 5000  // Lower the value, more the sensitivity
#endif

int counter = 0;
const int ledPin = 2;  // GPIO pin for onboard LED
touch_pad_t touchPin;

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

//Method to print the touchpad by which ESP32 has been awaken from sleep
void print_wakeup_touchpad() {
  touchPin = esp_sleep_get_touchpad_wakeup_status();

#if CONFIG_IDF_TARGET_ESP32
  switch (touchPin) {
    case 0:  Serial.println("Touch detected on GPIO 4"); break;
    case 1:  Serial.println("Touch detected on GPIO 0"); break;
    case 2:  Serial.println("Touch detected on GPIO 2"); break;
    case 3:  Serial.println("Touch detected on GPIO 15"); break;
    case 4:  Serial.println("Touch detected on GPIO 13"); break;
    case 5:  Serial.println("Touch detected on GPIO 12"); break;
    case 6:  Serial.println("Touch detected on GPIO 14"); break;
    case 7:  Serial.println("Touch detected on GPIO 27"); break;
    case 8:  Serial.println("Touch detected on GPIO 33"); break;
    case 9:  Serial.println("Touch detected on GPIO 32"); break;
    default: Serial.println("Wakeup not by touchpad"); break;
  }
#else
  if (touchPin < TOUCH_PAD_MAX) {
    Serial.printf("Touch detected on GPIO %d\n", touchPin);
  } else {
    Serial.println("Wakeup not by touchpad");
  }
#endif
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  delay(1000);  //Take some time to open up the Serial Monitor

#if CONFIG_IDF_TARGET_ESP32
  //Setup sleep wakeup on Touch Pad 3 + 7 (GPIO15 + GPIO 27)
  touchSleepWakeUpEnable(T3, THRESHOLD);
  touchSleepWakeUpEnable(T7, THRESHOLD);
#else  //ESP32-S2 + ESP32-S3
  //Setup sleep wakeup on Touch Pad 3 (GPIO3)
  touchSleepWakeUpEnable(T3, THRESHOLD);
#endif

}

void loop() {
  Serial.printf("Counter: %d\n", counter);
  counter++;

  digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
  delay(5000);
  digitalWrite(ledPin, LOW);  // LED on to indicate wake-up

  Serial.println("Going into light sleep...");
  delay(500);
  esp_light_sleep_start(); 
  
  Serial.println("----------------------");
  Serial.println("Returning from light sleep");  
  delay(2000);
  
  print_wakeup_reason();
  print_wakeup_touchpad();
}

Afficher le code brut

Comment fonctionne le code?

Jetons un coup d’œil aux parties pertinentes de ce code.

Définition du seuil

La première chose que vous devez faire est de définir une valeur de seuil pour les broches tactiles.

#define THRESHOLD 40 // Greater the value, more the sensitivity

Les valeurs lues par une épingle tactile diminuent lorsque vous le touchez. La valeur de seuil signifie que l’ESP32 se réveillera lorsque la valeur lue sur la broche tactile est inférieure à 40. Vous pouvez ajuster cette valeur en fonction de la sensibilité souhaitée.

IMPORTANT: Cependant, si vous utilisez un modèle ESP32-S2 ou ESP32-S3, les choses fonctionnent un peu
différemment. C’est pourquoi il y a une section différente dans le code définissant un seuil différent pour ces conseils. Dans ce cas, plus la valeur est faible, plus la sensibilité est faible.

#if CONFIG_IDF_TARGET_ESP32
#define THRESHOLD 40 // Greater the value, more the sensitivity
#else // ESP32-S2 and ESP32-S3 + default for other chips (to be adjusted)
#define THRESHOLD 5000 // Lower the value, more the sensitivity
#endif

Raison de réveil et pavé tactile de réveil

Nous avons une fonction appelée print_wakeup_reason () pour vérifier et imprimer ce qui a provoqué le réveil.

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

Et une fonction appelée print_wakeup_touchpad () pour déterminer quelle broche tactile a provoqué le réveil.

// Method to print the touchpad by which ESP32 has been awaken from sleep
void print_wakeup_touchpad() {
  touchPin = esp_sleep_get_touchpad_wakeup_status();

#if CONFIG_IDF_TARGET_ESP32
  switch (touchPin) {
    case 0:  Serial.println("Touch detected on GPIO 4"); break;
    case 1:  Serial.println("Touch detected on GPIO 0"); break;
    case 2:  Serial.println("Touch detected on GPIO 2"); break;
    case 3:  Serial.println("Touch detected on GPIO 15"); break;
    case 4:  Serial.println("Touch detected on GPIO 13"); break;
    case 5:  Serial.println("Touch detected on GPIO 12"); break;
    case 6:  Serial.println("Touch detected on GPIO 14"); break;
    case 7:  Serial.println("Touch detected on GPIO 27"); break;
    case 8:  Serial.println("Touch detected on GPIO 33"); break;
    case 9:  Serial.println("Touch detected on GPIO 32"); break;
    default: Serial.println("Wakeup not by touchpad"); break;
  }
#else
  if (touchPin < TOUCH_PAD_MAX) {
    Serial.printf("Touch detected on GPIO %d\n", touchPin);
  } else {
    Serial.println("Wakeup not by touchpad");
  }
#endif

Définir les broches tactiles comme source de réveil

Pour définir une épingle tactile en tant que source de réveil, vous pouvez utiliser la fonction TouchSleepWakeuPenable () qui accepte comme arguments la broche tactile et la valeur de seuil qui réveillera la carte.

Dans cet exemple, il définit GPIO 15 (T3) et GPIO 27 (T7) en tant que sources de réveil avec la même valeur de seuil.

#if CONFIG_IDF_TARGET_ESP32
  // Setup sleep wakeup on Touch Pad 3 + 7 (GPIO15 + GPIO 27)
  touchSleepWakeUpEnable(T3, THRESHOLD);
  touchSleepWakeUpEnable(T7, THRESHOLD);

Si vous utilisez un modèle ESP32-S2 ou S3, l’exemple définit simplement le réveil sur GPIO 3 (T3). Notez que la numérotation tactile peut être différente en fonction du modèle de carte que vous utilisez.

#else // ESP32-S2 + ESP32-S3
  // Setup sleep wakeup on Touch Pad 3 (GPIO3)
  touchSleepWakeUpEnable(T3, THRESHOLD);

boucle()

Dans chaque boucle (), nous augmentons la variable de comptoir pour garder une trace du nombre de fois que l’ESP32 s’est réveillé. Nous allumons également la LED embarquée pendant quelques secondes avant de mettre l’ESP32 en mode de sommeil léger.

void loop() {
  Serial.printf("Counter: %d\n", counter);
  counter++;

  digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
  delay(5000);
  digitalWrite(ledPin, LOW); // LED on to indicate wake-up

  Serial.println("Going into light sleep...");
  delay(500);
  esp_light_sleep_start(); 

Après s’être réveillé du sommeil, l’ESP32 imprime la raison du réveil et la punie de touche a provoqué le réveil.

print_wakeup_reason();
print_wakeup_touchpad();

Câblage du circuit

Pour tester cet exemple, câblez un câble de cavalier à GPIO 15 et / ou GPIO 27, comme indiqué dans le schéma ci-dessous.

Toucher le réveil en câblant le circuit

Si vous utilisez un modèle ESP32-S2 ou ESP32-S3, veuillez vérifier l’emplacement de vos épingles tactiles.

Tester l’exemple

Téléchargez le code sur votre ESP32 et ouvrez le moniteur en série à un taux en bauds de 115200.

ESP32 Moniteur en série ouvert avec arduino ide

L’ESP32 passe en mode de sommeil profond.

Vous pouvez le réveiller en touchant le fil connecté pour toucher la broche 3 ou toucher la broche 7.

Épingles de capteur tactile ESP32 arduino ide

Lorsque vous touchez le fil, l’ESP32 s’affiche sur le moniteur en série: le numéro de démarrage, la cause du réveil et le GPIO sensible au toucher a provoqué le réveil.

ESP32 Light Sleep with Touch Revel-up Demonsive

Sommeil léger avec un réveil

L’ESP32 peut se réveiller du sommeil léger sur l’entrée UART en activant le réveil UART avec ESP_SLEEP_ENABLE_UART_WAKEUP ().

Vous devez également appeler la fonction UART_SET_WAKEUP_THRESHOLD () pour définir le nombre de bords positifs sur la broche RX qui provoquera le réveil. Trois bords positifs sont le nombre défini pour la plupart des cas.

L’exemple suivant montre comment réveiller l’ESP32 en utilisant UART. Cet exemple spécifique réveillera l’ESP32 sur UART 0. Nous enverrons un message via le moniteur série pour réveiller l’ESP32. Mais, pour une application pratique, vous voudrez connecter un capteur ou une autre carte à la broche ESP32 RX et envoyer des octets via Serial pour le réveiller.

Pour en savoir plus sur UART avec l’ESP32, nous vous recommandons de jeter un œil à notre guide: Communication UART ESP32 (série): Définissez des épingles, des interfaces, des données d’envoi et de réception (Arduino IDE).

/*********
  Rui Santos & Sara Santos - Raspberryme.com
  Complete project details at https://Raspberryme.com/esp32-light-sleep-arduino/
*********/

#include 

int counter = 0;
const int ledPin = 2;         // GPIO pin for onboard LED
String receivedMessage = "";  // Variable to store the complete message

// 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;
    case ESP_SLEEP_WAKEUP_UART:     Serial.println("Wakeup caused by UART"); break;
    default:                        Serial.printf("Wakeup was not caused by light sleep: %d\n", wakeup_reason); break;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  delay(1000);  //Take some time to open up the Serial Monitor

  // Enable UART wake-up from light sleep
  uart_set_wakeup_threshold(UART_NUM_0, 3);  // 3 edges on U0RXD to wakeup
  esp_sleep_enable_uart_wakeup(0);           // UART0 (default Serial (includes Serial Monitor))
}

void loop() {
  Serial.printf("Counter: %d\n", counter);
  counter++;

  digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
  delay(5000);
  digitalWrite(ledPin, LOW); // LED on to indicate wake-up

  Serial.println("Going into light sleep...");
  delay(500);
  esp_light_sleep_start(); 
  
  Serial.println("----------------------");
  Serial.println("Returning from light sleep");  
  delay(2000);
  
  print_wakeup_reason();
   // Clear the internal wake-up indication by sending some extra data
  Serial.write(' ');   // Send a single space character

 while (Serial.available()) {
    char incomingChar = Serial.read();  // Read each character from the buffer
    
    if (incomingChar == '\n') {  // Check if the user pressed Enter (new line character)
      // Print the message
      Serial.print("You sent: ");
      Serial.println(receivedMessage);
      
      // Clear the message buffer for the next input
      receivedMessage = "";
    } else {
      // Append the character to the message string
      receivedMessage += incomingChar;
    }
  }  
}

Afficher le code brut

Ce code est similaire aux exemples précédents mais utilise le réveil UART. Nous appelons les deux fonctions suivantes dans la configuration () pour configurer le réveil UART sur UART0 (qui est également l’UART utilisé pour la communication série avec le moniteur série).

// Enable UART wake-up from light sleep
uart_set_wakeup_threshold(UART_NUM_0, 3);   // 3 edges on U0RXD to wakeup
esp_sleep_enable_uart_wakeup(0); // UART0 (default Serial (includes Serial Monitor))

Dans la LOOP (), nous appelons la fonction ESP_light_sleep_start () pour mettre l’ESP32 en mode de sommeil profond.

esp_light_sleep_start(); 

Lorsqu’il se réveille du sommeil, il imprime la raison de réveil et vérifie s’il a des données UART entrantes à lire.

print_wakeup_reason();
// Clear the internal wake-up indication by sending some extra data
Serial.write(' ');   // Send a single space character

while (Serial.available()) {
  char incomingChar = Serial.read();  // Read each character from the buffer
    
  if (incomingChar == '\n') {  // Check if the user pressed Enter (new line character)
    // Print the message
    Serial.print("You sent: ");
    Serial.println(receivedMessage);
      
    // Clear the message buffer for the next input
    receivedMessage = "";
  } else {
    // Append the character to the message string
    receivedMessage += incomingChar;
  }
}  

Ensuite, il commence à exécuter la boucle () depuis le début. Il augmente le numéro de comptoir et illumine la LED embarquée avant de recommencer.

Serial.printf("Counter: %d\n", counter);
counter++;

digitalWrite(ledPin, HIGH); // LED on to indicate wake-up
delay(5000);
digitalWrite(ledPin, LOW); // LED on to indicate wake-up

Serial.println("Going into light sleep...");
delay(500);
esp_light_sleep_start(); 

Tester le code

Après avoir téléchargé le code sur la carte, ouvrez le moniteur série à un taux en bauds de 115200. L’ESP32 passera en mode de sommeil léger.

Envoyez quelque chose à l’ESP32 via Serial à l’aide du moniteur série – un seul caractère fera l’affaire. L’ESP32 se réveillera instantanément et reprendra le code où il est parti. Si vous voulez qu’il lise les données série, vous devez les envoyer juste après le réveil.

ESP32 Light Sleep réveil en utilisant UART

Emballage

Dans ce tutoriel, nous avons examiné le sommeil léger avec l’ESP32 et différentes façons de le réveiller. Il prend en charge le réveil de la minuterie, le réveil externe à l’aide des GPIO, en utilisant les broches tactiles, et même via UART.

Nous espérons que vous avez trouvé ce tutoriel utile. Si vous avez besoin d’une option plus économique, vous voudrez peut-être jeter un œil à un sommeil profond avec l’ESP32 à la place:

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 :

YouTube video

  • DIYables ESP32 ESP-WROOM-32 Carte de développement WiFi et Bluetooth, 38 broches, avec USB Type-C et CP2102, microcontrôleur ESP32 double cœur pour projets IoT, compatible avec Arduino IDE
  • iHaospace ESP32-DevKitC Core Board ESP32-WROOM-32U Development Board ESP32 WiFi Bluetooth Development Board (WROOM-32U)