Ken
Published © GPL3+

Build Your Offline Pomodoro Timer Using an E-Ink Display

Easily create your own offline Pomodoro timer using an E-ink screen and XIAO's DIY kit.

IntermediateFull instructions provided1 hour2,727
Build Your Offline Pomodoro Timer Using an E-Ink Display

Things used in this project

Hardware components

XIAO ePaper Display Board(ESP32-S3) - EE04
×1
7.5'' inch E-paper
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Build Your Offline Pomodoro Timer Using an E-Ink Display

C/C++
Easily create your own offline Pomodoro timer using an E-ink screen and XIAO's DIY kit.
#include <TFT_eSPI.h>
// Initialize the E-Paper object
EPaper epaper; 

// Define color layout (Supported by 7.3" multi-color e-paper) [2]
#define COLOR_WORK    TFT_RED     // Red for work-related tasks
#define COLOR_LEISURE TFT_BLUE    // Blue for leisure/meditation
#define COLOR_TEXT    TFT_BLACK
#define COLOR_BG      TFT_WHITE

// --- Logic Variables ---
int remainingMinutes = 25;           // Initial countdown minutes
unsigned long lastUpdateMs = 0;      // Stores the timestamp of the last refresh
const unsigned long ONE_MINUTE = 60000; // 60,000 milliseconds = 1 minute
char timeBuf[4]; // Buffer for the time string (e.g., "25:00")

void setup() {
    // Initialize Serial for debugging
    Serial.begin(115200);
    
    // 1. Initialize the display [3]
    epaper.begin();
    
    // 2. Perform initial UI rendering
    renderUI();
    lastUpdateMs = millis();
    
    // NOTE: For large screens like 7.3", ensure PSRAM is enabled in Arduino IDE 
    // to avoid memory allocation errors! [2]
}

void loop() {
    // Check if one minute has passed
    if (millis() - lastUpdateMs >= ONE_MINUTE) {
        if (remainingMinutes > 0) {
            remainingMinutes--; // Decrement the countdown
            renderUI();         // Trigger a physical screen refresh [3]
        }
        lastUpdateMs = millis(); // Reset the timer
    }
}

/**
 * Core rendering function that draws the layout and countdown.
 * It uses the Unified API for consistent drawing. [1]
 */
void renderUI() {
    // 1. Clear the canvas (Prepare buffer)
    epaper.fillScreen(COLOR_BG); 
    
    // --- Left Side: Weekly Plan (Static Layout) ---
    // Draw a vertical divider at the center (assuming 800px width)
    epaper.drawLine(400, 0, 400, 480, TFT_BLACK); 
    
    epaper.setTextColor(TFT_BLACK);
    epaper.drawString("WEEKLY PLAN", 20, 20, 4); 
    
    epaper.setTextColor(TFT_BLACK);
    epaper.drawString("09:00 - Deep Work (Coding)", 20, 80, 2);
    
    epaper.setTextColor(TFT_BLACK);
    epaper.drawString("12:00 - Garden Meditation", 20, 120, 2);
    
    epaper.setTextColor(TFT_BLACK);
    epaper.drawString("14:00 - Project Review", 20, 160, 2);

    // --- Right Side: Pomodoro Countdown ---
    epaper.setTextColor(TFT_BLACK);
    epaper.drawString("POMODORO", 460, 20, 4);
    
    // Generate the "XX:00" format string
    sprintf(timeBuf, "%02d:00", remainingMinutes);
    
    // Set text size and use font index 7 for large digits [3]
    epaper.setTextSize(2); 
    epaper.drawString(timeBuf, 470, 200, 7); 
    
    epaper.setTextSize(1);
    epaper.drawString("Stay Focused, No API needed.", 480, 400, 2);

    // 3. Execute physical refresh
    // E-Paper displays require an explicit update() to change pixels [3]
    epaper.update(); 
}

Credits

Ken
1 project • 0 followers

Comments