Skip to content

Instantly share code, notes, and snippets.

@palaniraja
Created June 2, 2026 05:04
Show Gist options
  • Select an option

  • Save palaniraja/0d7576d82662dba386bf6874714662b2 to your computer and use it in GitHub Desktop.

Select an option

Save palaniraja/0d7576d82662dba386bf6874714662b2 to your computer and use it in GitHub Desktop.
ESP32 C6 deep sleep with epaper display GDEW0583Z21 600x448, UC8159c. Relevant main.cpp (esp_sleep_pd_config) ESP_PD_OPTION_ON
#include <Arduino.h>
#include <SPI.h>
#include <GxEPD2_3C.h>
// Low-level hardware power management registers for ESP-IDF v5.x targets
#include "esp_sleep.h"
#include "soc/rtc.h"
// Hardware connection pins based on your working configuration
#define EPD_SCK_PIN 18
#define EPD_MOSI_PIN 20
#define EPD_RST_PIN 16
#define EPD_CS_PIN 17
#define EPD_DC_PIN 1
#define EPD_BUSY_PIN 3
// Instantiate the 3-color 5.83" panel (600x448, UC8159c) using full buffer allocation
// GDEW0583Z21 600x448, UC8159c.
static GxEPD2_3C<GxEPD2_583c, GxEPD2_583c::HEIGHT>
g_display(GxEPD2_583c(EPD_CS_PIN, EPD_DC_PIN, EPD_RST_PIN, EPD_BUSY_PIN));
// This variable resides inside Low-Power RAM and survives deep sleep routines
RTC_DATA_ATTR uint32_t bootCount = 0;
void setup()
{
// 1. Initialize serial monitoring line
Serial.begin(115200);
delay(1000); // Small pause to allow hardware lines to stabilize
bootCount++;
Serial.printf("\n--- ESP32-C6 Deep Sleep Verification Cycle: #%u ---\n", bootCount);
// 2. Hardware pin configurations for the e-ink display lines
pinMode(EPD_RST_PIN, OUTPUT);
pinMode(EPD_DC_PIN, OUTPUT);
pinMode(EPD_CS_PIN, OUTPUT);
pinMode(EPD_BUSY_PIN, INPUT_PULLUP);
// Initialize default SPI bus targeting assigned pins
// SPI.begin(EPD_SCK_PIN, -1, EPD_MOSI_PIN, EPD_CS_PIN);
SPI.begin(EPD_SCK_PIN, -1, EPD_MOSI_PIN, -1); // leave EPD_CS_PIN for GxEPD2
g_display.epd2.selectSPI(SPI, SPISettings(10000000, MSBFIRST, SPI_MODE0));
// Initialize the high-level GxEPD2 display controller
g_display.init(115200, true, 2, false);
// 3. The Software Step: Render text layers instantly into the internal RAM buffer
Serial.println("Drawing cycle information directly into internal RAM buffer...");
g_display.setRotation(1);
g_display.setFullWindow();
// Clear the RAM canvas (does not touch the physical display)
g_display.fillScreen(GxEPD_WHITE);
// Arrange text parameters inside the buffer frame (takes mere microseconds)
g_display.setTextColor(GxEPD_BLACK);
g_display.setTextSize(3);
g_display.setCursor(50, 100);
g_display.print("ESP32-C6 Power Verification");
g_display.setTextSize(2);
g_display.setCursor(50, 180);
g_display.printf("Current Boot Count: %u", bootCount);
g_display.setCursor(50, 230);
g_display.print("Status: Single Refresh Mode Active");
g_display.setCursor(50, 280);
g_display.print("Next sleep step duration: 5 Minutes (300s)");
// 4. The Hardware Step: Fire exactly ONE physical hardware refresh sweep
Serial.println("Pushing buffer layout to panel via SPI. Initiating SINGLE screen update...");
g_display.display(false); // false = full update sweep, exactly one pass executed
// 5. Put the display panel hardware into deep hibernation mode instantly
Serial.println("Putting the display panel hardware into hibernation mode...");
g_display.powerOff();
// 6. Explicitly structure sleep registers using updated v5.x Low-Power APIs
Serial.println("Prepping sleep clocks. Entering Deep Sleep mode now...");
Serial.flush();
// Keep the Low-Power memory blocks cleanly energized to track the bootCount variable
#if defined(ESP_PD_DOMAIN_RTC_SLOW)
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW, ESP_PD_OPTION_ON);
#elif defined(ESP_PD_DOMAIN_LP_RAM)
esp_sleep_pd_config(ESP_PD_DOMAIN_LP_RAM, ESP_PD_OPTION_ON);
#else
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
#endif
// Set absolute sleep window timer: 5 minutes = 300 seconds
uint64_t deepSleepSeconds = 300ULL;
esp_sleep_enable_timer_wakeup(deepSleepSeconds * 1000000ULL);
// Say goodnight
esp_deep_sleep_start();
}
void loop()
{
// Deep sleep cuts off CPU execution completely. Execution never drops down here.
}
[env:c6]
platform = https://github.com/pioarduino/platform-espressif32.git#fbdfc2962e468ca3c4b51811ae691ed887df903c
board = esp32-c6-devkitc-1
framework = arduino
monitor_speed = 115200
monitor_filters =
time
send_on_enter
upload_speed = 921600
lib_deps =
zinggjm/GxEPD2 @ ^1.5.9
build_flags =
-D ARDUINO_USB_MODE=1
-D ARDUINO_USB_CDC_ON_BOOT=1
-D CONFIG_RTC_CLK_SRC_INT_RC=1
-D CONFIG_ESP_SLEEP_RTC_SLOW_CLK_BIAS_WY=1
@palaniraja

Copy link
Copy Markdown
Author
21:53:06.700 > 
21:53:06.701 > --- ESP32-C6 Deep Sleep Verification Cycle: #1 ---
21:53:06.722 > Drawing cycle information directly into internal RAM buffer...
21:53:06.733 > Pushing buffer layout to panel via SPI. Initiating SINGLE screen update...
21:53:06.806 > _PowerOn : 73001
21:53:47.515 > Busy Timeout!
21:53:47.515 > _Update_Full : 40000019
21:53:59.747 > _PowerOff : 12231001
21:53:59.747 > Putting the display panel hardware into hibernation mode...
21:53:59.747 > Prepping sleep clocks. Entering Deep Sleep mode now...
Disconnected (read failed: [Errno 6] Device not configured)
Reconnecting to /dev/cu.usbmodem14101 .................................  Connected!
21:58:57.858 > 
21:58:57.858 > --- ESP32-C6 Deep Sleep Verification Cycle: #2 ---
21:58:57.880 > Drawing cycle information directly into internal RAM buffer...
21:58:57.891 > Pushing buffer layout to panel via SPI. Initiating SINGLE screen update...
21:58:57.964 > _PowerOn : 72001
21:59:38.672 > Busy Timeout!
21:59:38.672 > _Update_Full : 40000019
21:59:50.909 > _PowerOff : 12235001
21:59:50.909 > Putting the display panel hardware into hibernation mode...
21:59:50.909 > Prepping sleep clocks. Entering Deep Sleep mode now...
Disconnected (read failed: [Errno 6] Device not configured)
Reconnecting to /dev/cu.usbmodem14101 ..................................

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment