婚后時間計時 —— 電子紙時鐘
婚后時間計時 —— 電子紙時鐘

項目故事
項目介紹
婚后時間計時 —— 電子紙時鐘,是我為朋友婚禮制作的一款定制時鐘。
與傳統顯示當前時間的時鐘不同,這個時鐘顯示的是自婚禮以來已經過去的時間,以小時和天數為單位進行顯示。
本項目的目標是制作一件有意義、極簡、并且可以長期使用的作品。
通過使用電子紙顯示屏,時鐘可以始終保持可讀狀態,同時功耗極低,非常適合放在書桌或置物架上長期展示。
該時鐘通過 Wi-Fi 連接互聯網,從網絡同步時間,并且每小時自動更新一次顯示內容。
時鐘的工作原理
設備首次上電時,會創建一個自己的 Wi-Fi 熱點。
用戶可以使用手機或電腦連接該熱點,并在瀏覽器中打開配置頁面。
SSID:WeddingClock_Setup
密碼:12345678
在配置頁面中,用戶選擇自己的家庭 Wi-Fi 網絡并輸入密碼。
連接成功后,設備會通過 NTP 服務器 同步當前時間。
婚禮的日期和時間被直接寫入固件中。
在完成時間同步后,時鐘會計算自婚禮以來已經過去的小時數和天數,并將結果顯示在電子紙屏幕上。
如果設備無法連接到已保存的 Wi-Fi 網絡,它會自動重新進入配置模式,方便用戶重新進行網絡設置。
使用的硬件

本項目使用的主要硬件包括:
Seeed Studio XIAO ESP32-C3
2.9 英寸黑白電子紙顯示屏
我為 XIAO ESP32C3 設計的自制轉接 PCB
選擇 XIAO ESP32-C3 的原因在于它體積小、內置 Wi-Fi、功耗低,非常適合用于常顯型顯示項目。
外殼設計與 3D 打印

我使用 Fusion 360 為該項目設計了外殼,然后導出了 STL 文件用于 3D 打印。
婚后時間計時 —— 電子紙時鐘的外殼,使用 JLC3DP 的 3D 打印服務制作完成。
整體設計簡潔、極簡,與電子紙屏幕干凈清爽的視覺風格保持一致。
JLC3DP 提供多種材料和表面處理選項,使得成品外殼具有良好的質感,并呈現出專業級的完成度。
組裝步驟

將 XIAO 焊接到 PCB 轉接板上
按照提供的接線圖,將 XIAO 與電子紙模塊連接。
該接線圖中也展示了電池連接方式。如果你希望使用電池供電,可以按照該接線方式添加電池。
如果僅使用 USB 供電,也可以直接采用 USB 方式。使用 M2 × 5 mm 螺絲,將電子紙模塊固定到顯示框架中
使用 M3 螺絲固定 XIAO PCB
安裝天線
適量涂膠并封閉外殼
連接到電腦,用于燒錄程序和供電

代碼
以下是本項目的完整代碼:
#include <WiFi.h>
#include <WebServer.h>
#include <Preferences.h>
#include <time.h>
#include <GxEPD2_BW.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
// ================= E-PAPER PINS =================
#define CS_PIN D1
#define DC_PIN D3
#define RST_PIN D0
#define BUSY_PIN D5
GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(
GxEPD2_290_BS(CS_PIN, DC_PIN, RST_PIN, BUSY_PIN)
);
// ================= WIFI =================
WebServer server(80);
Preferences prefs;
const char* apSSID = "WeddingClock_Setup";
const char* apPASS = "12345678";
unsigned long lastHourShown = 0;
uint8_t refreshCount = 0; // for ghosting control
// ================= HEART BITMAP =================
// 15x16 monochrome heart
const unsigned char image_cards_hearts_bits[] PROGMEM = {
0x1C, 0x38,
0x3E, 0x7C,
0x7F, 0xFE,
0xFF, 0xFF,
0xFF, 0xFF,
0x7F, 0xFE,
0x3F, 0xFC,
0x1F, 0xF8,
0x0F, 0xF0,
0x07, 0xE0,
0x03, 0xC0,
0x01, 0x80,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00
};
// ================= WEDDING TIME =================
// Oct 19, 2025 – 6:15 AM IST → 00:45 UTC
time_t getWeddingEpochUTC() {
struct tm t = {};
t.tm_year = 2025 - 1900;
t.tm_mon = 9;
t.tm_mday = 19;
t.tm_hour = 0;
t.tm_min = 45;
t.tm_sec = 0;
t.tm_isdst = 0;
return mktime(&t);
}
// ================= DISPLAY UI =================
void drawWeddingUI(unsigned long hoursPassed, unsigned long daysPassed) {
char hrsBuf[20];
char daysBuf[20];
sprintf(hrsBuf, "%09lu Hrs", hoursPassed);
sprintf(daysBuf, "%09lu Dys", daysPassed);
bool fullRefresh = (refreshCount >= 6);
if (fullRefresh) {
display.setFullWindow(); // anti-ghosting
refreshCount = 0;
} else {
display.setPartialWindow(0, 0, display.width(), display.height());
refreshCount++;
}
display.firstPage();
do {
display.fillScreen(GxEPD_WHITE);
display.setTextColor(GxEPD_BLACK);
display.setTextWrap(false);
// Hours
display.setFont(&FreeMonoBold18pt7b);
display.setCursor(10, 73);
display.print(hrsBuf);
// Days
display.setCursor(10, 112);
display.print(daysBuf);
// Names
display.setFont(&FreeMonoBold12pt7b);
display.setCursor(56, 31);
display.print("Arjun");
display.setCursor(152, 31);
display.print("Amgitha");
// Heart
display.drawBitmap(
131, 17,
image_cards_hearts_bits,
15, 16,
GxEPD_BLACK
);
} while (display.nextPage());
}
// ================= TIME COUNTERS =================
void showTimeCounters() {
time_t now;
time(&now);
time_t weddingEpoch = getWeddingEpochUTC();
if (now < weddingEpoch) {
drawWeddingUI(0, 0);
return;
}
unsigned long seconds = now - weddingEpoch;
drawWeddingUI(seconds / 3600, seconds / 86400);
}
// ================= WIFI CONFIG PAGE =================
void handleRoot() {
String page =
"<!DOCTYPE html><html><head>"
"<meta name='viewport' content='width=device-width, initial-scale=1'>"
"<style>"
"body{font-family:Arial;background:#f2f2f2;padding:20px;}"
".card{background:#fff;padding:20px;border-radius:14px;"
"max-width:400px;margin:auto;box-shadow:0 10px 25px rgba(0,0,0,.15);}"
"h2{text-align:center;}"
"select,input,button{width:100%;padding:12px;margin-top:10px;"
"border-radius:8px;border:1px solid #ccc;}"
"button{background:#000;color:#fff;font-weight:bold;}"
"</style></head><body>"
"<div class='card'><h2>Wedding Clock Wi-Fi</h2>"
"<f至此,硬件與軟件的制作已經完成。
3D 打印外殼將這些電子元件轉化為一件精致的桌面擺件,使其非常適合作為一份結婚禮物。











評論