今天結束時,你會做出這個
一台真的能量到你自己心跳的心電圖機,而且每一行程式你都看得懂。
四個階段:①接線 → ②貼電極 → ③燒錄韌體 → ④跑 Python 看波形
整套系統長這樣
AD8232 的六支腳
接地。第一條接、最後一條拔
供電。最高只能吃 3.5V,接 5V 會當場燒掉
放大後的心電訊號,沒訊號時停在中點 1.65V
電極脫落偵測(負極)
電極脫落偵測(正極)
關機腳。板上已上拉,不要接
六條線這樣接
Arduino UNO R4 端:杜邦線接在 D10、D11、GND 與下方的 3.3V、A0
AD8232 端:六支腳位接杜邦線,3.5mm 感測線接電極貼片
| AD8232 | UNO R4 | 說明 |
|---|---|---|
| GND | GND | 接地 |
| 3.3V | 3.3V | 供電 — 不要接 5V |
| OUTPUT | A0 | 心電訊號 |
| LO+ | D10 | 正極脫落偵測 |
| LO− | D11 | 負極脫落偵測 |
| SDN | 不接 | 板上已上拉 |
⚠️ 最常見、也最貴的錯誤
3.3V 接成 5V — AD8232 的供電上限是 3.5V。接到隔壁的 5V 腳位,模組會當場燒毀,而且從外觀完全看不出來。
自保習慣:接線時 USB 先拔掉 → 先接 GND → 最後才接 3.3V → 插 USB 之前,用眼睛再對一次 3.3V 那條線。
接線的順序
USB 拔掉,斷電再接線
先接 GND(黑線)
接三條訊號線:OUTPUT→A0、LO−→D11、LO+→D10
最後才接 3.3V(紅線)
用眼睛再對一次 3.3V 沒插到 5V
插上 USB
電極貼法
貼法 A — 胸口(改良式三導程)
- 紅 RA — 右鎖骨下方,右上胸
- 黃 LA — 左鎖骨下方,左上胸
- 綠 RL — 左下腹,肋骨下緣
貼法 B — 手腕 + 腳踝
- 紅 RA — 右手腕內側
- 黃 LA — 左手腕內側
- 綠 RL — 右腳踝內側或右小腿
貼片貼附注意事項
- 請先清潔皮膚並擦乾,確保貼片貼附良好
- 避開毛髮較多、骨突出或皮膚破損處
- 貼片需緊貼皮膚,避免鬆脫影響訊號品質
用 Claude Code 燒韌體 + 寫即時心電圖
這堂課的重點不是跑別人寫好的程式,而是你用 AI 寫出自己的。接好線、貼好電極之後,打開 Claude Code,用下面的 prompt 讓它幫你完成韌體燒錄和即時心電圖程式。Claude Code 有 arduino-cli,可以直接編譯、上傳,不用開 Arduino IDE。
建立專案、打開 Claude Code
$ mkdir my-ecg && cd my-ecg
$ conda activate bioagent
$ pip install pyserial numpy matplotlib
$ git init
$ claude
Prompt:燒韌體
# 在 Claude Code 裡輸入:
我的電腦 USB 上插著一塊 Arduino UNO R4,
上面接了 AD8232 心電模組。
幫我寫一個韌體 ecg.ino,然後編譯並上傳到板子上。
硬體接線:
- AD8232 OUTPUT 接 A0
- AD8232 LO+ 接 D10
- AD8232 LO- 接 D11
韌體需求:
1. 取樣率 500 Hz(用 micros() 計時)
2. ADC 解析度 14-bit
3. 開機時送 banner:#ECG fs=500 bits=14
4. 每個 sample 輸出一行:ADC值,電極脫落
5. 電極脫落 = LO+ 或 LO- 任一為 HIGH
Claude Code 會自動安裝 arduino-cli、下載 UNO R4 的 board package、編譯韌體、找到序列埠、上傳。整個過程不用開 Arduino IDE。
Prompt:即時心電圖
# 接著在 Claude Code 裡輸入:
幫我寫一個 Python 程式 ecg_live.py,
即時顯示剛才燒進去的 Arduino 心電訊號。
硬體資訊:
- Arduino 透過 USB serial 以 115200 baud 送資料
- 每行格式:ADC值,電極脫落 例如 8213,0
- 開機時會送 banner:#ECG fs=500 bits=14
- 取樣率 500 Hz,ADC 14-bit (0~16383)
功能需求:
1. 自動找到 Arduino 的序列埠
2. 即時畫出心電波形(用 matplotlib animation)
3. 濾波:去基線漂移(高通)、去 60Hz 市電(陷波)、去高頻雜訊(低通)
4. 偵測 R 波,顯示即時心率 bpm
5. 電極脫落時波形變橘色,顯示警告
6. 加上 --csv 參數可以同時錄檔
7. 加上 --list 參數可以列出所有序列埠
CSV 格式要求:
- 表頭:sample,adc,filtered,lead_off
- sample: 流水號從 0 開始
- adc: Arduino 原始 ADC 值
- filtered: 濾波後的值
- lead_off: 電極脫落狀態 0/1
執行
$ python3 ecg_live.py
看到波形了嗎?如果有問題,直接跟 Claude Code 說錯誤訊息,讓它幫你修。
如果 Claude Code 不順:助教寫好的版本
如果 Claude Code 產出的程式有問題、arduino-cli 裝不起來、或是時間不夠,下載助教寫好的版本:
arduino/ecg_r4/ecg_r4.ino— Arduino 韌體python/ecg_plot.py— 即時心電圖顯示python/ecg_sim.py— 模擬器(沒有硬體時用)python/ecg_replay.py— CSV 重播工具
Arduino 只做一件事
整份韌體 65 行,沒有任何濾波或分析——只是讀值、印成文字。
韌體核心
void loop() {
// 每 2ms(500 Hz)跑一次
int value = analogRead(A0);
int leadOff = digitalRead(10)
|| digitalRead(11);
Serial.print(value);
Serial.write(',');
Serial.println(leadOff);
}
USB 上流過的東西
5995,0
5998,0
6001,0
6014,1
- 第一欄:ADC 值 0~16383
- 第二欄:電極脫落 0/1
- 500 Hz、每秒約 4 KB
手動燒韌體(Arduino IDE)
- 用 Arduino IDE 開啟教材裡的
arduino/ecg_r4/ecg_r4.ino - 左側開發板管理員搜尋
UNO R4,安裝套件(約 200MB,只需一次) - Tools → Port 選有
usbmodem的那個(不是 debug-console、wlan-debug、Bluetooth) - 按 ✓ 驗證 再按 → 上傳,出現 Done 就成功
- 關掉 Serial Monitor——同一個埠不能兩邊開,不然 Python 會報
could not open port
跑助教的 Python
$ cd ecg-r4
$ python3 python/ecg_plot.py
不用指定序列埠,程式會自己找到 Arduino。常用參數:
| --list | 列出所有序列埠 |
| -p /dev/cu.usbmodem1101 | 手動指定序列埠 |
| --csv run1.csv | 同時錄檔 |
| --notch 0 | 關掉市電濾波 |
Python 幫你做了什麼
原始未處理的資料完整保留在 CSV 的 adc 欄位,事後想重新分析隨時可以。濾波演算法可以改、可以重跑,但原始訊號丟了就沒了。
螢幕上會看到什麼
綠色波形 + bpm 數字
三片電極都接觸良好,正在正常量測。左上角是即時心率。
橘色波形 + 「電極脫落」
至少一片沒接觸好。檢查貼片是否乾掉、線有沒有插到底。
一組良好訊號長這樣
實際量測 12 秒的結果,可以拿來對照你自己的數據:
怎麼用數據找問題
結論:左邊的 A0 讀到 0.95V、97.7% 都是 60Hz——AD8232 根本沒接上,A0 那支浮空的腳在當天線,吸收空氣中的市電。右邊接對後,直流準位跳到 1.81V(AD8232 的中點)、峰對峰一萬多 counts、99.7% 能量在心跳頻段。
沒有硬體?用模擬器
教材附的 ecg_sim.py 會產生合成心電訊號,讓你在硬體還沒焊好前就能先測 ecg_plot.py。
# 終端機 A:啟動模擬器
$ python3 python/ecg_sim.py
# -> 印出類似 模擬埠: /dev/ttys012
# 終端機 B:連上模擬埠
$ python3 python/ecg_plot.py -p /dev/ttys012
# 調整參數
$ python3 python/ecg_sim.py --bpm 90 --noise 0.4 --leadoff-every 15
另外還有 ecg_replay.py,可以把錄好的 CSV 重播一次,沒有板子或想重看某一段量測時很好用。