// Waveshare 1.54” ePaper display (GDEH0154D67) // https://www.waveshare.com/wiki/1.54inch_e-Paper_Module_(B) #include #include #include #include #include #include // === Pin Definitions === #define EPD_CS 17 // Chip Select #define EPD_DC 16 // Data/Command #define EPD_RST 23 // Reset #define EPD_BUSY 22 // Busy // SPI pins (custom mapping if needed) #define EPD_MOSI 18 // SPI MOSI (DIN) #define EPD_SCK 19 // SPI Clock (CLK) // Optional: define MISO if your board or library needs it (not used by display) #define EPD_MISO -1 // ePaper doesn't use MISO // === GxEPD2 Display object (1.54" 200x200) === // GxEPD2_BW display(GxEPD2_154_D67( // EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // 3-color 1.54" e-paper class (200x200 resolution) // GxEPD2_3C display(GxEPD2_154c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); GxEPD2_3C display( GxEPD2_154c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // Optional: replace with RTC if available (e.g. DS3231 via RTClib) unsigned long lastUpdate = 0; unsigned long refreshInterval = 30000; // 30 seconds int counter = 0; // Timekeeping unsigned long bootMillis; int hours = 12, minutes = 0, seconds = 0; // Helper: format two digits String formatDigits(int digits) { if (digits < 10) return "0" + String(digits); return String(digits); } // ====== 🔧 Wait for BUSY Pin Helper ====== void waitWhileBusy(const char* label) { Serial.print("🕒 Waiting for BUSY ("); Serial.print(label); Serial.println(")..."); uint32_t start = millis(); while (digitalRead(EPD_BUSY)) { if (millis() - start > 10000) { Serial.println("⛔ BUSY Timeout!"); break; } delay(10); } Serial.println("✅ BUSY cleared."); } // Setup the screen with initial static content void drawInitialScreen() { Serial.println("🖥️ Drawing initial screen..."); display.setFullWindow(); Serial.println("debug 0"); display.firstPage(); do { Serial.println("debug 1"); display.fillScreen(GxEPD_WHITE); Serial.println("debug 2"); display.setFont(&FreeMonoBold12pt7b); Serial.println("debug 3"); display.setTextColor(GxEPD_BLACK); Serial.println("debug 4"); display.setCursor(30, 60); display.print("Counter:"); } while (display.nextPage()); Serial.println("✅ Initial screen drawn."); } // Draw the counter value with partial refresh void drawCounter() { Serial.print("🔢 Updating counter to: "); Serial.println(counter); char buffer[16]; snprintf(buffer, sizeof(buffer), "%d", counter); // Define the area to refresh display.setPartialWindow(30, 80, 140, 40); display.firstPage(); do { display.fillRect(30, 80, 140, 40, GxEPD_WHITE); // Clear previous text display.setCursor(30, 110); display.setTextColor(GxEPD_RED); // Use red for the counter display.print(buffer); } while (display.nextPage()); Serial.println("✅ Counter updated."); } void setup() { Serial.begin(115200); delay(100); delay(2000); Serial.println("🚀 Starting ePaper test..."); pinMode(EPD_BUSY, INPUT); pinMode(EPD_RST, OUTPUT); pinMode(EPD_DC, OUTPUT); pinMode(EPD_CS, OUTPUT); // Initialize SPI with custom pins BEFORE display.init() SPI.begin(EPD_SCK, EPD_MISO, EPD_MOSI, EPD_CS); // SCK, MISO, MOSI, SS Serial.println("🔌 Initializing display..."); display.init(115200); // optional: set SPI frequency display.setRotation(1); display.setFont(&FreeMonoBold12pt7b); // display.setTextColor(GxEPD_BLACK); Serial.println("🖼️ Display initialized"); waitWhileBusy("post-init"); drawInitialScreen(); // drawTime(); // first time display drawCounter(); lastUpdate = millis(); } void loop() { if (millis() - lastUpdate >= refreshInterval) { counter++; drawCounter(); lastUpdate = millis(); } }