護系統(tǒng)開發(fā)實戰(zhàn):心率血氧、跌倒檢測與遠程告警)
簡介面向嵌入式、物聯(lián)網及智能硬件學習者的一份完整老人監(jiān)護系統(tǒng)設計文檔以STM32F103RCT6為主控整合SIM800C、GPS、MPU6050、MAX30102等模塊覆蓋脈搏心率、體溫監(jiān)測跌倒檢測、定位跟蹤與OneNet云平臺遠程監(jiān)護等典型場景。資源為單個PDF文檔壓縮包約29.6MB內容按設計需求、硬件選型、云平臺部署、STM32代碼設計四大部分展開詳細分析了三軸加速度傳感器檢測摔倒的原理以及SIM800C、GPS、MAX30102等芯片的工作機制與調試要點并給出完整Keil工程實現(xiàn)思路。目前已有174人學習適合正在開展嵌入式課程設計、畢業(yè)設計或智能穿戴產品預研的讀者參考。通過這份材料可以快速建立老人監(jiān)護系統(tǒng)的整體框架認知減少硬件選型和代碼調試階段的時間成本。1. 為什么想給獨居老人做一套監(jiān)護系統(tǒng)需求倒推設計目標說實話做這個項目的起因很現(xiàn)實。家里老人獨居白天我們去上班晚上才回家。以前總覺得老人身體還行但有一次鄰居打電話說老人在樓道里坐了半天起不來問怎么回事老人說就是覺得暈想坐一會兒。話是輕飄飄的可那段時間我心里一直在想如果當時他直接倒地了誰會知道手機在口袋里他自己能拿得出來嗎基于STM32做一套老人監(jiān)護系統(tǒng)本質上就是把這個沒人知道的空窗期用嵌入式方案填上。站在畢業(yè)設計或者個人項目的角度來看這類題目的技術覆蓋度也非常友好底層要配置GPIO、定時器、I2C、ADC、串口上層要處理傳感器協(xié)議、數據濾波、狀態(tài)判斷再加上WiFi通信、實時操作系統(tǒng)一條鏈捋下來STM32開發(fā)里最重要的知識點幾乎全過了一遍。這也是為什么STM32相關的畢業(yè)設計題目里老人監(jiān)護、智能穿戴、健康監(jiān)測總是排在前列——不是題目沒新意是它確確實實能鍛煉完整的產品思維。在設計目標上我沒有一上來就追求全功能、高端化。跟幾個做過類似方案的朋友聊過之后結合自己踩坑的感受我把需求收斂成了下面幾條能實時測量心率、血氧飽和度這是最基本的人體體征參數能檢測跌倒動作并且在識別到疑似跌倒時主動詢問/告警提供一鍵SOS緊急求救用戶主動觸發(fā)要最可靠異常情況下能遠程通知家人不能只在本地響鈴設備要便攜、可充電數據至少能夠脫離手機獨立工作。這幾條需求看著簡單真正做起來每條都不省心。心率血氧牽扯到模擬前端和信號處理跌倒檢測牽扯到姿態(tài)解算和誤報抑制遠程通知又牽扯到網絡模塊的功耗和穩(wěn)定性。后面我會按模塊拆開講把從選型到調試的完整鏈路都過一遍包括那些文檔里查不到、只有上手跑過才會遇到的坑。2. 硬件選型里的思路主控、傳感器和通信模塊怎么搭才合理2.1 主控為什么選STM32F103C8T6而不是更小的芯片主控選的是STM32F103C8T6。這顆芯片在如今看來不算新但作為監(jiān)護系統(tǒng)的主控它的平衡性非常好72MHz主頻足夠跑傳感器數據解算和通信協(xié)議棧64KB Flash在Keil5工程里不用精打細算地擠空間20KB SRAM跑FreeRTOS任務也不會太緊張1個I2C、1個USART、幾個定時器管腳位分布合理能把外設很舒服地分配開。有人可能會問用STM32L431之類更低功耗的芯片不更好包括我自己最初也糾結過。但實際對比后會發(fā)現(xiàn)L系列的低功耗優(yōu)勢要靠仔細配置多個低功耗模式才能發(fā)揮而F103在正常運行時功耗也沒到不可接受的程度。對初版功能驗證來說F103的資料密度、例程數量、調試工具兼容性都有明顯優(yōu)勢。項目重點是先把邏輯跑通功耗優(yōu)化我放在了第二版迭代里后面會專門講。2.2 傳感器選型MAX30102和MPU6050是性價比組合體征采集部分用了MAX30102。這顆芯片把紅光LED、紅外光LED和光電二極管集成在一起通過I2C直接輸出經過AD轉換的PPG光電容積脈搏波原始數據省去了前端模擬電路的設計。如果用分立元件搭光電容積脈搏波采集電路光是運放選型、濾波電路調試就夠折騰好幾周MAX30102的存在讓項目的重心回到算法和系統(tǒng)上這是用芯片換時間的一個典型做法。姿態(tài)檢測用的是MPU6050內置三軸加速度計和三軸陀螺儀。跌倒檢測主要靠加速度計的數據來判斷沖擊和姿態(tài)變化陀螺儀則用于計算姿態(tài)角變化兩個配合能判斷出人是直立摔倒還是彎腰下蹲之類的非跌倒動作。MPU6050在平衡小車、手勢識別這些項目里被用爛了資料極多驅動代碼也好改對開發(fā)效率很友好。通信模塊我留了兩個方案位。室內場景下首選ESP8266因為它便宜、SDK成熟、串口透傳方便如果后續(xù)要做室外場景可以把通信換成4G Cat.1模塊比如Air724UG或者EC200S代碼層面抽象出統(tǒng)一的發(fā)送接口即可。初版先用WiFi打通遠程告警鏈路這點很關鍵。2.3 人機交互與電源方案人機交互部分包括一塊0.96寸OLED屏、兩個物理按鍵、一顆有源蜂鳴器和一顆震動馬達。OLED用來顯示當前心率、血氧值、告警狀態(tài)物理按鍵一個是SOS急按鍵一個是復位/確認鍵蜂鳴器和震動馬達負責本地告警實測下來震動馬達在嘈雜環(huán)境下的提醒效果比蜂鳴器好老人放在口袋里也能感覺明顯。電源采用3.7V鋰電池方案電池經過TP4056充電模塊充電再通過RT9193-3.3V穩(wěn)壓芯片給整個系統(tǒng)供電。剛開始我用AMS1117做穩(wěn)壓但空載電流偏大對電池供電的設備不友好。RT9193的靜態(tài)電流只有微安級別而且輸出電壓紋波小給MAX30102這種模擬測量芯片供電更合適。系統(tǒng)休眠的時候整板電流能壓到幾百微安日常佩戴充電一次可以撐一天以上。3. 心率血氧采集從MAX30102的寄存器到濾波和數值解算3.1 理解PPG信號才能讀懂MAX30102的輸出先講一點背景原理。MAX30102內部的兩個LED交替點亮光打到皮膚上后一部分被血液吸收一部分反射回來被光電二極管接收。心臟收縮時血管內血容量增加吸收的光變多反射光就變弱心臟舒張時相反。光電二極管輸出的光強信號經過跨阻放大和ADC采樣就得到了隨時間波動的PPG波形。血氧飽和度則是利用含氧血紅蛋白和脫氧血紅蛋白對紅光660nm與紅外光940nm吸收率的差異來計算的這是脈搏血氧儀的基本原理。MAX30102的驅動配置看起來簡單實際上有幾個關鍵參數直接影響數據質量。LED電流我調到了20mA左右脈沖寬度設成最寬的4096微秒ADC量程選2048。這個組合的好處是寬脈沖讓每個采樣點積累更多光信號信噪比更高20mA電流在指夾或腕戴場景下既不會太暗導致信號幅度過小也不會因為電流太大把功耗和發(fā)熱帶上去。采樣率設置在100Hz對人體的脈搏頻帶來說足夠了平均心率、呼吸干擾都不需要太高的采樣率。3.2 I2C讀取和FIFO的使用方式MAX30102內部有FIFO緩沖可以把多個采樣點暫存在芯片里再一次性讀走。代碼上非常適合用定時器主循環(huán)配合DMA或者輪詢I2C讀取。我實際的讀取流程是一個定時器以10ms為周期觸發(fā)軟件標志位主循環(huán)檢測到標志位后通過I2C從FIFO寄存器讀出兩個通道的數據紅光和紅外光各占3個字節(jié)轉換成32位整數存在數組里。這里有個細節(jié)值得提一下MAX30102的FIFO深度是32個樣本如果讀得不及時數據會被新數據覆蓋。所以讀取FIFO的周期不要比采樣周期大太多。我直接用100Hz的采樣率配10ms的讀取周期每次讀出來正好是一到兩個新樣本。實測在標準庫和HAL庫兩種環(huán)境下都跑過HAL庫的I2C因為中間有多層抽象如果中間打斷次數多偶爾會丟樣本后來改成用DMA方式讀FIFO基本沒有再出現(xiàn)掉數的情況。3.3 心率解算滑動平均加閾值檢測比FFT更好用從原始PPG信號到心率值大多數人第一反應是上FFT做頻譜分析。但FFT在資源受限的MCU上做需要維護較大的計算緩沖而且窗口長度短了頻率分辨率不夠。我實際試過之后最終采用的是時域方案先做滑動平均濾波去掉高頻噪聲再用一個簡單的一階高通濾波截止頻率約0.5Hz去除基線漂移然后通過自適應閾值法檢測脈搏波的峰值計算相鄰兩個峰的時間間隔換算得到心率值。自適應閾值的思路是維護一個滑動窗口取窗口中信號最大值的70%作為當前檢測閾值。當信號從下向上穿過閾值時記錄一個峰值點。兩次峰值之間的時間差取倒數再乘以60就得到當前的心率。血氧飽和度采用的是經驗查表法計算紅光和紅外光交流分量與直流分量的比值R再代入血氧芯片數據手冊中的標準曲線用分段線性插值擬合出SpO2值。這套算法在靜止狀態(tài)下誤差可以控制在±2%以內已經能滿足日常監(jiān)護的精度要求。3.4 實操里最容易忽視的信號質量問題調試階段最讓我頭疼的不是算法而是信號質量。MAX30102的數據手冊會告訴你芯片支持紅血氧檢測但它不會告訴你戴得不緊、環(huán)境光太強、手指晃動時數據會直接變成一堆毛刺。后來我總結了幾條實用的排查方法用手指肚按壓傳感器指尖變白的瞬間如果看不到清晰的脈搏波說明光路沒有對準或LED電流太小用黑色海綿遮光袋包住手指和傳感器對比遮光前后波形如果遮光后波形幅度變化很大說明環(huán)境光干擾嚴重需要加強結構遮光手指保持靜止時波形幅度明顯增大稍有晃動幅度就掉一半這種情況下算出的心率值會忽高忽低算法上必須識別信號質量差值信號質量差的時候寧可不上報數據也不能報錯數據。關于上不上報錯誤數據這件事我后來專門做了邏輯保護實時計算兩個相鄰峰值的間隔如果間隔差異超過30%就判定當前信號不可信心率值顯示--直到連續(xù)出現(xiàn)5個以上穩(wěn)定的峰值間隔才恢復顯示。這個機制在用戶翻身、活動肢體時能有效避免心率值亂跳實際使用體驗好很多。4. 跌倒檢測的邏輯加速度波形分析加姿態(tài)判斷4.1 跌倒的波形特征和檢測難點跌倒檢測是這類監(jiān)護系統(tǒng)里誤報率最高、最容易被用戶吐槽的模塊。我一開始以為只要檢測到合加速度突變就能判定跌倒后來用MPU6050做了一組真實模擬實驗包括從站著倒地、從椅子上滑落、快速坐下、彎腰撿東西、原地跳了跳才發(fā)現(xiàn)單純用閾值判斷完全不可靠??焖僮潞吞幌峦瑯訒a生超過3g的加速度尖峰如果按閾值直接報警系統(tǒng)基本上會一天誤報幾十次。所以我把跌倒檢測拆成了三個階段來識別第一個是失重階段人體從站立到失重倒地合加速度會先下降低于0.6g并且持續(xù)至少100ms第二個是撞擊階段身體接觸地面瞬間合加速度產生一個至少2.5g到3g的尖峰持續(xù)時間在30ms到200ms之間第三個是靜止階段倒地后身體保持不動加速度回到1g附近姿態(tài)角從接近垂直變成接近水平。4.2 合加速度計算與姿態(tài)角獲取合加速度的計算很簡單三個軸加速度的平方和開根號。由于MPU6050輸出的是數字加速度值單位被配置成±2g量程取出的原始值除以16384就得到以g為單位的加速度。姿態(tài)角方面我用的是加速度計靜態(tài)傾角公式pitch atan2(accel_y, sqrt(accel_x^2 accel_z^2)) * 180 / PI roll atan2(-accel_x, sqrt(accel_y^2 accel_z^2)) * 180 / PI為什么要用這個公式而不是直接取某個軸的數值因為裝在手環(huán)或者口袋里的設備穿戴方向不固定直接用單軸判斷是否水平非常不靠譜。用雙軸反正切算出的姿態(tài)角在設備任意旋轉90度的情況下都能穩(wěn)定反映出人體軀干相對地面的角度。設計上要求可穿戴設備在任意角度佩戴都能使用這是必須過的坎。4.3 三階段判定算法和誤報抑制三階段判定在FreeRTOS里是作為一個獨立任務跑的每50ms讀一次MPU6050并更新狀態(tài)機。還有一個好用的小技巧每1分鐘滑動存儲最近50秒的姿態(tài)角均值當發(fā)生疑似跌倒時把當前姿態(tài)角與均值對比如果角度差小于30度說明這人本來就躺著大概率是翻身或者起身動作不是跌倒。確認疑似跌倒后系統(tǒng)不會立刻發(fā)告警而是進入一段10秒的預告警模式蜂鳴器鳴叫、屏幕上顯示檢測到跌倒按鍵取消報警。如果用戶在這10秒內按下確認鍵說明自己沒事告警取消如果10秒沒有取消系統(tǒng)自動判定為嚴重跌倒觸發(fā)遠程告警并附帶當前GPS位置如果接了定位模塊。這個10秒倒計時可取消機制比我最初設計的檢測即報警好太多誤報率在實際測試里從原來的每周十幾次降到了差不多兩周一次。4.4 實際測試數據說明問題我整理了一組室內模擬測試的記錄每次動作重復20遍統(tǒng)計檢出結果測試動作檢出次數未檢出次數誤報情況從站立位直接倒地191無從椅子上滑落200無快速坐下1檢出191次彎腰撿東西020無原地跳躍2檢出182次躺下翻身1檢出191次從數據里能明顯看到漫游心跳、下蹲、跳躍這類動作依然會有一定比例的誤報這是當前算法方案的天花板。如果想進一步壓低誤報率可以往里面加陀螺儀的姿態(tài)角變化率判斷或者在撞擊階段之后加入一個波形恢復時間的特征。但從可靠報警的角度看現(xiàn)在這個方案已經能解決大多數真實跌倒場景后續(xù)算法迭代可以作為獨立優(yōu)化點繼續(xù)深化。5. 遠程告警鏈路ESP8266加MQTT把消息送到手機上5.1 通信方案為什么選MQTT而不是TCP長連接遠程告警是整個系統(tǒng)離用戶最近、也是價值最直觀的部分。告警消息必須推送到家人的手機上而且延遲要盡量低。這里我選了MQTT協(xié)議通過ESP8266 Wi-Fi模塊連到云服務器。有人會不解STM32直接通過AT指令發(fā)個TCP連接不也能把數據傳出去嗎為什么要繞一層MQTT原因就在于TCP長連接需要自己維護保活、重連、消息確認這些機制而MQTT發(fā)布訂閱模型天然支持一對多推送家里人用微信小程序訂閱設備的告警主題設備只需要發(fā)布一條消息所有訂閱者都能收到。阿里云物聯(lián)網平臺、EMQX這類公共MQTT Broker都提供免費的開發(fā)檔位注冊一個設備三元組就能用省去自己搭服務器的麻煩。我用的云平臺是阿里云IoT的公共實例免費額度對個人項目綽綽有余。5.2 數據幀結構與發(fā)送流程設備發(fā)送給云端的數據格式用JSON字段包括設備ID、當前心率、血氧、電池電量、告警類型sos/fall、時間戳。因為MCU內存有限JSON字符串不能做得太大我裁掉了不必要的空格整個包的字符串長度控制在220字節(jié)以內放在一個256字節(jié)的緩沖數組里發(fā)送完立即清空。// 告警消息JSON結構示例 {dev:A001,hr:85,spo2:97,bat:78,alarm:fall,ts:1720000000}發(fā)送流程設計成三級防抖第一級是本地蜂鳴器和屏幕提示第二級是MQTT發(fā)布告警主題第三級是把告警記錄存在STM32內部Flash里下次設備收發(fā)電時重新上報。這個三級備份設計是我從一次WiFi斷開導致的丟事件中總結出來的。當時 ESP8266斷網重連花了差不多一分多鐘恰好那一次真正的SOS請求沒有發(fā)出去我意識到所有數據只走網絡鏈路是不可靠的必須在設備端留一份底。5.3 斷線重連與電量優(yōu)化ESP8266作為WiFi客戶端最大問題在于斷線后不會主動恢復需要通過AT固件的事件上報機制來感知連接斷開然后重新發(fā)起TCP連接、重新訂閱主題。這個邏輯名叫自動恢復?;顧C制我實現(xiàn)的時候用一個軟件定時器每30秒檢查一次連接狀態(tài)不通就自動走重連流程。只要WiFi信號不是弱到-85dBm以下實測重連成功概率很高。WiFi全時在線是這類設備功耗的最大殺手。我實測過MAX30102加MPU6050全速運行加上ESP8266保持常連電池電流平均在120mA到150mA之間一塊500mAh電池不到4小時就空了這顯然沒法用。后來優(yōu)化的策略是ESP8266平時Power Down心跳數據每30秒通過串口發(fā)送完就休眠只有檢測到異常告警時才喚醒并建立連接。這樣日常模式平均電流降到30mA左右異常模式下才走全功率鏈路。犧牲了一點數據實時上傳的平滑度換來了接近十倍的續(xù)航提升這筆買賣非常劃算。6. 軟件架構FreeRTOS任務劃分與模塊解耦6.1 多任務劃分的依據系統(tǒng)軟件采用FreeRTOS管理原因很直接這套方案里同時存在傳感器讀取、算法判斷、顯示刷新、按鍵掃描、WiFi通信、Flash存儲多個需要并行處理的環(huán)節(jié)。如果用裸機輪詢邏輯寫主循環(huán)會被I2C讀取的阻塞延時占滿按鍵響應和顯示刷新都會變得卡頓。任務劃分成這樣傳感器采集任務100Hz讀取MAX30102和MPU6050原始數據算法處理任務20Hz運行PPG濾波、心率血氧計算、跌倒檢測狀態(tài)機顯示任務5Hz刷新OLED屏幕更新心率血氧值和圖標狀態(tài)網絡任務1Hz處理MQTT收發(fā)、心跳?;睢嗑€重連按鍵與告警任務10Hz掃描SOS和取消鍵控制蜂鳴器與震動馬達。6.2 任務間通信用消息隊列代替全局變量任務之間傳數據用的是FreeRTOS消息隊列而不是到處定義全局變量。全局變量的問題在調試多任務代碼時特別明顯循環(huán)緩沖被多個任務同時寫容易產生數據錯位和難復現(xiàn)的隱性BUG。消息隊列的方式相當于把數據流按管道隔離生產者只管往隊列里丟消費者只在隊列非空時才取不會出現(xiàn)兩個任務同時訪問同一塊內存的情況。傳感采集任務和算法處理任務之間用的是兩個隊列一條通道傳PPG原始波形數據一條通道傳MPU6050的姿態(tài)數據。隊列深度的設置也需要考慮我最后定的是每個隊列長度64每項4字節(jié)FIFO讀出的樣本如果短時間沒被取走隊列會暫存而不是立刻丟降低了高優(yōu)先級任務被打斷時數據缺失的概率。實測在系統(tǒng)負載最高的異常處理場景下隊列也不會滿沒有出現(xiàn)因為隊列滿導致丟失關鍵傳感器數據的現(xiàn)象。6.3 按鍵消抖與中斷處理的細節(jié)SOS按鍵的可靠性直接關乎生命安全這里不能簡單用延遲消抖的常規(guī)做法。我的方案是按鍵觸發(fā)外部中斷中斷里只做一件事把一個軟件定時器的啟動時間重置。定時器超時0.15秒后在任務上下文中做一次完整的電平確認多重確認通過后才判定為一次有效按鍵。這么做既避免了延遲消抖帶來的誤觸發(fā)又不會在中斷里做太多事影響其他實時邏輯。7. 實測表現(xiàn)與調試經驗哪些坑值得記下來7.1 整體運行效果整套系統(tǒng)做完后我戴著原型機進行了大約三天的日常測試包括做飯、打掃、快走、午睡這幾個場景。心率顯示在靜息狀態(tài)下與小米手環(huán)對比差值在3次/分以內血氧在靜止狀態(tài)下與醫(yī)用指夾式血氧儀對比誤差在1%以內SOS按鍵響應時間小于1秒跌倒檢測模擬測試的識別率約95%誤報集中在快速坐下的場景。這個成績作為畢業(yè)設計或者個人項目交差完全夠用但離商用產品的準確度和魯棒性還有差距。7.2 MAX30102數據異常排查的三板斧很多卡在起步階段的人會問為什么我的MAX30102讀數全是0xFFFFFFFF這類問題九成出在I2C通信和芯片配置上。我按經驗總結了一個排查順序確認I2C地址是否沖突。MAX30102的7位地址是0x57如果總線上掛了其他I2C器件需要通過地址區(qū)分避免地址沖突導致讀寫錯亂檢查I2C上拉電阻一般4.7k到10k都可以。如果上拉電阻太大或太小波形邊沿會變差數據就讀不回來尤其當I2C線路稍微長一點的時候更明顯初始化順序很重要。要嚴格按照數據手冊的流程先寫模式配置寄存器再配置LED電流最后使能FIFO寫入。順序錯了會出現(xiàn)在某個狀態(tài)一直讀不到有效數據的情況。7.3 電池電量顯示的水分還有一個容易被忽略的坑是電量顯示。原計劃用ADC直接讀電池電壓再換算成電量百分比后來發(fā)現(xiàn)鋰電池的電壓和剩余電量并不是線性關系。3.7V到4.2V之間前半段電壓掉得慢后半段掉得很快直接線性映射的電量會有將近20%的誤差。后來我在網上找了一張比較通用的鋰電池電壓-容量曲線表用分段線性查表替代了一刀切的線性換算實測誤差縮小到5%以內。這個小改動人不多但對每天看電量顯示的老年用戶來說準確的電量顯示就是安全感。7.4 結構設計上的一點建議軟件和硬件都完成之后剩下的問題就是怎么裝進殼子。我建議用3D打印機打印一個帶卡扣的手環(huán)外殼傳感器部分用透明窗口讓光路盡量直射皮膚。感應面不要緊貼外殼表面內部留大概1到2毫米的懸空間隙否則手指按壓時受力不均會造成局部透光影響信號采集質量。OLED屏直接嵌在殼體表面朝外方便用戶查看。把排線全部用熱熔膠固定在殼體內壁避免晃動引起排線虛接這一條對于裸露測試板狀態(tài)的階段特別有用。8. 從畢業(yè)設計到可用產品還要補哪些功課做到現(xiàn)在這個程度原型機已經能穩(wěn)定監(jiān)體征、識別跌倒、發(fā)遠程告警自己也真實用小半個月。不過如果想讓它真正適合給老人長期使用還有幾層功課要補。功耗方面當前WiFi方案只適合在有電源環(huán)境的家里使用出門就沒網。要真正做成戶外可用通信方案必須換成4G Cat.1另外STM32的睡眠模式要細分平時除了傳感器輪詢主控盡量進Stop模式把平均電流壓到10mA級別配上1000mAh以上電池才能實現(xiàn)一周一充。算法方面心率血氧在用戶轉身、說話、抬手時依然會有短時抖動跌倒檢測也還沒做到老人真實的摔倒數據學習。這些場景的邊界性能要進一步提升靠的是大量真實佩戴數據來調試模型參數已經屬于數據驅動的范疇了。硬件層面鋰電池充電保護電路、電源和傳感器鋪地隔離、EMC測試這些量產必須考慮的事情原型機上還沒有系統(tǒng)做。如果要將這套方案繼續(xù)推進到實際產品階段硬件的可靠性是第一優(yōu)先級這可能比算法迭代更花時間。不過從學習、畢業(yè)設計、個人項目的角度衡量基于STM32的這套老人監(jiān)護系統(tǒng)已經把從硬件到云端全鏈路打通了。對我來說最大的收獲不是那一堆能跑的代碼而是習慣了從真實用戶場景出發(fā)倒推技術方案這個思考方式。在把心率血氧的調試閾值一個個試、把跌倒誤報率一點點降下來的過程里你真的能感受到工程實踐和課本例題之間的差別——課本告訴你什么是對的踩坑會告訴你什么是足夠好。這套系統(tǒng)的調優(yōu)空間還有很多但作為一個起點它已經給了我繼續(xù)往深做的理由。本文還有配套的精品資源點擊獲取