謝作如++金孜達
我們如何得知自己的睡眠質量?比如夜里翻身幾次,有沒有夢游?或許大家第一個想到的就是智能手環。常見的智能手環的確都帶有睡眠監測功能,但我們對其監測結果深表懷疑,因為手環畢竟是戴在手上的,未必準確。而最可靠的監測位置,應該在人體的中心,即肚子。于是,我們試著用加速度傳感器做了一個能監測睡眠質量的小儀器。
● 材料選擇
我們選擇了Microduino。Microduino是Arduino的兼容開發板,體積很小,一塊板子和1元硬幣相近。因其具有電子積木的特點,堆疊方便,不需要焊接連線,做產品原型特別方便。制作這個作品大致需要如下材料,分別說明如表1:
當然,SD卡和USB線是不可少的,這里不再贅述。這四個模塊可以直接堆疊,高度約2CM,如圖1所示。
● 工作原理分析
睡眠監測儀的關鍵就是負責記錄身體的朝向,并將其忠實地記錄于SD卡上,以便于特制的數據分析器分析數據。我們先分析一下對身體朝向的定義。
圖2至圖5的視角是當你將其佩戴在腹部時,從頭部往腹部看的視角。
為了更易觀察,下頁圖6、圖7的視角發生了變動,請使用原先的相對視角看待它們。
然而事實上,幾乎不可能得到如圖2至下頁圖7那樣的監測值。實際上往往每次監測都會得到重力加速度的X、Y、Z方向的分量,且均不為零。對此,我們采用了一個非常簡單的判斷法:取模最長的一個分量對應的方位為此次的方位,如下頁圖8所示。
此外,我們還可以順便記錄每相鄰2次測得數量值的矢量差,這些都是有用的數據,可以用來判斷是否入睡以及估算一段時間內的睡眠質量等。
● 算法優化
最簡單的方法是周期性地監測重力加速度,不加任何處理地直接原始地記錄入SD卡,將一切處理任務全部交付于數據分析器。然而,這種方法一個晚上會產生大量的數據,如果每100ms記錄一次,記錄8小時,則文件大概為5.5M,明顯不是一種好方法。
第一種方法產生的文件之所以大,是因為存在大量的冗余數據。例如,一個人睡覺時一般會在10~15分鐘保持同一朝向幾乎不移動,而這段時間得到的數據十分接近,卻都被記錄了。所以應該要剔除相似數據,即設定一個閾值,閾值以內的數據不記錄。
然而,我們本來就是為了記錄身體的朝向,所以需要記錄的其實僅僅是身體朝向改變的事件。因此,數據還可以進一步優化。經過測試,一個晚上記錄的文件的大小一般小于3K。
需要注意的是,并不是任何原始數據都是可信的,除了無法預測的數據噪音,更值得關注的還有如下兩種情況:①用戶根本沒有進入睡眠狀態。我們無法期待用戶在睡著前一瞬間啟動產品,因此啟動產品的時機都是睡著前的一段時間,而這段時間用戶的行為被認為是相對活躍的。此時的數據根本不應當被記入,否則會對數據產生一定的干擾。②用戶已經進入睡眠狀態,但是身體正在運動。雖然一般情況測得的加速度可直接視為重力加速度,然而當用戶轉身或者有大幅度的運動時,就不能如此輕率地將測得的加速度用于確定當前用戶朝向的數據來源。
第一種情況的解決方法是并不急于記錄數據,而是將監測儀分為“監視狀態”和“記錄狀態”。一開始監測儀處于“監視狀態”,該狀態僅僅將數據寫入內存而不寫入文件。我們認為,若一段時間內數據變化不大且朝向主要不為站立時,則用戶已經進入睡眠狀態,隨后切入“記錄狀態”并新建數據文件。在“記錄狀態”,數據不僅被寫入內存,還會經過初步處理寫入文件。我們認為,若一段時間內用戶幾乎一直處于站立狀態,則用戶已經離開睡眠狀態,隨后返回“監視狀態”并終止數據文件。
第二種情況的解決方法是綜合考慮附近的數據。在這種處理方式下,我們可以較輕松地排除個別的突變數據,而不將之錯誤地作為有效數據進行處理。但如果用戶確實發生了朝向改變等大動作,我們也能夠正確地認知到這種變化并將其予以考慮。
● 睡眠指數的實現
睡眠好不好,總要弄個指標吧。睡眠質量指數是我們為了增加設備的功能而設計的一個參考指數。一般來說,在相等的一段時間內,身體活動越少,睡眠質量肯定越好。我們通過獲取這段時間內任意相鄰2次測得加速度的矢量差的模的平方并求和,來衡量身體如何活動。顯然,在相等一段時間內,模的平方和越大,身體的活動就越劇烈。
我們每次對朝向相同的一段連續時間計算睡眠質量指數,考慮到這些時間不盡相同,還需要將其除以時間差。這是睡眠質量指數的計算公式:
其中表示這段時間內第次測得的加速度;是這段時間相對于啟動儀器的開始時刻;是這段時間相對于啟動儀器的結束時刻;是相鄰2次測量的周期。
由于一共測量了次,故這段時間內的“平均相鄰加速度差的模的平方”的值為,除以100是數據上的需求(防止溢出)。
接著對計算得到的值進行映射。因為原先的值域為,故對其進行一次反正切運算并除以圓周率,就可以將其映射到一個上下有界的區間。由于一般情況下我們覺得這個值越高睡眠質量越好,因此將其取負。為了方便觀察,再加上。最后,乘以2000將其映射到,且此時睡眠質量指數與睡眠質量剛好成正相關,符合要求。
● 程序編寫
代碼編寫并不是很難,但是只能用Arduino的代碼寫,圖形化工具做不到。因為篇幅的緣故,下頁表2僅提供“監視狀態”模式的代碼和簡要解說,完整內容請訪問文尾二維碼鏈接的博客。
即使是經過初步處理的數據,其格式對一般用戶來講依然晦澀難懂,且格式不友好。因此,將數據轉變為用戶易于直觀讀取和理解的內容就成為了一項重要的任務。我們采用VB編寫分析器的源代碼和界面。雖然外表簡陋,不過已經能將數據顯示得足夠直觀。
首先,我們點擊菜單中的文件選項打開文件選擇框,選擇一份文件(該文件是一份生成數據文件,格式為*.rd,僅供演示);然后,數據將被處理與顯示,分寫界面如下頁圖9所示。
左上角表示睡眠的時間,一般情況只需了解最下面的“持續時間”即可。“起始時間”是自產品啟動到開始記錄文件的時間,“終止時間”是自產品啟動到結束記錄文件的時間。
右上角有一個按時間升序排列的列表,分別記錄每一次身體轉向的時間,和轉向完畢后身體的朝向,以及這個朝向的這段時間內睡眠質量指數。睡眠質量指數是一個量化數值,可以反映你的睡眠質量,值在0~999內浮動,數值越高,睡眠質量越好。
下方是一個睡眠質量指數圖表,直接完全地顯示了每個轉向的時刻及此段時間的睡眠質量指數,可清晰直觀地了解一次睡眠的總體質量與變化。
● 作品原型
做一個作品原型吧,于是我們找了三個小電池并連接起來(如圖10),以方便脫機運行。我們還采用3D打印外殼,將芯片與電池放入其中,最后封口??紤]到要以腰帶的形式固定在肚子上測試,我們最終拆了一個毛絨絨的公仔,放在里面。
睡眠質量的監測儀器并不復雜,制作簡易,探索歷程卻十分有趣。設計過程用到了單片機、編程和3D打印,體現了科技協作的力量。但這個作品還存在很多需要進一步考慮的問題,如加入一些簡易有效的濾波算法,以便高效精準地處理原始數據;通過一段時間的數據更好地推測當前用戶的睡眠狀況;改進數據分析軟件,使其更加易懂并具有更良好的交互功能等。
此外,睡眠數據的記錄使用了SD卡??紤]到現今使用的數據格式并不會占用大塊空間,因此還可以改良數據的傳輸方式,如使用藍牙或者WiFi將數據直接實時傳送到數據分析軟件,這些都是下一步要研究的重點。