yahboom
HomeLearn
Solution
Blog
Online Store
About Us
EN/中文
ESP32 Core Board📖
1. ESP32 Introduction
  • 1. ESP32S3 Overview
  • 2. Environment Setup Introduction
  • 3. Dev Board Introduction
2. ESP-IDF Development Tutorial
1. Before Development
  • 1. Environment Setup (Windows)
  • 2. Environment Setup (Linux)
  • 3. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. DMA
  • 8. ADC
  • 9. PWM Breathing LED
  • 10. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. PSRAM External Memory Experiment
  • 5. Flash Read and Write Experiment
  • 6. USB Emulated Mass Storage Experiment
4. FreeRTOS operating system
  • 1.FreeRTOS Core Concepts Theory
  • 2.Task Creation and Management
  • 3.Queue
  • 4.Binary Semaphore
  • 5.Mutex
  • 6.Event Groups
  • 7.Software Timer
  • 8.Task Scheduler
  • 9.Low Power Mode
  • 10.Deadlock
  • 11.Priority Inversion
5. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. Socket Programming Basics
  • 9. HTTP Client Experiment
  • 10. HTTP Server Experiment
  • 11. MQTT IoT Communication Protocol
  • 12. WIFI OTA Upgrade
  • 13. Bluetooth Fundamentals
  • 14. Bluetooth Slave Mode
  • 15. Bluetooth Master Mode
6. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
7. Xiaozhi AI Voice
  • 1. Burn Xiaozhi Firmware
  • 2. Network and Configuration
  • 3. AI Agent Settings
  • 4. Program Analysis
  • 5. Free Chat
3. Arduino Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. ESP_TIMER
  • 5. GPTIMER
  • 6. Watchdog Timer
  • 7. ADC
  • 8. PWM Breathing LED
  • 9. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication
  • 2. I2C OLED Display
  • 3. SPI Bus Communication
  • 4. Flash Read and Write
  • 5. USB Emulated Mass Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Server Experiment
  • 5. UDP Client Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT IoT Communication Protocol
  • 11. WIFI OTA Upgrade
  • 12. Bluetooth Fundamentals
  • 13. Bluetooth Slave Mode
  • 14. Bluetooth Master Mode
5. Audio Applications
  • 1.I2S Microphone Recording and U-Disk Playback
  • 2.I2S Audio Playback Experiment
  • 3.Repeater Experiment
4. MicroPython Development Course
1. Before Development
  • 1. Environment Setup
  • 2. Build and Flash
  • 3. Thonny IDE
2. Basic Peripherals
  • 1. LED Control
  • 2. Button Detection
  • 3. Peripheral Interrupts
  • 4. TIMER_IT
  • 5. Watchdog Timer
  • 6. ADC
  • 7. PWM Breathing LED
  • 8. RGB LED Effects
3. Serial Communication and Storage System
  • 1. Serial UART Communication Experiment
  • 2. I2C_OLED Display Experiment
  • 3. SPI Bus Communication Experiment
  • 4. Flash Read and Write Experiment
  • 5. Print Storage
4. Network Protocols and Wireless Communication
  • 1. WIFI Network Basics
  • 2. WIFI STA Mode
  • 3. WIFI AP Mode
  • 4. UDP Client Experiment
  • 5. UDP Server Experiment
  • 6. TCP Client Experiment
  • 7. TCP Server Experiment
  • 8. HTTP Client Experiment
  • 9. HTTP Server Experiment
  • 10. MQTT
  • 11. Bluetooth Fundamentals
  • 12. Bluetooth Slave Mode
  • 13. Bluetooth Master Mode
5. Audio Applications
  • 1. I2S Audio Playback Experiment
  • 2. Repeater Experiment
Download
  • Code
  • Hardware_Info
  • 3D_Model_File
  • Software_Tools
  • VMware
  • VM_File
Download ZIP

Welcome to ESP32 Core Board repository

9.Low Power Mode

Low Power Mode


Low Power Mode1. Deep Sleep Overview2. Core Concepts2.1 ESP32-S3 Power Mode Comparison2.2 Deep Sleep API2.3 Wakeup Cause Enum2.4 Program Behavior After Deep Sleep3. Project Architecture and Flow4. Hardware Dependencies5. Source Code Analysis5.1 Header Files and Macro Configuration5.2 Functional Decomposition5.2.1 Function Declarations5.2.2 Print Wakeup Cause5.2.3 Pin Configuration5.2.4 Countdown Loop5.2.5 Enter Deep Sleep5.2.6 Main Entry6. Operation Flow6.1 Compilation and Flashing Flow6.2 Power-on Cold Boot6.3 GPIO Wakeup6.4 GPIO4 Prevents Sleep6.5 Button Resets Countdown7. FAQ


1. Deep Sleep Overview

Deep Sleep is the lowest power consumption mode for ESP32-S3. After entering deep sleep, the CPU is completely powered off, RAM content is lost (except RTC memory), and only the RTC domain remains operational, with power consumption dropping to ~5μA.

Importance and Application Scenarios: Deep sleep is the core method for battery-powered IoT devices to achieve long battery life. Typical scenarios include: sensor nodes collect data at intervals then sleep, remote controls send signals on button wakeup, door/window magnetic sensors and other security devices triggered by GPIO level for wakeup. Proper use of deep sleep can extend battery life from hours to months or even years — a technology that must be mastered in low-power product design.

After wakeup, the chip re-executes from app_main() (equivalent to cold boot reset). You can distinguish wakeup reasons via esp_sleep_get_wakeup_cause().

This project demonstrates: 5-second countdown into deep sleep, GPIO4 connected to high level prevents sleep, button resets countdown. GPIO0 low level wakeup.


2. Core Concepts

2.1 ESP32-S3 Power Mode Comparison

ModeCPURAMWakeup MethodPower ConsumptionWakeup Time
ActiveFull speedFull retention—~tens of mA—
Modem SleepRunningFull retentionAny interrupt~few mA—
Light SleepPausedFull retentionGPIO/Timer/...~0.8mA~1ms
Deep SleepPowered offLost (except RTC)RTC GPIO/Timer~5μA~1ms (reset)
HibernationPowered offLostRTC Timer only~3μA~1ms

2.2 Deep Sleep API

​x
// Enable ext0 wakeup (single GPIO level)
esp_err_t esp_sleep_enable_ext0_wakeup(
    gpio_num_t gpio_num,        // Wakeup pin
    // Wakeup level (0=low, 1=high)
    int level
);

// Get wakeup cause
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void);

// Enter deep sleep (never returns — chip resets)
void esp_deep_sleep_start(void);

2.3 Wakeup Cause Enum

Enum ValueMeaning
ESP_SLEEP_WAKEUP_UNDEFINEDPower-on cold boot (not wakeup)
ESP_SLEEP_WAKEUP_GPIOext0/ext1 GPIO wakeup
ESP_SLEEP_WAKEUP_TIMERRTC timer wakeup
ESP_SLEEP_WAKEUP_TOUCHPADTouch sensor wakeup
ESP_SLEEP_WAKEUP_ULPULP coprocessor wakeup

2.4 Program Behavior After Deep Sleep

xxxxxxxxxx
Power-on / Wakeup
     │
     ▼
   Bootloader
     │
     ▼
   app_main() — Execute from scratch
     │
     ├─ esp_sleep_get_wakeup_cause() determine cause
     │   ├─ ESP_SLEEP_WAKEUP_GPIO   → "Woken by button"
     │   └─ ESP_SLEEP_WAKEUP_UNDEFINED → "Power-on cold boot"
     │
     └─ Normal execution... → Enter sleep again

3. Project Architecture and Flow

xxxxxxxxxx
app_main()
  ├─ print_wakeup_cause()    ← Detect wakeup cause (GPIO wakeup / power-on cold boot)
  ├─ configure_pins()        ← Configure GPIO0 (button) and GPIO4 (prevent)
  ├─ run_countdown()         ← Countdown main loop (5 seconds, 100ms polling)
  │   ├─ GPIO4=high → countdown locked at 5 (prevent sleep)
  │   ├─ Button pressed (≥50ms) → countdown reset to 5
  │   └─ Every 1 second countdown--
  └─ enter_deep_sleep()      ← Configure ext0 wakeup source and enter deep sleep
        │
        ▼
    GPIO0 low level → chip reset → app_main() re-executes

Countdown Parameters:

ParameterValueMeaning
Countdown initial value5 secondsSleep after 5 seconds with no prevent/no button
Polling period100msCheck GPIO status every 100ms
Debounce time50msButton debounce
Wakeup methodext0 (GPIO0 low level)Press BOOT button to wakeup

4. Hardware Dependencies

PinFunctionDescription
GPIO 0Button + wakeup sourceLow level wakeup (ext0 wakeup); pressing also resets countdown
GPIO 4Sleep prevent pinHigh=prevent countdown, low/floating=allow countdown (internal pull-down)

Required Components: freertos/FreeRTOS, freertos/task, esp_sleep, driver/gpio, esp_log


5. Source Code Analysis

Full source code: Source Code → ESP-IDF → 4.FreeRTOS → 5. LOW_Power

5.1 Header Files and Macro Configuration

Project needs to include FreeRTOS, power management (esp_sleep), and GPIO driver headers, and define runtime parameters like countdown seconds and debounce time.

xxxxxxxxxx
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_err.h"
#include "esp_log.h"
// Deep-sleep API
#include "esp_sleep.h"
#include "driver/gpio.h"                             // GPIO driver

// Wake-up button
#define WAKE_UP_PIN     GPIO_NUM_0
// Hold pin (HIGH=hold)
#define HOLD_PIN        GPIO_NUM_4
// Debounce time
#define DEBOUNCE_MS     50
// Countdown seconds
#define COUNTDOWN_SEC   5

static const char *TAG = "DEEP_SLEEP";               // Log tag

5.2 Functional Decomposition

app_main() is split into 4 independent static functions, each with single responsibility, easy to read and maintain.

Reading order: Static function definitions are earlier in the file, app_main() is at the end.

5.2.1 Function Declarations

Forward declarations allow app_main() to be written at the end, keeping the main function visible at a glance.

xxxxxxxxxx
// Print wake-up cause
static void print_wakeup_cause(void);
// Configure GPIO pins
static void configure_pins(void);
// Countdown main loop
static void run_countdown(void);
// Enter deep sleep
static void enter_deep_sleep(void);

5.2.2 Print Wakeup Cause

Read wakeup cause register, distinguish GPIO wakeup from power-on cold boot.

xxxxxxxxxx
static void print_wakeup_cause(void)
{
    // Read wake-up cause
    uint32_t cause = esp_sleep_get_wakeup_cause();
    if (cause & ESP_SLEEP_WAKEUP_GPIO) {
        ESP_LOGI(TAG, "GPIO Wakeup!");               // GPIO wakeup
    } else {
        // Power-on boot
        ESP_LOGI(TAG, "Power-on Startup");
    }
}

5.2.3 Pin Configuration

Configure two GPIOs: button pin pull-up input for polling debounce, hold pin pull-down input to ensure sleep allowed when floating.

xxxxxxxxxx
static void configure_pins(void)
{
    /* Button pin (pull-up input, polling debounce only) */
    gpio_config_t btn_conf = {
        .pin_bit_mask = BIT64(WAKE_UP_PIN),
        .mode         = GPIO_MODE_INPUT,             // Input mode
        // Pull-up enabled
        .pull_up_en   = GPIO_PULLUP_ENABLE,
        // Pull-down disabled
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        // No ISR, polling only
        .intr_type    = GPIO_INTR_DISABLE,
    };
    ESP_ERROR_CHECK(gpio_config(&btn_conf));

    /* Hold pin (pull-down, floating=0=allow sleep) */
    gpio_config_t hold_conf = {
        .pin_bit_mask = BIT64(HOLD_PIN),
        .mode         = GPIO_MODE_INPUT,             // Input mode
        // Pull-up disabled
        .pull_up_en   = GPIO_PULLUP_DISABLE,
        // Pull-down enabled
        .pull_down_en = GPIO_PULLUP_ENABLE,
        // No ISR, level-read only
        .intr_type    = GPIO_INTR_DISABLE,
    };
    ESP_ERROR_CHECK(gpio_config(&hold_conf));

    ESP_LOGI(TAG, "BTN GPIO%u + HOLD GPIO%u ready", WAKE_UP_PIN, HOLD_PIN);
}

5.2.4 Countdown Loop

Poll at 100ms period, handle GPIO4 hold check, button debounce, and countdown decrement every second simultaneously.

xxxxxxxxxx
static void run_countdown(void)
{
    // Current countdown
    int countdown = COUNTDOWN_SEC;
    // 100ms tick counter
    int tick_cnt  = 0;
    bool       last_hold    = false;
    // Prev button (1=released)
    bool       btn_prev     = true;
    // Button edge tick
    TickType_t btn_chg_tick = 0;

    ESP_LOGI(TAG, "Enter deep sleep in %d...", countdown);

    while (countdown > 0) {
        // 100ms polling
        vTaskDelay(pdMS_TO_TICKS(100));
        tick_cnt++;

        /* -- GPIO4 Hold Check -- */
        bool hold = (gpio_get_level(HOLD_PIN) != 0); // HIGH=hold

        // Edge-print only
        if (hold != last_hold) {
            ESP_LOGI(TAG, "GPIO%u %s", HOLD_PIN,
                     hold ? "HIGH, holding countdown" : "LOW, countdown resumed");
            last_hold = hold;
        }

        if (hold) {
            // Lock countdown
            countdown = COUNTDOWN_SEC;
            tick_cnt  = 0;                           // Reset tick
            continue;
        }

        /* -- Button Debounce (polling) -- */
        bool btn_raw = (gpio_get_level(WAKE_UP_PIN) == 0); // 1=pressed

        if (btn_raw != btn_prev) {
            // Record edge time
            btn_chg_tick = xTaskGetTickCount();
            btn_prev = btn_raw;
        }

        /* LOW stable ≥ 50ms → confirmed press */
        TickType_t now = xTaskGetTickCount();
        if (btn_raw && ((now - btn_chg_tick) >= pdMS_TO_TICKS(DEBOUNCE_MS))) {
            ESP_LOGI(TAG, "Button pressed! Countdown -> %d s", COUNTDOWN_SEC);
            // Reset countdown
            countdown = COUNTDOWN_SEC;
            tick_cnt  = 0;

            /* Wait release + release debounce */
            while (gpio_get_level(WAKE_UP_PIN) == 0) {
                // 10ms release poll
                vTaskDelay(pdMS_TO_TICKS(10));
            }
            // Release debounce
            vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_MS));
            // Confirmed released
            btn_prev = true;
            continue;
        }

        /* -- Countdown Decrement (every 1s) -- */
        if (tick_cnt >= 10) {                        // 10×100ms = 1s
            tick_cnt = 0;
            countdown--;
            ESP_LOGI(TAG, "Enter deep sleep in %d...", countdown);
        }
    }
}

5.2.5 Enter Deep Sleep

Configure ext0 wakeup source then call esp_deep_sleep_start(). This function never returns — the chip will reset.

xxxxxxxxxx
static void enter_deep_sleep(void)
{
    esp_sleep_enable_ext0_wakeup(WAKE_UP_PIN, 0);
    ESP_LOGI(TAG, "Enter DEEP SLEEP mode");
    // Wait UART flush
    vTaskDelay(pdMS_TO_TICKS(50));
    // Sleep (never returns)
    esp_deep_sleep_start();
}

5.2.6 Main Entry

app_main() only calls 4 functions, main flow is clear at a glance.

xxxxxxxxxx
void app_main(void)
{
    // Print wake-up cause
    print_wakeup_cause();
    // Configure GPIO pins
    configure_pins();
    // Countdown loop
    run_countdown();
    // Enter deep sleep
    enter_deep_sleep();
}

BIT64(n) vs 1ULL << n: BIT64(n) is a macro provided by ESP-IDF, equivalent to (1ULL << (n)), used for GPIO bit masks exceeding 32 bits — a fixed safe写法.


6. Operation Flow

6.1 Compilation and Flashing Flow

For detailed flashing process, see: 1. Before Development → 3. Build and Flash

6.2 Power-on Cold Boot

xxxxxxxxxx
Power-on Startup
BTN GPIO0 + HOLD GPIO4 ready
Enter deep sleep in 5...
Enter deep sleep in 4...
Enter deep sleep in 3...
Enter deep sleep in 2...
Enter deep sleep in 1...
Enter DEEP SLEEP mode

上电冷启动

6.3 GPIO Wakeup

Press BOOT button (GPIO0 low level) to wakeup chip:

xxxxxxxxxx
GPIO Wakeup!                     ← Detected GPIO wakeup
BTN GPIO0 + HOLD GPIO4 ready
Enter deep sleep in 5...

按键唤醒

6.4 GPIO4 Prevents Sleep

Connect GPIO4 to 3.3V:

xxxxxxxxxx
Enter deep sleep in 5...
GPIO4 HIGH, holding countdown    ← Countdown locked at 5
GPIO4 LOW, countdown resumed     ← Resumed after connecting GPIO4 to GND

GPIO4阻止休眠

GPIO4接3.3V引脚连线图

GPIO4接3.3V引脚连线图——背面

6.5 Button Resets Countdown

Press BOOT button during countdown:

xxxxxxxxxx
Enter deep sleep in 3...         ← 3 seconds remaining
Button pressed! Countdown -> 5 s ← Reset to 5 seconds
Enter deep sleep in 5...

Button 阻止进去深度睡眠

 


7. FAQ

SymptomCauseSolution
Cannot sleep again after wakeupLogic after esp_deep_sleep_start() skippedCheck while(countdown>0) loop logic
Button cannot wakeupext0 wakeup source config error / level mismatchConfirm esp_sleep_enable_ext0_wakeup(GPIO0, 0)
Garbled output after wakeupUART buffer not fully flushedDelay 50ms before esp_deep_sleep_start()
GPIO4 floating prevents sleepPull-down resistor not configuredConfigure pull_down_en = GPIO_PULLDOWN_ENABLE
Analog input consumes power during deep sleepGPIO not configured for RTC domainBefore deep sleep, configure unused GPIOs as GPIO_MODE_DISABLE or RTC GPIO
Counter doesn't reset after wakeupNormal — wakeup=reset, countdown re-initialized to 5—
Task Scheduler
Deadlock

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文