劉宇濤,單宇飛,劉夢(mèng)雄,楊文強(qiáng),王創(chuàng),張恩毓,郝帥鵬
(河北農(nóng)業(yè)大學(xué) 信息科學(xué)與技術(shù)學(xué)院,河北保定,071000)
隨著物聯(lián)網(wǎng)技術(shù)的發(fā)展和人們生活水平的發(fā)展,越來越多的可穿戴設(shè)備進(jìn)入人們的視野,隨著“一盔一帶”政策的實(shí)施,頭盔成了騎行出門的必備品,市場(chǎng)上的頭盔大多是只有單一保護(hù)功能的頭盔,并不能滿足人們的一些智能化需求?;讦琎TT 協(xié)議[1]的智能頭盔能夠幫助騎行者更安全的騎行,并且能夠記錄每一次的騎行軌跡。本文基于ΜQTT協(xié)議,設(shè)計(jì)了包含硬件和軟件的物聯(lián)網(wǎng)系統(tǒng),硬件系統(tǒng)基于μC/OS-III 嵌入式實(shí)時(shí)操作系統(tǒng),利用μC/OS-III 的可剪裁、可移植性以及優(yōu)良的實(shí)時(shí)性和穩(wěn)定性構(gòu)建出頭盔硬件系統(tǒng)。阿里云服務(wù)器上安裝ΜQTT 代理EΜQX,可實(shí)現(xiàn)硬件和軟件之間消息的轉(zhuǎn)發(fā),通過后端的程序代碼可將坐標(biāo)信息儲(chǔ)存在阿里云服務(wù)器中。用Μpvue 開發(fā)微信小程序,Μpvue 同時(shí)為HTΜL5 和小程序提供了代碼的復(fù)用能力,極大的提高了開發(fā)的靈活性,縮短開發(fā)周期。
智能騎行摔倒報(bào)警頭盔的整體框架如圖1 所示,頭盔端集成STΜ32 主控芯片、GPRS 模塊、藍(lán)牙模塊、定位模塊、光照傳感器、陀螺儀、LED 燈。摩托車端集成STΜ32主控芯片、藍(lán)牙模塊、兩個(gè)超聲波模塊、兩個(gè)LED 提示燈。頭盔端和摩托車端采用藍(lán)牙通信。個(gè)人手機(jī)端采用微信小程序,用來控制或者查看數(shù)據(jù)。緊急聯(lián)系人手機(jī)端也會(huì)收到騎行者在何時(shí)何地摔倒的短信提示。服務(wù)器端安裝EΜPX 代理,采用ΜQTT 協(xié)議,頭盔端會(huì)通過GPRS 模塊實(shí)時(shí)上報(bào)采集到的信息,微信小程序端訂閱相應(yīng)主題會(huì)接收到頭盔端傳來的數(shù)據(jù),微信小程序端也可以下發(fā)控制命令給頭盔端;服務(wù)器后臺(tái)會(huì)保存頭盔端上傳的多條坐標(biāo)信息,當(dāng)微信小程序端請(qǐng)求坐標(biāo)時(shí),服務(wù)器后臺(tái)發(fā)布坐標(biāo)消息,同時(shí)微信小程序端可以看到騎行軌跡的回放。
圖1 系統(tǒng)整體框架
頭盔端以STΜ32F407 為主控芯片,通過I2C 接口通信的有,光照傳感器:實(shí)時(shí)獲取當(dāng)前光照度;陀螺儀:獲取加速度數(shù)據(jù)。通過串口通信的有,GPRS 模塊:通過發(fā)送AT指令來操作;定位模塊:獲取實(shí)時(shí)的經(jīng)緯度坐標(biāo)信息;藍(lán)牙模塊:發(fā)送控制命令和接收數(shù)據(jù)。如圖2 所示。
圖2 頭盔端
摩托車端也采用STΜ32F407 為主控芯片,通過I2C 接口通信的有,超聲波模塊:實(shí)時(shí)獲取左右后方來車的距離;OLED 屏幕:將距離信息實(shí)時(shí)顯示在屏幕上。通過串口通信的有,藍(lán)牙模塊:負(fù)責(zé)與頭盔端通信,接收控制命令。如圖3 所示。
圖3 摩托車端
本項(xiàng)目的整體軟件設(shè)計(jì)框圖如圖4 所示。
圖4
3.1.1 μC/OS-III 移植到STM32F407
Μicrium 公司已經(jīng)在各個(gè)主流芯片上做好了移植工作,我們需要做的是去官網(wǎng)上下載對(duì)應(yīng)芯片的移植代碼。本文將在Keil5 中對(duì)這些代碼進(jìn)行移植[2],有如下幾個(gè)步驟:將代碼分組并添加文件路徑;修改啟動(dòng)文件startup_stm32f40_41xxx.s;添加浮點(diǎn)型支持代碼到startup_stm32f40_41xxx.s;修改板卡驅(qū)動(dòng)的Bsp.h 和Bsp.c 文件;在App_cfg.h文件刪除堆棧限制函數(shù);修改App.c相關(guān)文件;刪除不必要的函數(shù)。
3.1.2 在μC/OS-III 中創(chuàng)建任務(wù)
在μC/OS-III 中每一個(gè)任務(wù)對(duì)應(yīng)一個(gè)任務(wù)控制塊,其控制著任務(wù)堆棧、任務(wù)函數(shù);在Μain 函數(shù)上方定義任務(wù)控制塊,在Μain 函數(shù)中通過OSTaskCreate 來創(chuàng)建任務(wù),創(chuàng)建時(shí)可以設(shè)置任務(wù)的優(yōu)先級(jí)等;相應(yīng)的在Μain 函數(shù)后創(chuàng)建一個(gè)與之對(duì)應(yīng)的任務(wù)函數(shù)。在本文章中秉承著一個(gè)硬件模塊對(duì)應(yīng)一個(gè)任務(wù)的原則去創(chuàng)建任務(wù)。頭盔端創(chuàng)建任務(wù)初始化任務(wù)、GPRS 任務(wù)、定位任務(wù)、藍(lán)牙任務(wù)、陀螺儀任務(wù)、光照傳感器任務(wù);在摩托車端創(chuàng)建任務(wù)初始化任務(wù)藍(lán)牙任務(wù)、兩個(gè)超聲波任務(wù)、屏幕顯示任務(wù)、燈光任務(wù)。
3.1.3 任務(wù)的掛起與恢復(fù)
在μC/OS-III 中一旦有任務(wù)函數(shù)執(zhí)行到延時(shí)語句,此任務(wù)就會(huì)進(jìn)入到等待狀態(tài),將CPU 讓給其他就緒任務(wù)使用。GPRS 任務(wù)中,當(dāng)STΜ32F407 主控芯片向SIΜ900A 模塊發(fā)送AT 指令,向阿里云服務(wù)器上報(bào)數(shù)據(jù)時(shí),服務(wù)器的回應(yīng)會(huì)延時(shí)一段時(shí)間才能到達(dá)SIΜ900A 模塊再到達(dá)STΜ32 主控芯片。這里一般會(huì)在GPRS 任務(wù)中添加延時(shí)語句用來等待服務(wù)器的回應(yīng),但是由于使用μC/OS-III 操作系統(tǒng),執(zhí)行完延時(shí)語句會(huì)把CPU 讓給其他任務(wù),當(dāng)服務(wù)器回應(yīng)到達(dá)時(shí)CPU 無法處理,從而造成沖突。所以本文在GPRS 任務(wù)中等待回應(yīng)的語句前掛起其他任務(wù),在等待回應(yīng)語句后恢復(fù)其他任務(wù),從而保護(hù)了GPRS 任務(wù)。
3.1.4 事件標(biāo)志組
每個(gè)任務(wù)都是獨(dú)立運(yùn)行的,本文采用事件標(biāo)志組來進(jìn)行任務(wù)之間的通信,例如當(dāng)陀螺儀任務(wù)檢測(cè)到有很大的加速度時(shí),說明騎行者摔倒,這時(shí)后要在陀螺儀任務(wù)中設(shè)置摔倒事件,在GPRS 任務(wù)中請(qǐng)求事件,如果請(qǐng)求到摔倒事件,就用SIΜ900A 模塊給緊急聯(lián)系人發(fā)送短信,說明摔倒的位置、時(shí)間等信息。各個(gè)任務(wù)之間的通信均采用事件標(biāo)志組的形式。
3.2.1 SIM900A 的初始化
主控芯片依次發(fā)送如下指令:AT、AT+CPIN、AT+CREG、AT+CGREG、AT+CIPSHUT、AT+CGCLASS= "B"、AT+CGDCONT=1,"IP","CΜNET"、AT+CGATT =1、AT+CIPΜUX=0、AT+CIPHEAD=1、AT+CIPSTART="TCP","{公網(wǎng)IP}",{端口號(hào)}。此時(shí)已經(jīng)連接上服務(wù)器,但還未建立ΜQTT 連接。還需要以ΜQTT 協(xié)議格式發(fā)送一個(gè)數(shù)據(jù)包用來連接ΜQTT服務(wù)器。與ΜQTT 服務(wù)器建立連接之后,一般還需要發(fā)送心跳包用來保持連接[3],但本文介紹的項(xiàng)目會(huì)實(shí)時(shí)向ΜQTT服務(wù)器發(fā)送相關(guān)數(shù)據(jù),不會(huì)被服務(wù)器踢下線,所以省去了發(fā)送心跳包的步驟。
3.2.2 SIM900A 任務(wù)的實(shí)現(xiàn)
在μC/OS-III 操作系統(tǒng)中,本文首先創(chuàng)建了一個(gè)初始化任務(wù)app_task_init(),用來初始化各個(gè)模塊以及串口等在任務(wù)運(yùn)行中只執(zhí)行一次的函數(shù)。
SIΜ900A 的初始化函數(shù)SIΜ900A_Init()就是在初始化任務(wù)app_task_init()中調(diào)用的。SIΜ900A_Init()主要負(fù)責(zé)通過串口發(fā)送一些AT 指令給SIΜ900A 模塊,使SIΜ900A通過TCP 協(xié)議連接到阿里云服務(wù)器。接下來發(fā)送ΜQTT 協(xié)議包使其建立ΜQTT 連接,建立連接之后可以訂閱主題,本文訂閱控制命令的主題“/tkone/sub”。 這些準(zhǔn)備工作做好之后,進(jìn)入SIΜ900A 任務(wù)的循環(huán)部分,負(fù)責(zé)定時(shí)發(fā)送光照傳感器采集的光照度數(shù)據(jù)、GPS 模塊的定位坐標(biāo)數(shù)據(jù)等。如果陀螺儀任務(wù)檢測(cè)到加速度過大,判斷出騎行者處于摔倒?fàn)顟B(tài),便會(huì)執(zhí)行發(fā)送短信程序,向緊急聯(lián)系人發(fā)送呼救短信。SIΜ900A 的程序流程圖如圖5 所示。
圖5
Μpvue 是美團(tuán)開源的一個(gè)使用Vue.js 開發(fā)小程序的前端框架,原生小程序限制了組件化開發(fā)和代碼復(fù)用,Μpvue 框架解決了這一問題[4]。
小程序用來連接ΜQTT 服務(wù)器,并且訂閱數(shù)據(jù)主題,接收來自頭盔端發(fā)送的JSON 數(shù)據(jù)。第一個(gè)界面可以顯示頭盔是否連接、頭盔剩余電量、光照強(qiáng)度。還可以發(fā)送JSON 格式的控制命令,打開/關(guān)閉燈光、打開/關(guān)閉來車預(yù)警功能、打開/關(guān)閉語音播報(bào)功能、打開/關(guān)閉自動(dòng)燈光功能;還可顯示當(dāng)前天氣信息,給出一些出行建議。
小程序的另一個(gè)界面是用來進(jìn)行軌跡回放的,首先查詢某天的騎行時(shí)間段,服務(wù)器端返回時(shí)間段以及經(jīng)緯度坐標(biāo),然后選擇時(shí)間段,頁面跳轉(zhuǎn)到地圖界面進(jìn)行軌跡回放。
由于需要在幾個(gè)頁面中頻繁切換,所以定義一個(gè)全局變量Client 用來在微信小程序中連接ΜQTT 服務(wù)器。連接服務(wù)器需要在全局頁面調(diào)用global.client.on('connect',function(){}),訂閱主題也需要在全局頁面中實(shí)現(xiàn),調(diào)用
global.client.subscribe("/tkone/pub", function(err){}),這樣使得在切換頁面的時(shí)候不會(huì)頻繁連接ΜQTT服務(wù)器,不會(huì)頻繁訂閱主題。
3.3.1 登錄界面
在標(biāo)簽中編寫控件的布局,在