Table of Contents

The ULP (Ultra-Low-Power Coprocessor) coprocessor is a specialized processor built into the ESP32 to handle tasks while the main CPU is in deep sleep or hibernation. The main advantage is that it allows the ESP32 to stay in a low-power state while still performing tasks, such as monitoring sensors or waiting for an event, without waking up the main CPU. The ULP coprocessor can then trigger a wake-up of the main ESP32 CPU when needed.

How ULP Coprocessor Wake-Up Works

  1. ULP Operation in Deep Sleep:

When the ESP32 enters deep sleep, the main CPU is powered off, but the ULP coprocessor and some RTC peripherals remain active, consuming only a very small amount of power (~10 µA).

  1. ULP Tasks:

The ULP coprocessor can be programmed to perform tasks like:

  • Monitoring GPIO pins for changes (e.g., detecting button presses or changes in a sensor).
  • Performing analog-to-digital conversions (ADC).
  • Running simple logic to trigger wake-ups.
  1. Wake-Up Condition:

Once the ULP coprocessor detects the specified condition (e.g., a GPIO pin change, a sensor threshold met), it can trigger a wake-up of the main ESP32 CPU, transitioning it from deep sleep or hibernation.

  1. Low Power Consumption:

Since the ULP coprocessor is designed for ultra-low power consumption, this allows the ESP32 to remain in deep sleep for extended periods with minimal power usage while still being able to react to external events.

Example of ULP Coprocessor Wake-Up

Here’s a simple example of how to use the ULP coprocessor to wake up the ESP32 when a GPIO pin (e.g., GPIO12) goes LOW.

Code to Program ULP Coprocessor to Monitor GPIO

#include <esp_sleep.h>
#include <driver/ulp.h>

#define ULP_PROGRAM_SIZE 200  // Size of the ULP program
#define GPIO_WAKEUP_PIN GPIO_NUM_12  // GPIO used to wake up the ESP32

void setup() {
    Serial.begin(115200);
    delay(1000);

    Serial.println("Uploading ULP program to monitor GPIO12...");

    // Load ULP program from file (ULP assembly code)
    ulp_load_binary(0, (const uint32_t*)ulp_program_bin_start, ULP_PROGRAM_SIZE);

    // Set up ULP wake-up condition (GPIO12 falling edge)
    ulp_set_wakeup_period(0, 1000 * 1000);  // Check every second (1,000,000 us)
    ulp_run((&ulp_entry) - 1);  // Start the ULP program

    // Enable wake-up on GPIO12 falling edge
    esp_sleep_enable_ext0_wakeup(GPIO_WAKEUP_PIN, 0);  // Wake up on GPIO LOW (falling edge)

    // Enter deep sleep
    Serial.println("Entering deep sleep mode...");
    esp_deep_sleep_start();
}

void loop() {
    // This will not execute after wake-up, as the ESP32 will restart
}

Explanation:

  1. ULP Program Upload: The ULP program, usually written in ULP assembly, is loaded into the ESP32’s ULP memory using the ulp_load_binary() function. This program monitors the GPIO pin (e.g., GPIO12).
  2. GPIO Wake-Up: The ULP program is configured to check the GPIO pin (GPIO12) every second. If it detects a falling edge (when the GPIO pin goes LOW), it triggers the main ESP32 to wake up from deep sleep.
  3. Enter Deep Sleep: The ESP32 enters deep sleep using esp_deep_sleep_start(), while the ULP coprocessor continues monitoring the GPIO pin.

Benefits of Using ULP Coprocessor:

  • Low Power Consumption: The ULP coprocessor consumes significantly less power (~5–10 µA), so the main ESP32 can stay in deep sleep without worrying about power loss from background tasks.
  • Fast Wake-Up: The ESP32 can wake up and start executing code as soon as the ULP coprocessor triggers an event, providing an efficient mechanism for handling external events without much delay.
  • Extended Battery Life: Perfect for battery-powered applications where the ESP32 needs to stay in a low-power state for long periods but still respond to events, such as environmental changes or user input.

Categorized in:

Deep Sleep,

Tagged in: