故事的起點:一台被遺棄的聽診器
我有一天在實驗室的倉庫裡翻到一台智慧聽診器。它被丟在一個角落,包裝盒上佈滿灰塵,看起來是某個合作案結束後就被遺忘了。
身為一個對 IoT 設備有點著迷的生醫工程師,我腦中只有一個念頭:拆。
這篇文章紀錄的就是我逆向工程這台聽診器的過程——從搞懂它的藍牙通訊協定、分析它收到的音訊訊號、到思考怎麼接上生成式 AI 做遠距診斷輔助。
先搞清楚:聽診器在「聽」什麼?
在拆設備之前,我們得先懂生理學。聽診器聽的東西主要有兩種:心音和肺音。
心音的來源
你的心臟有四個腔室和四組瓣膜。每次心跳包含兩個主要的聲音:
- S1(第一心音):二尖瓣和三尖瓣關閉時產生的聲音,代表心室開始收縮。聽起來像是「搏」的一聲,音調較低。
- S2(第二心音):主動脈瓣和肺動脈瓣關閉時的聲音,代表心室收縮結束。聽起來像「噠」的一聲,音調稍高。
正常的心音是規律的「搏-噠、搏-噠」。如果出現第三心音(S3)、第四心音(S4)或心雜音(Murmur),可能代表瓣膜有問題或心臟功能異常。
從**心臟電生理(Cardiac Physiology)**的角度來看,心音跟心電圖(ECG)有直接的時間對應關係:S1 出現在 ECG 的 QRS 波群附近(心室去極化、開始收縮),S2 出現在 T 波結束附近(心室再極化、收縮結束)。這個時間關係在後面的訊號分析會很重要。
肺音的來源
肺音是空氣在呼吸道中流動產生的聲音。**呼吸系統(Respiratory System)**的結構從氣管到支氣管、到細支氣管、最後到肺泡,就像一棵倒過來的樹。
正常的肺音(稱為肺泡呼吸音)是柔和的「呼——吸——」聲。異常的肺音包括:
- 囉音(Crackles/Rales):像揉搓頭髮的聲音,可能代表肺部有積液(如肺炎、心衰竭)
- 哮鳴音(Wheezes):高音調的「咻——」聲,代表呼吸道狹窄(如氣喘)
- 摩擦音(Pleural Friction Rub):像兩張砂紙互磨,代表肋膜發炎
聽起來很複雜,但重點是:不同的聲音代表不同的疾病狀態,這就是聽診器的診斷價值。
拆開來看:硬體架構
打開外殼之後,我看到了以下的硬體組成:
聲學模組
聽診器的前端是一個壓電式麥克風,跟傳統聽診器的膜片(Diaphragm)不同的是,壓電麥克風能把聲波直接轉換成電訊號。它的敏感度不錯,頻率響應範圍大約在 20-2000 Hz,剛好覆蓋了心音(20-200 Hz)和肺音(100-2000 Hz)的範圍。
類比前端
麥克風輸出的電訊號非常微弱(微伏等級),需要經過多級放大和濾波。這裡用了一個低雜訊運算放大器做前級放大,然後接一個帶通濾波器(20-2000 Hz),最後經過 ADC(類比數位轉換器)把類比訊號變成數位數據。
主控制器
核心是一顆 Nordic nRF52832 晶片——這是 IoT 設備界的「國民晶片」,同時整合了 ARM Cortex-M4 處理器和 BLE(低功耗藍牙)通訊模組。處理器負責數位訊號處理,BLE 負責把數據傳到手機 App。
電源管理
一顆 3.7V 鋰聚合物電池,搭配電源管理 IC。續航力大約 8 小時連續使用。
BLE 通訊協定:偷聽藍牙封包
這是逆向工程最有趣的部分。我用 nRF Connect(Nordic 出的藍牙除錯工具)去掃描這台聽診器的廣播封包。
發現的 GATT 服務
BLE 通訊用的是 **GATT(Generic Attribute Profile)**架構。簡單說就是把數據組織成「服務(Service)」和「特徵(Characteristic)」的層級結構,有點像資料夾和檔案的關係。
我在這台聽診器上找到了以下服務:
- Audio Streaming Service(自定義 UUID):這是主要的音訊傳輸通道。它用了一個 Notify 特徵,以 8kHz 取樣率、16-bit 精度持續串流原始音訊數據。每個 BLE 封包大約 160 bytes,也就是 80 個取樣點。
- Device Information Service(標準 UUID):包含韌體版本、硬體版本、序號等基本資訊。
- Battery Service(標準 UUID):回報電池電量。
- Control Service(自定義 UUID):用來控制錄音的開始/暫停/停止,以及調整麥克風增益。
封包格式解析
我把 Audio Streaming 的封包抓下來分析,發現它用的是 PCM(脈衝編碼調變) 原始格式,沒有壓縮。8kHz/16-bit 的數據流量大約是 128 kbps,在 BLE 4.2 的頻寬內剛好可以即時傳輸。
這裡有個問題:8kHz 的取樣率根據奈奎斯特定理,最高只能重現 4kHz 以下的頻率成分。對心音來說綽綽有餘(心音頻率主要在 200Hz 以下),但對高頻的肺音(可達 2000Hz)來說也還算夠用。不過如果要做更精細的肺音分析,16kHz 會是更好的選擇。
音訊訊號分析:讓電腦「聽」心肺音
拿到原始音訊數據之後,我用 Python 做了一系列的訊號分析。
心音分割
第一步是從連續的音訊中找出每一個 S1 和 S2。我用的方法是:
- 計算包絡線(Envelope):用希爾伯特轉換把音訊的瞬時振幅算出來
- 自適應閾值:根據包絡線的統計特性設定動態閾值
- 峰值偵測:找出超過閾值的峰值,標記為心音事件
- S1/S2 分類:利用 S1-S2 間距(收縮期)比 S2-S1 間距(舒張期)短的特性來區分
分割出 S1 和 S2 之後,就能計算心率、評估心音的規律性、偵測有沒有額外的心音或雜音。
頻譜分析
對每一段心音做短時傅立葉轉換(STFT),得到時頻圖(Spectrogram)。正常的 S1 頻率成分集中在 25-45 Hz,S2 在 50-80 Hz。如果出現頻率更高的成分(100-600 Hz),可能是心雜音的特徵。
肺音的分析也類似:正常呼吸音在 100-500 Hz 範圍,囉音會出現短促的高頻脈衝,哮鳴音會出現持續的窄頻帶能量。
機器學習分類
有了特徵之後,我訓練了一個簡單的分類模型。用的是梅爾頻率倒譜係數(MFCC)作為特徵,搭配一個輕量級的卷積神經網路(CNN)。在公開的心音數據集(PhysioNet Challenge 2016)上測試,正常/異常心音的分類準確率約 89%。
生成式 AI 的可能性:遠距診斷輔助
拆解完硬體和訊號處理之後,我開始想一個問題:如果把生成式 AI 接進來,這台聽診器能做什麼?
場景:偏鄉衛生所
想像一個偏鄉衛生所,只有一位護理師駐守。一位老伯伯走進來說胸口不舒服。護理師用智慧聽診器錄下心肺音,數據透過藍牙傳到平板,平板上的 AI 先做第一輪的自動分析:
- 心音分析結果:偵測到 S2 分裂,建議進一步評估主動脈瓣
- 肺音分析結果:右下肺葉有輕微囉音,建議評估有無肺部積液
- 綜合建議:疑似心衰竭早期表現,建議安排心臟超音波和胸部 X 光
護理師可以把 AI 的分析報告和原始音檔一起傳給遠端的心臟科醫師,醫師戴上耳機聽一下音檔、看一下 AI 的分析,就能給出更精確的指導。
生成式 AI 的角色
傳統 AI 只能給數值結果(「異常機率 87%」),但生成式 AI 可以用自然語言生成完整的分析報告,甚至根據病人的年齡、病史、症狀等資訊,給出個人化的建議。
它不是要取代醫生——在台灣的法規下,AI 不能直接做診斷。但它能扮演「超級助手」的角色,幫助非專科醫師或偏鄉醫療人員做出更好的初步判斷。
逆向工程教會我的事
拆這台聽診器的過程中,我學到最重要的事情是:一個看似簡單的醫療設備,背後涉及的知識域有多廣。
- 心臟電生理和呼吸生理學(為什麼會有這些聲音)
- 聲學和感測器原理(怎麼收集聲音)
- 嵌入式系統和 BLE 通訊(怎麼把數據傳出來)
- 數位訊號處理(怎麼分析訊號)
- 機器學習(怎麼讓電腦自動判斷)
- 臨床醫學(分析結果代表什麼)
- 法規和倫理(產品能不能合法上市)
這就是生醫工程迷人的地方——它不是任何一個單一學科,而是把很多學科串在一起的整合型領域。
給想動手做的你
如果你也想試試逆向工程,不一定要從聽診器開始。你家裡可能就有很多可以拆的 IoT 設備:智慧手環、藍牙體溫計、數位血壓計。
幾個建議:
- 先理解這個設備在偵測什麼生理訊號、背後的生理學原理是什麼
- 用 nRF Connect 或 LightBlue 去掃描設備的藍牙通訊,看看它傳了什麼數據
- 試著把數據接到 Python 裡做簡單的視覺化和分析
- 想想看:如果你是設計師,你會怎麼改良這個產品?
最好的學習方式,永遠是把東西拆開來看。
延伸概念:呼吸系統 · 呼吸系統解剖 · 心臟生理 · 電生理學 · 免疫系統生理概論 · 敏感度分析 · 心電圖 · 腎臟功能 · 肝臟功能


