Skip to content
Home » Embedded Systems » Sleep Modes and Low Power Techniques in Microcontrollers

Sleep Modes and Low Power Techniques in Microcontrollers

Sleep Modes and Low Power Techniques featured image with dark olive background, POWER badge, Zzz icon in gold circle, and Deep Sleep Idle and Wake-Up Sources subtitle by nerdyelectronics.com
Embedded Systems Learning Path
Part 84 of 129View Full Path →

KEY TAKEAWAYS

  • Sleep modes reduce power consumption by disabling the CPU, peripherals, or both while idle
  • Common modes range from idle (CPU halted, peripherals active) to deep sleep (most systems off)
  • Wake-up sources include external interrupts, timers, and communication events
  • Effective low-power design combines sleep modes with duty cycling and peripheral power gating

What are Sleep Modes?

Sleep modes are low-power states that a microcontroller can enter when it has no immediate work to do. Instead of wasting energy running an idle loop, the MCU shuts down some or all of its internal components to reduce current draw from milliamps down to microamps or even nanoamps.

The MCU wakes up when an event occurs: a timer expires, an external interrupt triggers, or a communication peripheral receives data.

Common Sleep Mode Levels

Most microcontrollers offer several sleep modes with increasing levels of power savings:

Sleep ModeWhat is OFFWhat is ONTypical CurrentWake-up Time
Idle / SleepCPU clockPeripherals, RAM, clock system1-5 mAInstant (1-2 cycles)
Light SleepCPU, most peripheralsRAM, RTC, selected peripherals0.1-1 mAFast (microseconds)
Deep SleepCPU, RAM, most peripheralsRTC, wake-up logic1-50 uASlow (milliseconds, re-init needed)
Shutdown / HibernateNearly everythingOnly wake-up pin logic0.1-1 uASlowest (full reboot)

The deeper the sleep, the more power you save, but the longer it takes to wake up and the more state you lose.

Sleep Modes on Popular Platforms

ESP32

ModeCurrentWake Sources
Active (WiFi)95-240 mAN/A
Modem Sleep20 mAAutomatic (WiFi stays associated)
Light Sleep0.8 mATimer, GPIO, touch, UART
Deep Sleep10 uATimer, ext0/ext1 GPIO, touch, ULP
Hibernation5 uATimer, RTC GPIO only
// ESP32 Deep Sleep example (ESP-IDF)
#include "esp_sleep.h"

void app_main(void) {
    // Read sensor
    float temp = read_temperature();
    send_data_mqtt(temp);

    // Configure wake-up after 15 minutes
    esp_sleep_enable_timer_wakeup(15 * 60 * 1000000ULL);  // microseconds

    // Or wake on GPIO (e.g., button press)
    esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0);  // Wake when GPIO33 goes LOW

    // Enter deep sleep
    esp_deep_sleep_start();
    // Code after this line never executes
    // On wake-up, the program restarts from app_main()
}

STM32 (Cortex-M)

ModeCurrent (STM32L4)Wake Sources
Run3-10 mAN/A
Sleep1-3 mAAny interrupt
Low-Power Sleep~100 uAAny interrupt
Stop 0/1/21-10 uAEXTI, RTC, LPUART, I2C
Standby0.3 uAWKUP pins, RTC
Shutdown0.03 uA (30 nA)WKUP pins only
// STM32 HAL - Enter Stop Mode 2
void enter_low_power(void) {
    // Disable unused clocks
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();

    // Configure wake-up source (e.g., RTC alarm in 60 seconds)
    set_rtc_alarm(60);

    // Enter Stop Mode 2
    HAL_SuspendTick();
    HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);

    // Execution resumes here after wake-up
    HAL_ResumeTick();
    SystemClock_Config();  // Reconfigure clocks
}

Arduino (ATmega328P)

#include <avr/sleep.h>
#include <avr/wdt.h>

void enter_sleep(void) {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Deepest sleep
    sleep_enable();

    // Disable ADC (saves ~300 uA)
    ADCSRA &= ~(1 << ADEN);

    // Disable BOD during sleep (saves ~25 uA)
    sleep_bod_disable();

    sleep_cpu();  // Actually go to sleep

    // Execution continues here after wake-up
    sleep_disable();
    ADCSRA |= (1 << ADEN);  // Re-enable ADC
}

// Wake-up via watchdog timer interrupt
ISR(WDT_vect) {
    // Watchdog fired - MCU wakes up
}

Wake-up Sources

Timer / RTC Wake-up

The most common method. A low-power timer (RTC) counts while the MCU sleeps and triggers a wake-up after a set duration. Ideal for periodic tasks like sensor readings.

External Interrupt (GPIO)

A change on a pin (button press, sensor alert, motion detection) wakes the MCU. Ideal for event-driven devices that should only wake when something happens.

Communication Peripheral

Some MCUs can wake on UART data received or I2C address match while in light sleep. This allows the device to respond to external commands without staying fully awake.

Touch Pad (ESP32)

The ESP32 can wake from deep sleep when a capacitive touch pad is activated, useful for devices with touch interfaces.

The Duty Cycling Pattern

The most common low-power design pattern is duty cycling: wake up, do work, go back to sleep.

    Active    Sleep           Active    Sleep
    |‾‾‾‾|___________________|‾‾‾‾|___________________
    2ms        14,998ms       2ms        14,998ms
    10mA       5uA            10mA       5uA

    Duty Cycle = 2ms / 15,000ms = 0.013%
    Average Current = (10mA x 0.00013) + (5uA x 0.99987) = 6.3 uA

Even though the active current is 10mA, the average drops to just 6.3 uA because the device sleeps 99.99% of the time.

Practical Low-Power Tips

  1. Disable ADC before sleeping. The ADC draws significant current even when not converting. On AVR, this alone saves 300 uA.
  2. Configure unused GPIO pins. Floating input pins can oscillate and draw current. Set unused pins as outputs (driven low) or inputs with pull-ups/pull-downs.
  3. Use the lowest clock speed needed. Run at 1 MHz for simple tasks, boost to full speed only for computation-heavy work.
  4. Minimize LED usage. A single LED at 10mA can consume more than the entire MCU in sleep. Use brief blinks instead of steady-on indicators.
  5. Store data in RTC memory. On ESP32, RTC memory survives deep sleep. Store state there to avoid re-initialization:
    RTC_DATA_ATTR int boot_count = 0;  // Persists across deep sleep cycles
    
    void app_main(void) {
        boot_count++;
        printf("Boot #%d\n", boot_count);
    }
  6. Batch operations. If you need to send 6 sensor readings per hour, sleep for 10 minutes, store the reading in RAM, and send all 6 at once every hour. One WiFi connection every hour uses far less energy than six.

Summary

Sleep modes are the most effective tool for extending battery life in embedded systems. The key principle is simple: if the MCU has nothing to do, put it to sleep. Choose the deepest sleep mode your application allows, wake up only when needed, do the work as fast as possible, and go back to sleep. A well-designed duty cycling system can extend battery life from days to years.

Leave a Reply

Your email address will not be published. Required fields are marked *