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