ESP32 Power Management: Deep Sleep for On/Off System (Code)

Hello everyone,

As a student with a deep passion for Arduino and ESP32, I'm excited to share with you a code I recently developed to implement an On/Off power management system using an ESP32 module with Deep Sleep mode. I want to emphasize that I'm not yet an expert, but I believe this experience can be valuable for other beginners like myself.

Code Description: The code I'm sharing here enables the implementation of an On/Off power management system using a push-button and the ESP32's Deep Sleep mode. Here's an overview of its main features:

  • The ESP32 enters Deep Sleep mode to conserve power when the system is in the "off" state.
  • A push-button is used to activate/deactivate the system by holding it down for a short duration.
  • The code handles button events such as single clicks, double clicks, and repeated long presses.
  • It prints the reasons for waking up from Deep Sleep (wakeup reasons).

I'd be thrilled to discuss the logic behind the code, its benefits, potential applications, and any questions you may have. I'm still in the learning process, so your guidance and experiences are highly appreciated.

Source Code: Here's the complete source code I used. It was developed using the AceButton library for button management:

/*
  Author: SanaYasfp <yasfp.pro@gmail.com>
  Description: This code implements an On/Off system with power management using an ESP32 microcontroller and a push button.
  It prints wakeup reasons and handles button events.
*/

#include <Arduino.h>
#include <AceButton.h>

using namespace ace_button;

// Task to blink the built-in LED
void xTaskBlink(void *pvParameters);

// Event handler for button actions
void handleEvent(AceButton *, uint8_t, uint8_t);

// Method to print the reason for waking up from sleep
void print_wakeup_reason();

RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR bool isSystemON = false;
const int BUTTON_PIN = GPIO_NUM_33;

AceButton button(BUTTON_PIN, LOW);

void setup()
{
  // Initialize the serial communication for debugging
  Serial.begin(9600);

  // Increment boot count and print it every reboot
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  // Print the wakeup reason for ESP32
  print_wakeup_reason();

  // Set button pin and LED pin as input and output respectively
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  // Configure button features and event handler
  ButtonConfig *buttonConfig = button.getButtonConfig();
  buttonConfig->setEventHandler(handleEvent);
  buttonConfig->setFeature(ButtonConfig::kFeatureClick);
  buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
  buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress);
  buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick);
  buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterDoubleClick);
  buttonConfig->setFeature(ButtonConfig::kFeatureSuppressAfterClick);

  // Setup wakeup with ext0 on a rising edge (button press)
  esp_sleep_enable_ext0_wakeup(static_cast<gpio_num_t>(BUTTON_PIN), 1);

  // Delay to check if the button was pressed during boot
  delay(2500);
  bool buttonPressedOnBooting = button.isPressedRaw();

  // Check if the button was pressed during boot and system is not already on
  if (buttonPressedOnBooting && !isSystemON)
  {
    Serial.println("Button pressed on booting");
    isSystemON = true;
  }
  else
  {
    Serial.println("Button not pressed on booting");
    Serial.println("Going to sleep now");
    isSystemON = false;
    delay(500);
    // Enter deep sleep mode to save power
    esp_deep_sleep_start();
  }

  // Create a task to blink the built-in LED
  xTaskCreatePinnedToCore(xTaskBlink, "blink_builtin_led", 4096, NULL, 1, NULL, 0);
}

void loop()
{
  // Check the button state and handle button events
  button.check();
}

// Method to print the reason for waking up from sleep
void print_wakeup_reason()
{
  esp_sleep_wakeup_cause_t wakeup_reason;

  // Get the wakeup reason
  wakeup_reason = esp_sleep_get_wakeup_cause();

  // Print the wakeup reason
  switch (wakeup_reason)
  {
  case ESP_SLEEP_WAKEUP_EXT0:
    Serial.println("Wakeup caused by an external signal using RTC_IO");
    break;
  case ESP_SLEEP_WAKEUP_EXT1:
    Serial.println("Wakeup caused by an external signal using RTC_CNTL");
    break;
  case ESP_SLEEP_WAKEUP_TIMER:
    Serial.println("Wakeup caused by a timer");
    break;
  case ESP_SLEEP_WAKEUP_TOUCHPAD:
    Serial.println("Wakeup caused by a touchpad");
    break;
  case ESP_SLEEP_WAKEUP_ULP:
    Serial.println("Wakeup caused by a ULP program");
    break;
  default:
    Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
    break;
  }
}

// Event handler for button actions
void handleEvent(AceButton * /*button*/, uint8_t eventType, uint8_t buttonState)
{
  // Print out a message for all button events
  Serial.print(F("handleEvent(): eventType: "));
  Serial.print(AceButton::eventName(eventType));
  Serial.print(F("; buttonState: "));
  Serial.println(buttonState);

  switch (eventType)
  {
  case AceButton::kEventClicked:
    Serial.println("Button Clicked!");
    break;
  case AceButton::kEventDoubleClicked:
    Serial.println("Button Double Clicked!");
    break;
  case AceButton::kEventRepeatPressed:
    Serial.println("Button Held Down!");
    Serial.println("Going to sleep now");
    isSystemON = false;
    delay(2000);
    // Enter deep sleep mode to save power
    esp_deep_sleep_start();
    break;
  }
}

// Task to blink the built-in LED
void xTaskBlink(void *pvParameters)
{
  while (true)
  {
    // Toggle the built-in LED state
    digitalWrite(LED_BUILTIN, HIGH);
    vTaskDelay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    vTaskDelay(1000);
  }
}

Code Credit:

Objective: The goal of this post is to share knowledge, gather feedback, and discuss best practices in power management and sleep modes with the ESP32. If you're a fellow student or a beginner like me, please feel free to ask questions and explore this code together.

Thank you for taking the time to read this post, and I'm looking forward to discussing this topic with you.

Best regards

I appreciate your hard work and spirit. However, it would be more inclined to education and learning if you would implement the deep sleep mode of ESP32 using Arduino IDE Platform first and then to present the same using FreeRTOS functions.

Hmm, I see. Could you elaborate further?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.