久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > 婚后時間計時 —— 電子紙時鐘

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

作者: 時間:2025-12-17 來源: 收藏

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

affffed0-0373-46ef-a18b-de991cc07114.png


項目故事

項目介紹

婚后時間計時 —— 電子紙時鐘,是我為朋友婚禮制作的一款定制時鐘。
與傳統顯示當前時間的時鐘不同,這個時鐘顯示的是自婚禮以來已經過去的時間,以小時天數為單位進行顯示。

本項目的目標是制作一件有意義、極簡、并且可以長期使用的作品
通過使用電子紙顯示屏,時鐘可以始終保持可讀狀態,同時功耗極低,非常適合放在書桌或置物架上長期展示。

該時鐘通過 Wi-Fi 連接互聯網,從網絡同步時間,并且每小時自動更新一次顯示內容


時鐘的工作原理

設備首次上電時,會創建一個自己的 Wi-Fi 熱點。
用戶可以使用手機或電腦連接該熱點,并在瀏覽器中打開配置頁面。

  • SSID:WeddingClock_Setup

  • 密碼:12345678

在配置頁面中,用戶選擇自己的家庭 Wi-Fi 網絡并輸入密碼。
連接成功后,設備會通過 NTP 服務器 同步當前時間。

婚禮的日期和時間被直接寫入固件中。
在完成時間同步后,時鐘會計算自婚禮以來已經過去的小時數和天數,并將結果顯示在電子紙屏幕上。

如果設備無法連接到已保存的 Wi-Fi 網絡,它會自動重新進入配置模式,方便用戶重新進行網絡設置。


使用的硬件

7dcf284f-8f2d-4989-983b-2407fc35dd12.png

本項目使用的主要硬件包括:

  • Seeed Studio XIAO ESP32-C3

  • 2.9 英寸黑白電子紙顯示屏

  • 我為 XIAO ESP32C3 設計的自制轉接 PCB

選擇 XIAO ESP32-C3 的原因在于它體積小、內置 Wi-Fi、功耗低,非常適合用于常顯型顯示項目


外殼設計與 3D 打印

3cdd7805-be13-4405-98cd-20b735518cbc.png

我使用 Fusion 360 為該項目設計了外殼,然后導出了 STL 文件用于 3D 打印。

婚后時間計時 —— 電子紙時鐘的外殼,使用 JLC3DP 的 3D 打印服務制作完成。

整體設計簡潔、極簡,與電子紙屏幕干凈清爽的視覺風格保持一致。
JLC3DP 提供多種材料和表面處理選項,使得成品外殼具有良好的質感,并呈現出專業級的完成度。


組裝步驟

8b8e33ec-72af-4bee-8a84-f9f5dffc2a2f.png

  1. 將 XIAO 焊接到 PCB 轉接板上

  2. 按照提供的接線圖,將 XIAO 與電子紙模塊連接。
    該接線圖中也展示了電池連接方式。如果你希望使用電池供電,可以按照該接線方式添加電池。
    如果僅使用 USB 供電,也可以直接采用 USB 方式。

  3. 使用 M2 × 5 mm 螺絲,將電子紙模塊固定到顯示框架中

  4. 使用 M3 螺絲固定 XIAO PCB

  5. 安裝天線

  6. 適量涂膠并封閉外殼

  7. 連接到電腦,用于燒錄程序和供電

e460ef2a-718c-4ad1-aec4-acffae334f2e.png


代碼

以下是本項目的完整代碼:

#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 打印外殼將這些電子元件轉化為一件精致的桌面擺件,使其非常適合作為一份結婚禮物。




關鍵詞:

評論


相關推薦

技術專區

關閉