2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-05 16:16:34 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00
2026-05-27 08:38:40 +08:00

Difference Equation Analyzer

Difference Equation Analyzer 是用來設計、檢視與驗證離散時間濾波器的工具。它同時支援浮點係數、fixed-point 係數、時域 CSV 驗證,以及透過 Web Serial 將係數寫入 MCU。

Backend 使用 FastAPI、NumPy、SciPy 與 PandasFrontend 使用 Vue 3、Vite、Tailwind CSS 與 Plotly。

Features

  • 設計 Lowpass、Highpass、Bandpass、Notch、1P1Z、2P1Z、2P2Z、PID、SOGI 濾波器。
  • 比較 Ideal Float 與 Fixed-Point 的 Bode 頻率響應。
  • 支援多個 cascade stages 的頻率響應與時域模擬,並可個別啟用或 bypass。
  • 手動微調 b/a 係數、a1/a2、δ/r、Q-format 位元數與 fixed-point 整數係數。
  • 上傳 CSV 時域資料,繪製輸入、Ideal Float 輸出與 Mimic Integer 輸出。
  • 匯出包含理想浮點與定點整數模擬輸出的 CSV;cascade workflow 可匯出乾淨的 4 欄 CSV。
  • 使用瀏覽器 Web Serial API 將 fixed-point 係數寫入 MCU。
  • 時域圖表支援 zoom 後以 start_idx / end_idx 向後端重取可視區間資料,保留 IIR 完整歷史狀態。
  • 支援 Dark Mode 與響應式 UI。

Quick Start

cd /home/wisetop/diff-eq-analyzer
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
npm install
npm run build
bash certs/generate_cert.sh
.venv/bin/uvicorn dea_api:app --host 0.0.0.0 --port 8000 --ssl-keyfile certs/key.pem --ssl-certfile certs/cert.pem

開啟:

https://192.168.2.58:8000/ui/

本專案固定從 FastAPI 提供的 HTTPS UI 使用。不要用 Vite dev server URL 測試 CSV 或 MCU 功能,否則 /api/... 可能會回 Not Found

自簽憑證會讓瀏覽器顯示安全性警告,第一次開啟時需手動信任或選擇繼續前往。

Project Layout

dea_api.py              FastAPI 入口與 HTTP route
dea/                    後端核心模組
  bode.py               頻率響應計算
  config.py             限制值與伺服器端 serial 設定
  csv_processing.py     CSV 快取、驗證、單濾波器/cascade 濾波與匯出
  filter_design.py      濾波器設計
  mcu.py                MCU serial port 列表與命令寫入
  schemas.py            Pydantic request schema
  security.py           LAN 存取限制與安全標頭
  validation.py         係數、頻率與有限值驗證
src/                    Vue 3 前端原始碼
certs/                  HTTPS 自簽憑證與產生腳本
static/build/           Vite production build 輸出
tests/                  unittest 測試
dea.service             systemd service 範例
chirp_signal.csv        CSV 上傳測試範例

Architecture

Layer Responsibility
FastAPI 提供 API、serve /ui/、套用 LAN 存取限制與安全標頭
dea/ 濾波器設計、單濾波器/cascade Bode plot、CSV 處理、fixed-point simulation、驗證
Vue UI 管理係數、Q-format、CSV workflow、Plotly 圖表與 Web Serial 狀態
Vite build src/ 打包到 static/build/,由 FastAPI 在 production 提供

CSV workflow

  1. 前端選擇 CSV。
  2. 前端只讀取檔案前段內容建立欄位與 preview,避免為了 preview 把大型 CSV 全部載入瀏覽器記憶體。
  3. 前端呼叫 POST /api/csv/upload,後端將檔案暫存並回傳 file_id
  4. 上傳完成前,filter 按鈕會保持 disabled,避免尚未取得 file_id 就送出處理。
  5. 後續 POST /api/filterPOST /api/filter/download 使用 file_id,避免反覆傳大檔。

CSV 預設暫存在:

/tmp/diff-eq-analyzer-csv/

可用環境變數覆寫:

DEA_TEMP_CSV_DIR=/path/to/csv-cache

暫存 CSV 預設保留 24 小時。可用環境變數調整,設為 0 可停用清理:

DEA_TEMP_CSV_TTL_SECONDS=86400

Usage

Filter Design

在左側控制面板選擇濾波器類型並調整參數。系統會更新 b/a 係數,並繪製 Ideal Float 與 Fixed-Point 的頻率響應。

支援濾波器:

Lowpass, Highpass, Bandpass, Notch,
1P1Z, 2P1Z, 2P2Z,
PID, SOGI-Alpha, SOGI-Beta

a1/a2 Fine Tuning

針對二階濾波器,UI 支援 δ/r 參數化微調。

Mode Formula
Float a1 = -1 - r, a2 = r + δ
Fixed a1 = -a0 - r, a2 = r + δ

反推關係:

Mode δ r
Float a1 + a2 + 1 -1 - a1
Fixed a1 + a2 + a0 -a0 - a1

桌機可用 Shift + 滑鼠滾輪微調;觸控裝置可按住數值面板上下拖曳。

Cascade Stages

UI 以 cascade stage accordion 管理多段濾波器。每個 stage 顯示序號、濾波器型態、Active/Bypass 狀態、係數摘要與 Q-format 摘要;可用上移/下移調整串接順序。

完整的濾波器設計、浮點係數、fixed-point 係數與 MCU 寫值控制只會出現在目前選取的 active stage accordion 內。同時間只有一個 active stage 承載完整 editor,避免多份表單同時修改同一組全域 active-stage state。展開非 active stage 時,UI 會先切換該 stage 為 active stage。

送出 Bode 或 CSV 時,前端會先同步目前 active stage,再把所有 stages 依畫面順序打包送到後端。單一 stage 時仍等同 legacy 單濾波器 workflow。

後端相容兩種路徑:

Mode API Behavior
Legacy single filter /api/bode/api/bode/compare/api/filter 仍接受原本的 b/a/b_int/a_int 參數
Cascade /api/bode/compare_cascade 接受 stages/api/filter/api/filter/download 可接受 stages form payload

Cascade 設計刻意不直接 merge origin/cascadedfilters 的整包檔案,而是在 main 上重作功能,避免帶入大型 CSV、暫存檔、log、舊文件與 build noise。

Fixed-Point Time Simulation

時域分析同時計算兩條路徑:

Path Description
Ideal Float 使用 SciPy signal.lfilter() 作為理想浮點參考
Mimic Integer 將輸入與係數量化為整數,模擬 MCU / DSP fixed-point 差分方程

Q-format 參數:

Parameter Meaning
shift_in 輸入訊號量化位元數
shift_out 輸出訊號量化位元數
shift_b 前饋 b 係數量化位元數
shift_a 回授 a 係數量化位元數
use_round 右移時使用 Floor (SRA) 或 Round (+0.5)

整數模擬採高精度狀態變數架構:前饋項保留在 Q_in+b 精度,回授項除以 A0 對齊,再於最終輸出依 Q_out 縮放。

Time-Domain LOD Zoom

時域圖表使用 Plotly zoom / pan 時,前端會把目前可視時間範圍換算成 sample index,透過 /api/filter 傳送 start_idxend_idx。後端仍先用完整訊號計算 IIR 輸出,保留濾波器歷史狀態正確性,再只切出可視區間並 downsample 回傳,避免 zoom in 後只能看到粗略的全域降採樣資料。

時間軸單位會在首次完整載入時鎖定為 smsμs,避免 zoom 後重新換單位造成 Plotly uirevision 座標錯位。前端也使用 isRedrawingTimePlot 避免 Plotly.react() 觸發 relayout callback 造成重繪迴圈。

CSV Workflow

限制與行為:

Item Value
檔案大小上限 300 MB
時域運算列數上限 1,200,000 rows
圖表點數上限 5000 points
格式要求 必須有標題列與至少一筆資料

若第一欄像 timetsecxindex,前端會預設選第二欄作為訊號欄位。

首頁會自動嘗試載入 .scratch/examples/preset_signals.csv 作為 preset waveform;若檔案不存在,UI 仍可正常手動上傳 CSV。preset 路徑可用環境變數覆寫:

DEA_PRESET_CSV_PATH=/path/to/preset_signals.csv

範例 CSV 不再放在 Git 追蹤路徑。大型範例請放在本機 ignored 目錄:

.scratch/examples/

常用範例欄位格式:

time,value

可從歷史 commit 匯出範例到本機 ignored 路徑使用:

mkdir -p .scratch/examples
git show 075f20d:chirp_signal.csv > .scratch/examples/chirp_signal.csv
git show 0140b049:chirp_signal_small_s.csv > .scratch/examples/chirp_signal_small_s.csv
git show 0140b049:step_signal.csv > .scratch/examples/step_signal.csv
git show 8caa8918:static/preset_signals.csv > .scratch/examples/preset_signals.csv

.scratch/ 已被 .gitignore 忽略,適合放大型 CSV、手動測試資料與暫存分析檔。

CSV Export

/api/filter/download 預設保留 legacy 行為:輸出原始 CSV 欄位,並新增 [欄位]_filtered_ideal[欄位]_filtered_fixed

若前端傳送 compact=true,後端會輸出專供分析用的 4 欄 CSV:

Column Meaning
Time (s) 由 sample index 與前端傳入的 fs 計算
原輸入欄位 選定訊號欄位原始值
[欄位]_filtered_ideal Ideal Float 輸出
[欄位]_filtered_fixed Mimic Integer / fixed-point 輸出

MCU Web Serial

Web Serial 是主要 MCU 寫入方式,伺服器不需要 serial 權限。

Action Description
連線 點擊「選擇連接埠並連線」,在瀏覽器彈窗選擇 MCU
寫值 點擊「寫值到 MCU」
限制 Chrome / Edge,且必須透過 HTTPS 或 localhost

寫入命令格式:

bodeplot=b0,b1,b2,a1,a2

API

Method Endpoint Purpose
POST /api/design 依濾波器參數產生 b/a 係數
POST /api/bode 計算單組 b/a 頻率響應
POST /api/bode/compare 比較單一濾波器 Ideal Float 與 Fixed-Point 頻率響應
POST /api/bode/compare_cascade 比較 cascade stages 的 Ideal Float 與 Fixed-Point 頻率響應
GET /api/csv/preset 讀取本機 ignored preset CSV metadata,供首頁自動載入
POST /api/csv/upload 上傳 CSV 並回傳 file_id
POST /api/filter 使用 file_id 回傳單濾波器或 cascade 時域圖表資料;可傳 start_idx/end_idx 做 LOD zoom
POST /api/filter/download 使用 file_id 匯出結果 CSV;可傳 compact=true 匯出 4 欄 CSV
GET /api/mcu/ports 列出伺服器端 serial ports
POST /api/mcu/write 後端模式寫入 MCU 命令

Development

Frontend

npm install
npm run test:frontend
npm run build

開發模式:

npm run dev

CSV 與 API 流程保留 dev-v2 的兩段式設計:先 upload 取得 file_id,再用 file_id filter 或 download。vite.config.js 仍保留 main 的 HTTPS deployment 設定,不在 Vite 內設定 /api proxy。因此 npm run dev 只適合檢查前端畫面;CSV upload、filter API、MCU API 請固定使用:

https://192.168.2.58:8000/ui/

Backend

.venv/bin/pip install -r requirements.txt
.venv/bin/uvicorn dea_api:app --host 0.0.0.0 --port 8000 --ssl-keyfile certs/key.pem --ssl-certfile certs/cert.pem

HTTPS Certificate

bash certs/generate_cert.sh

會在 certs/ 產生:

cert.pem
key.pem

systemd

sudo cp dea.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable dea.service
sudo systemctl start dea.service

查看狀態:

sudo systemctl status dea.service
sudo journalctl -u dea.service -f

Backend Serial Fallback

若無法使用 Web Serial,可改用後端 serial API。環境變數:

MCU_SERIAL_PORT=/dev/ttyUSB2
MCU_BAUD_RATE=115200
MCU_WRITE_TIMEOUT=1.0

systemd 可在 [Service] 加入:

Environment="MCU_SERIAL_PORT=/dev/ttyUSB2"
Environment="MCU_BAUD_RATE=115200"
Environment="MCU_WRITE_TIMEOUT=1.0"

Testing

Python syntax check

.venv/bin/python -m py_compile dea_api.py tests/test_dea_api.py

Backend tests 使用 Python 內建 unittest

.venv/bin/python -m unittest discover -s tests

Frontend build check

npm run build

建議完整驗證:

.venv/bin/pip install -r requirements.txt
.venv/bin/python -m unittest discover -s tests
npm run build
sudo systemctl restart dea.service

Security And Limits

Item Value
Network access 只允許 private / loopback IP
CSV size 300 MB
Time-domain rows 1,200,000 rows
Plot points 5000 points
Coefficients 最多 64 個

HTTP responses 會加上 CSP、Referrer-PolicyX-Content-Type-Options: nosniffX-Frame-Options: DENY

Troubleshooting

CSV 上傳顯示 Not Found

請確認目前網址是:

https://192.168.2.58:8000/ui/

如果從 http://localhost:5173 或其他 Vite dev server URL 開啟,/api/csv/upload 會送到前端 dev server,而不是 FastAPI,因此會回 Not Found

無法連線 MCU

  1. 確認使用 https://192.168.2.58:8000/ui/
  2. 確認瀏覽器支援 Web Serial API。
  3. 使用 Chrome 或 Edge。
  4. 檢查 USB 線與 MCU 裝置狀態。

頁面沒有更新

  1. 執行 npm run build
  2. 重啟服務:sudo systemctl restart dea.service
  3. 瀏覽器按 Ctrl+F5 強制重新整理。

systemd 顯示 status=203/EXEC

通常是 .venvuvicorn 路徑不正確。可重建 venv

rm -rf .venv
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
sudo systemctl restart dea.service

找不到 pytest

本專案不使用 pytest。請改用:

.venv/bin/python -m unittest discover -s tests
S
Description
No description provided
Readme 26 MiB
Languages
JavaScript 32%
Vue 25.8%
Python 20.7%
CSS 18%
HTML 3.3%
Other 0.2%