祝小蜜,溫琦霖
(廣州商學院,廣東廣州,511363)
近年來,我國老齡化越來越嚴重,高血壓、糖尿病等慢性疾病越來越多,再加上現(xiàn)在不健康的飲食和生活方式使得各種疾病越來越常見。遠程的家庭醫(yī)生在社會上需求越來越大。同時,現(xiàn)在市場上出現(xiàn)了一些常見的家庭用的藍牙醫(yī)療設備,如血壓計、血糖儀、電子聽診器等?;谶h程家庭醫(yī)生的構想,可以做一套基于現(xiàn)有設備的遠程家庭醫(yī)生系統(tǒng)。常見的藍牙設備網關都采用帶系統(tǒng)的嵌入式,軟件開發(fā)難度相對較大,本文設計并實現(xiàn)了一種基于單片機的藍牙網關的軟件,設計不需要考慮藍牙協(xié)議、WIFI協(xié)議和4G通信協(xié)議的底層,可以快速的構建藍牙數(shù)據(jù)到云端的通信,將這些常用的藍牙醫(yī)療設備的數(shù)據(jù)上傳至云服務器,為實現(xiàn)遠程醫(yī)療打通了設備到云端的數(shù)據(jù)通信路徑。
藍牙網關的作用示意圖如圖1所示。
圖1 藍牙網關作用示意圖
本設計的網關功能是實現(xiàn)與四臺藍牙醫(yī)療設備的藍牙自動連接和數(shù)據(jù)傳輸,實現(xiàn)網關通過WIFI模塊或4G模塊與云服務器雙向通信。另外考慮到可推廣性和可用性,設計WIFI賬戶和密碼、服務器IP和端口號等信息的修改功能,和設備連接狀態(tài)的指示等,這部分功能用按鍵和顯示屏實現(xiàn)。同時設計掉電記憶功能,用于掉電保存每個用戶修改后的WIFI的名稱、密碼和服務器的IP地址、端口號,保證本設計的網關修改過上述信息后,掉電再開機時,網關能連接上WIFI和服務器。
本設計的硬件框圖如圖2所示。其中主控單片機型號是STM32F103RCT6,串口擴展電路使用WK2114芯片,藍牙模塊1、2、3使用低功耗藍牙模塊HLK-B40,用于連接血糖儀和兩個血壓儀藍牙,模塊4使用經典藍牙模塊HC-05,用于連接聽診器,WIFI模塊使用ESP-12E,4G模塊使用銀爾達公司生產的Core-Air724 AT固件版本,按鍵使用三個普通的獨立按鍵,顯示屏使用常見的1.44寸IIC總線的TFT-LCD顯示屏,掉電記憶使用EEPROM,型號是AT24C02 。
圖2 硬件平臺系統(tǒng)框圖
整個軟件功能是首先進行初始化,使網關能夠同時與4個藍牙模塊和WIFI模塊或4G模塊建立通信并使WIFI模塊或4G模塊能連接到服務器。初始化時要從AT24C02中讀取待聯(lián)網的WIFI的名稱、密碼和服務器的IP地址、端口號。初始化后網關處于空閑狀態(tài)下,該狀態(tài)網關服務器發(fā)送心跳包,服務器會回復心跳。當服務器下發(fā)上傳數(shù)據(jù)的命令時,網關退出空閑狀態(tài),此時如果對應的藍牙設備有數(shù)據(jù)產生則給服務器上傳數(shù)據(jù),每0.5秒上傳一次數(shù)據(jù)包,每次上傳后服務器都會發(fā)送確認數(shù)據(jù)包。當服務器發(fā)送停止上傳命令時,網關再次進入空閑狀態(tài)。空閑狀態(tài)下即使接收到藍牙設備發(fā)送的數(shù)據(jù),也不會將數(shù)據(jù)上傳到服務器。當網關在3秒內收不到服務器的心跳或確認信號,或者初始化階段WIFI模塊不能聯(lián)網,則認為當前WIFI模塊與服務器之間的連接中斷,此時啟動4G模塊初始化,使4G模塊替代WIFI模塊與服務器之間建立連接并繼續(xù)實現(xiàn)數(shù)據(jù)上傳。如果4G模塊斷網了,則提醒用戶聯(lián)網失敗請重啟。另外顯示屏上可實時查看與藍牙設備以及服務器的連接狀態(tài),通過按鍵可以進入修改界面,并修改WIFI賬戶和密碼以及服務器的IP地址和端口號,并將修改后的值在AT24C02中保存起來。
軟件整體分為初始化、用戶交互、與服務器之間的心跳和命令處理、數(shù)據(jù)上傳和利用外部中斷接收藍牙數(shù)據(jù)等幾個模塊,其中用戶交互包括按鍵檢測和處理、連接狀態(tài)檢測和顯示。
注意,本文對于STM32單片機的外設的使用、按鍵、顯示、IIC時序、EEPROM使用等常用的設計不展開說明,主要說明幾個模塊的配置過程以及整體代碼的邏輯設計。
圖3 整體軟件框架和流程
初始化分為兩個部分,一部分是單片機本身的外設的初始化,包括對IO口,串口,定時器,外部中斷的初始化;另一部分是指對功能模塊的初始化,目的是做好底層調用函數(shù)和使相應的模塊能正常工作,包括顯示屏和EEPROM用的IIC總線,WK2114串口擴展芯片的使用,各個藍牙模塊、WIFI模塊、4G模塊的AT指令配置等。
2.2.1 單片機外設初始化
單片機本身外設的初始化具體步驟不展開說明,只說明設置時要考慮的參數(shù)。對于定時器來說,系統(tǒng)用到了0.5秒計時、5秒計時等多個計時,對于多個計時,并不需要很多個定時器,只需要取所有計時的最大公約數(shù)的時間作為定時器中斷時間,同時記錄進中斷次數(shù),然后可以用進中斷次數(shù)來判斷多個計時時間是否達到。所以定時器中斷周期設置為0.5秒,中斷次數(shù)10次即為5秒。串口初始化的目的是建立單片機與各個模塊之間的串口通信,之后才能設置模塊的功能并接收數(shù)據(jù)。本系統(tǒng)一共使用了單片機的三個串口,分別連接擴展芯片的主串口、WIFI模塊和4G模塊的串口??紤]到數(shù)據(jù)傳輸速度至少要滿足電子聽診器12KB/s的傳輸速度,結合三種串口模塊能達到的串口最大速度,這三個串口的速度都設置為460800,這樣既能滿足設計需要,又不至于速度太高引起傳輸出錯率增加。外部中斷是為了從WK2114上讀取藍牙設備傳來的數(shù)據(jù)。為了不丟失數(shù)據(jù),讀取數(shù)據(jù)需要盡快反應,所以使用中斷的方式從WK2114的FIFO中讀數(shù)據(jù),并把該中斷優(yōu)先級設置為最高。
2.2.2 串口擴展芯片初始化
WK2114串口擴展芯片初始化時先拉低RST引腳10ms,實現(xiàn)對WK2114串口擴展芯片的復位,然后再拉高進入到工作狀態(tài)。然后進行主串口波特率的自動匹配,方法是給主串口發(fā)送匹配碼0x55,WK2114 可以自動測得此時MCU的波特率并把主接口UART的波特率鎖定,以后就以此波特率進行通信;如果主接口需要再次更換波特率,需要對芯片硬件復位,然后再次進行波特率測試和鎖定。匹配成功后,對每個子串口進行初始化,包括使能子串口的時鐘、軟件復位子串口、使能子串口總中斷、使能子串口接收觸點中斷和超時中斷、初始化FIFO和設置固定中斷觸點、使能子串口的發(fā)送和接收使能,設置子串口波特率等。本設計使用外部中斷來處理各個子串口之間的數(shù)據(jù)接收。
使能了WK2112的子串口中斷來讀取FIFO中的數(shù)據(jù),每個子串口的中斷方式都設置為64觸點中斷和超時中斷,即當任意一個子串口的FIFO中有64個字節(jié)數(shù)據(jù)或者在接收數(shù)據(jù)過程中有連續(xù)4個字節(jié)的時間內沒有收到數(shù)據(jù),則觸發(fā)中斷。
為了保證子串口同時收到的數(shù)據(jù)都能被主串口及時讀出,那么主串口的傳輸速度要大于所有子串口的數(shù)據(jù)接收速度之和。本設計只有經典藍牙模塊產生的數(shù)據(jù)速度快,要預留大于16KB/是的速度,所以對應經典藍牙模塊的子串口波特率設置為460800,其他三個藍牙產生數(shù)據(jù)的速度要小很多,所以另外三個子串口波特率設置為115200。
2.2.3 經典藍牙模塊初始化
首先讓模塊的復位引腳在高電平狀態(tài)下,連續(xù)拉低兩次50ms,讓藍牙模塊進入到AT指令模式。然后通過以下AT指令和步驟進行配置:
AT+UART=460800,0,0:修改模塊的串口波特率;
AT+ROLE=1:設置為主機模式;
AT+BIND=藍牙地址:綁定藍牙地址NAP:UAP:LAP(十六進制)綁定指令只有在指定藍牙地址連接模式時有效;
AT+LINK =藍牙地址:連接從機的配對地址;
AT+RESET:重啟模塊。
之后將藍牙RST引腳拉低,將保存這些AT指令配置并將進入到運行模式。
2.2.4 低功耗藍牙模塊初始化
當MCU每次復位時,通過對藍牙模塊復位引腳的重新配置,復位引腳在高電平狀態(tài)下拉低電平一秒鐘,讓藍牙模塊進入到AT指令模式。然后通過以下AT指令和步驟進行配置:
AT+BAND=115200:修改模塊的串口波特率;
AT+UUIDS=0000FFF000001000800000805F9B34 FB:藍牙模塊透傳服務默認值UUIDS;
AT+UUIDR=0000FFF400001000800000805F9B34 FB:透傳服務中的Read特征默認值UUIDR;
AT+UUIDW=0000FFF100001000800000805F9B34 FB:透傳服務中的Write特征默認值UUIDW;
AT+ROLE=2:設置為主機模式;
AT+PINCODE=000000:設置配對碼;
AT+PEERMAC=藍牙的MAC地址:連接從機的配對地址;
AT+REBOOT=1:重啟模塊。
之后模塊將按照這些AT指令的配置并進入到運行模式。
2.2.5 WiFi模塊初始化
WiFi模塊的初始化通過對復位引腳進行拉低250ms后拉高,實現(xiàn)WiFi模塊的復位,進入到AT指令模式。然后通過以下AT指令和步驟進行配置:
AT+CWMODE=3:模塊設置為softAP + station 模式;
AT+RST:重啟設備;
AT+UART_DEF=115200,8,1,0,1:設置串口波特率,并開啟串口流控制;
AT+CWJAP_CUR="WiFi名稱","WiFi密碼":配置模塊連接的WiFi名稱和密碼;
AT+CIFSR:查詢本地的IP地址;
AT+CIPMUX=0:設置多連接模式;
AT+CIPMODE=1:設置傳輸模式為透傳模式,僅支持TCP單連接情況;
AT+CIPSTART="TCP","IP地址",端口號:建立TCP連接;
AT+CIPSEND:在透傳模式時,開始發(fā)送數(shù)據(jù)。
當WiFi連接網絡失敗時,會啟動4G模塊的初始化,保證設備的聯(lián)網成功。
2.2.6 4G模塊初始化
復位引腳在低電平狀態(tài)下進行拉高1100ms后再拉低,完成4G模塊的復位,當復位完成時,會接收到模塊發(fā)送的“SMS READY”,表示復位完成。然后通過以下AT指令和步驟進行配置:
AT+CPIN?:查詢卡是否插好,直到接收到回應,否則嘗試重啟模塊;
AT+CSQ:查詢卡的信息質量;
AT+CREG?:網絡注冊狀態(tài);
AT+CGATT?:附著GPRS網絡;
AT+CIPMODE=1:設置為透傳模式;
AT+CIPMUX=0:IP設置為單鏈接模式;
AT+CSTT="CMNET","","":選擇卡的類型APN,這里使用的是中國移動;
AT+CIICR:激活后獲取IP地址;
AT+CIFSR:查詢IP地址;
AT+CIPSCONT:保存TCP的IP地址參數(shù);
AT+CIPSTART="TCP","IP地址",端口號:創(chuàng)建TCP連接。
以上每個步驟單片機都要收到對應的回復才會進行下一步。當接收到服務器下發(fā)的”CONNECT”,表示連接服務器完成。當4G初始化失敗時,顯示屏上提示連接不成功請重啟。
用戶交互包括顯示屏和按鍵。顯示屏有兩個顯示界面,一個界面是顯示網關與藍牙以及與服務器之間的連接狀態(tài),與各藍牙模塊的連接狀態(tài)由藍牙模塊的狀態(tài)輸出引腳的狀態(tài)判斷,與服務器之間的連接狀態(tài)由是否收到服務器的心跳信號或數(shù)據(jù)接收信號判斷;另一個界面顯示修改WIFI用戶名和密碼以及服務器IP地址和端口號的過程。
用戶輸入使用了三個獨立按鍵,分別是KEY1、KEY2、KEY3。KEY1用于進入修改狀態(tài)和切換修改的位數(shù)。設定家庭WIFI的用戶名和密碼都是8位的數(shù)字和小寫字母,而服務器的IP地址最大是255.255.255.255共12位數(shù)字,端口號最大是65535共5位數(shù)字,則總共需要修改的數(shù)字和字母位數(shù)是33位。系統(tǒng)正常工作時是顯示網關連接狀態(tài)的界面,當按鍵KEY1第一次按下時畫面切換到信息修改界面,并處于第一個字符待修改的狀態(tài),界面上該位顯示為紅色,其他位置顯示為藍色,之后每次按下KEY1時,待修改位都會切換到下一個并顯紅色,一直到第33個位置之后再按下一次就推出修改界面,回到連接狀態(tài)顯示界面,并且把修改之后的字符存入到EEPROM中。KEY2、KEY3用于待修改位的字符的加減,字符在0-9和a到z之間循環(huán)。
定時器初始化時設置為每0.5秒中斷一次,用于提供0.5秒的時基和5秒、100秒、200秒的計時,其中0.5秒用于區(qū)分為階段1和階段2,兩個階段交替的處理數(shù)據(jù);5秒計時用于空閑狀態(tài)時每個5秒發(fā)送一次心跳包;100秒用于開始WIFI模塊初始化的計時,如果WIFI在100秒內初始化成功,就不再計這個時間了,如果計時超過100秒就認為WIFI模塊聯(lián)網初始化不成功,這時要開啟4G模塊的初始化;200秒用于整個初始化階段的計時,如果超過這個時間還沒有初始化成功,則認為本網關連接不上網絡,在顯示屏上提醒用戶重啟本網關,如果初始化成功了,就會退出初始化狀態(tài),也就不再計時了。本文的流程圖都比較長,用偽代碼表達程序邏輯效果更好。定時器中斷服務函數(shù)的邏輯設計用偽代碼表示如下所示。
本網關根據(jù)服務器下發(fā)的命令處于空閑和非空閑兩種狀態(tài),空閑狀態(tài)不會上傳藍牙模塊收到的數(shù)據(jù),只上傳心跳包,非空閑狀態(tài)時,如果藍牙設備有數(shù)據(jù)發(fā)送過來,就把數(shù)據(jù)上傳給服務器。系統(tǒng)上電默認為空閑狀態(tài),此時每隔5秒給服務器發(fā)送心跳包??臻e狀態(tài)下如果收到開始上傳的命令,則系統(tǒng)進入非空閑狀態(tài),非空閑狀態(tài)下,如果收到停止上傳的命令,則進入空閑狀態(tài)。
不管在任何狀態(tài)下,任何數(shù)據(jù)包在網關和服務器的通信都是要回發(fā)確認數(shù)據(jù)包的。如果網關發(fā)出任何數(shù)據(jù)的3秒內收不到正確的服務器回發(fā)數(shù)據(jù),則認為網關和服務器之間斷開連接了,此時如果是使用WIFI模塊跟服務器通信,則需要啟動4G模塊的初始化,使4G模塊替代WIFI模塊與服務器之間建立連接并繼續(xù)實現(xiàn)數(shù)據(jù)上傳,如果是使用4G模塊在通信,則提示用戶聯(lián)網失敗,請重啟。
單片機計時都是使用的定時器,關于計時的邏輯是和定時器中斷函數(shù)一起實現(xiàn)的。與WIFI或4G模塊之間傳輸數(shù)據(jù)使用各自連接的串口。服務器下發(fā)的心跳回復、命令、接收數(shù)據(jù)回復都是固定長度為31的數(shù)據(jù)字節(jié),只是其中的有效字節(jié)不同。判斷是否收到正確的回復,通過串口接收中斷是否接收到31個的字節(jié)的數(shù)據(jù)且有效字節(jié)匹配。程序流程如下所示。
本設計采用WK2114串口拓展芯片,實現(xiàn)將一路異步串口拓展為 4 路 UART,用于連接四個藍牙模塊。WK2114是UART接口的4 通道 UART 器件,WK2114將一個標準異步串口擴展成為4個增強功能串口。
擴展的子通道的UART具備如下功能特點:每個子通道UART的波特率、字長、校驗格式可以獨立設置,最高可以提供2Mbps 的通信速率,每個子通道具備收、發(fā)獨立的256 級FIFO,F(xiàn)IFO的中斷可按用戶需求進行編程觸發(fā)點且具備超時中斷功能。FIFO功能非常必要。當大量數(shù)據(jù)連續(xù)傳輸時,需要單片機每0.5秒處理數(shù)據(jù)幀格式并配置串口DMA等,這需要一段時間,這段時間內新的要傳輸?shù)臄?shù)據(jù)就可以暫存在FIFO緩沖區(qū),等待下一個周期的處理。
藍牙模塊都連接在串口擴展芯片WK2114的四個子串口通道上,初始化完成后,當任一個藍牙設備發(fā)送數(shù)據(jù)都會存在對應子串口的FIFO中,當滿足FIFO的觸點或超時中斷條件時,都會觸發(fā)單片機的外部中斷,進入外部中斷服務函數(shù)??紤]到可能會有多個藍牙設備同時發(fā)送,而所有的子串口觸發(fā)中斷的引腳是共用的,所以每次進外部中斷,都對每個子通道的FIFO進行讀取并置位設備收到過數(shù)據(jù)的標記,保證不會漏掉數(shù)據(jù)。從每個子通道的FIFO都會讀取到數(shù)據(jù)長度和數(shù)據(jù),要將新收到的數(shù)據(jù)存儲到對應的存儲數(shù)組中,同時記錄存儲數(shù)組的總長度。根據(jù)擴展芯片的特性,當從某通道的FIFO讀出數(shù)據(jù)時,該通道對應的中斷標記位就會清零的,基于此,在中斷服務函數(shù)中會循環(huán)檢查FIFO中是否有新的中斷標記產生,如果有就繼續(xù)讀出,一直到4個FIFO中都沒有產生新的中斷標記。這樣在中斷服務過程中,如果已經讀過的子串口又收到了數(shù)據(jù),也會把新收到的讀出來并清掉新產生的標記,保證不會在讀某個子串口數(shù)據(jù)的時候,漏掉其他子串口剛好發(fā)過來的數(shù)據(jù)。
數(shù)據(jù)上傳服務器是0.5秒一次,為了保證上傳過程中還能收到藍牙發(fā)來的數(shù)據(jù),給每一個藍牙設備的數(shù)據(jù)存儲都分配了兩個數(shù)組。每0.5秒時間到了都要切換一次接收藍牙數(shù)據(jù)的存儲數(shù)組,以便讓下一個0.5秒接收的數(shù)據(jù)存在另一個數(shù)組里。這樣每個0.5秒的周期到來時,程序會通過串口DMA將上一個周期內收到的數(shù)據(jù)發(fā)送出去,同時在觸發(fā)新的數(shù)據(jù)接收中斷時,會將數(shù)據(jù)存儲到另一個數(shù)據(jù)存儲數(shù)組中,實現(xiàn)對數(shù)據(jù)接收和發(fā)送的乒乓操作,避免數(shù)據(jù)丟失。
對于每個藍牙設備,0.5秒可能收到的最大的數(shù)據(jù)量要了解清楚,以便分配足夠的緩存數(shù)組,本設計中,電子聽診器音頻的數(shù)組長度經過理論估算和實際測試,數(shù)組長度設為8000,其他三個設備的數(shù)據(jù)量小,緩存數(shù)組長度設置為255。
本段程序流程用如下的偽代碼表示。
當網關處于非空閑狀態(tài)時,每0.5秒判斷一次藍牙設備有沒有數(shù)據(jù)發(fā)送過來,如果有,就把0.5秒收到的數(shù)據(jù)上傳給服務器。連續(xù)的兩個0.5秒的周期分別稱為階段1和階段2,每次階段變化時,去發(fā)送上一個階段收到的數(shù)據(jù)。藍牙有沒有數(shù)據(jù)依據(jù)外部中斷服務器中產生的標記。上傳服務器的數(shù)據(jù)包包含幀頭、設備號、數(shù)據(jù)長度、數(shù)據(jù)代號、數(shù)據(jù)內容、校驗碼等,所以在數(shù)據(jù)發(fā)送前要給待發(fā)送的數(shù)據(jù)加上這些幀格式。然后啟動WIFI模塊或4G模塊對應的串口DMA發(fā)送功能,把數(shù)據(jù)發(fā)出去,使用WIFI模塊還是4G模塊,去前面描述的邏輯決定。當數(shù)據(jù)傳輸完成后,要立刻清掉數(shù)組里面數(shù)據(jù)和數(shù)據(jù)長度。注意,單片機串口DMA將數(shù)據(jù)發(fā)送到WIFI模塊的速度比較高,當連續(xù)發(fā)送的數(shù)據(jù)量非常大,比如發(fā)送電子聽診器的音頻數(shù)據(jù)時,WIFI模塊可能會來不及把WIFI模塊從串口收到的數(shù)據(jù)及時發(fā)送給服務器,造成數(shù)據(jù)擁堵,從而丟失傳輸數(shù)據(jù),所以該串口必須開啟硬件流控功能,這樣當WIFI模塊內部緩存的數(shù)據(jù)量比較大時,WIFI模塊會通過流控讓串口暫停發(fā)送。程序邏輯和流程如下所示。
本設計經過調試和驗證,能可靠的連接四個藍牙醫(yī)療設備并接收數(shù)據(jù),同時可以完整的把藍牙數(shù)據(jù)發(fā)送到云服務器,可以做為遠程家庭醫(yī)生系統(tǒng)中的重要組成部分。本設計為藍牙設備和云服務器之間的數(shù)據(jù)傳輸提供了一種設計思路,設計所用的藍牙醫(yī)療設備也換成其他的藍牙設備,只需要更改藍牙連接的初始化部分。后期也可以把更換藍牙設備連接的過程做到用戶交互功能里面,使本網關有更大的通用性,便于推廣使用。需要注意的是,網關的設計要考慮數(shù)據(jù)的吞吐量,本設計的傳輸速度可以滿足這類物聯(lián)網設計的要求,如果數(shù)據(jù)產生的又快又多,比如四個藍牙全部是音頻,就要重新考慮各模塊的傳輸速度了。
本文重點是對設計邏輯的說明,常用的基礎的代碼沒有詳細列出來,比如外設的初始化,IIC總線的操作、按鍵操作,顯示操作等等,這樣做是想盡可能的說明軟件的邏輯思路和構造,希望能為廣大的單片機開發(fā)者提供一定的參考價值。