專案開發歷程大綱 - pondahai/epaper_ime GitHub Wiki

專案開發歷程大綱:從概念到實現的中文輸入裝置

第一部分:專案啟動與核心概念定義

  1. 初始構想:基於微控制器 (RP2040) 的獨立中文輸入顯示裝置

    • 輸入:按鍵矩陣 (注音/倉頡)
    • 輸出:SPI TFT 螢幕
    • 挑戰:如何在資源受限的 Pico 上處理龐大的中文字型 (.ttc) 和輸入法碼表。
  2. 核心技術決策:離線預處理 + 線上按需加載

    • 否定方案:在 Pico 上直接解析 .ttf/.ttc 檔(因 RAM/CPU 限制而不可行)。
    • 確定方案
      • 在 PC 端將字型預先渲染成輕量級的點陣格式。
      • 在 PC 端將輸入法碼表轉換為高效的二進位索引格式。
      • Pico 在執行時只從外部儲存(SD卡)中讀取需要的一小部分資料。

第二部分:PC 端 Python 模擬器開發與驗證

  1. 策略轉變:先用 Python 模擬,再移植硬體

    • 目的:在一個易於除錯的環境中快速驗證核心演算法和資料格式。
    • 工具選擇:Pygame (模擬螢幕), Pillow (圖像與字型處理)。
  2. 字型系統的實現

    • 開發 font_converter.py 工具。
    • 討論字元集的來源:
      • 方案一:通用常用字列表。
      • 方案二 (最終採用):從輸入法碼表中精確提取,確保無遺漏、無浪費。
    • 開發 charset_extractor.py 以自動從 BPMFBase.txtBPMFPunctuations.txt 提取字元。
    • 開發 FontRenderer 類別,在 Pygame 中實現按需讀取並顯示中文字元。
    • 除錯:解決 Pygame 版本更新導致的 fromstring / frombuffer 函式問題。
  3. 輸入法系統的實現

    • 討論輸入法碼表來源,最終選定 McBopomofo 的 BPMFBase.txt
    • 開發 ime_converter.py 工具,將「字→音」的碼表反轉為「音→字」的索引格式 (.idx) 和資料格式 (.dat)。
    • 除錯:解決因分隔符(空格 vs Tab)導致的解析失敗問題。
    • 開發 ImeEngine 類別,實現根據注音碼查詢候選字的功能。
  4. 模擬器 UI 與互動

    • 整合 FontRendererImeEnginemain.py
    • 實現輸入區、候選字區、編輯區的 UI 佈局。
    • 實現鍵盤輸入、選字、刪除等基本邏輯。
    • 功能迭代:增加候選字翻頁功能。
    • 體驗優化:討論並恢復「輸入單個注音符號時也顯示候選字」的功能。

第三部分:從模擬器到真實硬體 (Raspberry Pi Zero + 電子紙)

  1. 硬體轉向與可行性分析

    • 新硬體:Waveshare 2.13 吋觸控電子紙。
    • 核心挑戰:電子紙的極慢刷新速度
    • 對策:必須放棄即時反饋,重新設計「批次處理,整頁刷新」的互動模型。
  2. 硬體驅動與基礎框架搭建

    • 分析 Waveshare 官方範例程式碼 (TP2in13_V4_test.py)。
    • 識別其優點(功能可用)與缺點(結構混亂、全域變數、硬編碼)。
    • 策略:取其精華(初始化、驅動呼叫),去其糟粕(巨大的 while 迴圈和狀態管理)。
    • 創建面向物件的 App 類別,作為新的、乾淨的應用程式框架。
  3. 核心問題除錯:觸控失靈

    • 初步診斷:懷疑 I2C 未啟用或驅動不匹配。
    • 關鍵線索:使用者反饋 i2cdetect 結果和「官方範例可用」。
    • 問題定位:發現官方範例依賴一個獨立的執行緒來監測 INT 腳位,而我們的程式遺漏了這一點。
    • 解決方案:將執行緒邏輯整合進 App 類別。
  4. 核心問題除錯:觸控彈跳與連續觸發

    • 現象:按一下觸發多次事件,或按住不動時反覆觸發「按下」和「抬起」。
    • 認知迭代
      1. 初步嘗試:基於時間戳的防抖。
      2. 再次失敗後深入分析 gt1151.py 原始碼,意識到必須呼叫 GT_Scan 來清除硬體狀態。
      3. 再次失敗後,根據「按住仍觸發抬起」的現象,最終推斷出 INT 腳位是脈衝式而非狀態式訊號。
    • 終極解決方案:拋棄對 INT 訊號的依賴,直接在主迴圈中輪詢 GT_Scan,並以其返回的 TouchCount 作為判斷手指是否在螢幕上的黃金標準,結合軟體狀態鎖實現精確的「邊緣觸發 (edge trigger)」。

第四部分:電子紙 UI/UX 的精細化調校

  1. 虛擬鍵盤佈局優化

    • 問題:初始佈局過於擁擠,按鍵跑出螢幕範圍。
    • 討論:分析了「動態鍵盤」、「分區佈局」、「九宮格」三種方案。
    • 決策:採用「分區佈局」,將鍵盤分為聲母、韻母、聲調三頁,並採用兩行佈局,確保按鍵尺寸合理。
  2. 刷新策略優化

    • 問題:單純的局部刷新導致嚴重殘影,而全局刷新又會閃爍。
    • 解決方案:實現智慧混合刷新機制。
      • 小更新用局部刷新。
      • 大更新(切換鍵盤、選字成功等)或在 N 次局部刷新後,用一次全局刷新來「清理」螢幕。
    • 實驗性迭代:根據使用者需求,實現了「多次局部塗白」來模擬局部清空,並最終將整個應用的刷新模型統一為此方案,徹底告別閃爍。
  3. 顯示與點擊邏輯同步

    • 問題:候選字間距改為「固定槽位」後,點擊位置判斷失效。
    • 解決方案:重構 process_touch 中的點擊判斷邏輯,使其與 draw_ui 中的繪圖佈局邏輯嚴格同步,都基於 CANDIDATE_SLOT_WIDTH 這個「黃金標準」進行計算。

第五部分:專案收尾

  1. 最終程式碼定稿:提供包含所有功能和優化的完整版 epaper_ime_app.py
  2. 文件撰寫 (README.md):
    • 撰寫面向部署的 README。
    • 根據使用者要求,補充「鳴謝與資料來源」章節。
    • 討論並實現對索引檔 (.map, .idx) 進行「壓縮」(去掉空白)的優化。