149 lines
3.9 KiB
C++
149 lines
3.9 KiB
C++
// Waveshare 1.54” ePaper display (GDEH0154D67)
|
|
// https://www.waveshare.com/wiki/1.54inch_e-Paper_Module_(B)
|
|
|
|
|
|
#include <GxEPD2_BW.h>
|
|
#include <GxEPD2_3C.h>
|
|
#include <SPI.h>
|
|
#include <Fonts/FreeMonoBold9pt7b.h>
|
|
#include <Fonts/FreeMonoBold12pt7b.h>
|
|
#include <Wire.h>
|
|
|
|
// === 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<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(
|
|
// EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
|
|
// 3-color 1.54" e-paper class (200x200 resolution)
|
|
// GxEPD2_3C<GxEPD2_154c, GxEPD2_154c::HEIGHT> display(GxEPD2_154c(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
|
|
GxEPD2_3C<GxEPD2_154c, GxEPD2_154c::HEIGHT> 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();
|
|
}
|
|
}
|