上周帶孩子上課時,有個網(wǎng)友求助我一個藍(lán)牙的問題,正巧孩子上課我有大把時間,于是便聊了起來,他使用的是nordic的平臺,想要鏈接頑鹿和zwift這類的應(yīng)用app來實現(xiàn)室內(nèi)自行車等運動設(shè)備。
我曾經(jīng)也想過這個應(yīng)用,家里有一臺閑置著,滿是灰塵的橢圓機,只有一個簡單的斷碼屏幕可以顯示寫數(shù)字,比較枯燥,一直想改裝一下,無奈不得閑。
今天正巧,遇上了就嘗試著了解一下,順便幫網(wǎng)友也一起調(diào)試一下,不過他用的nordic平臺我已經(jīng)七八年不使用了,幾乎回憶不起來了,因為藍(lán)牙這個東西,每家的軟件都不甚相同,跨行業(yè)的電控工程師上手還是很難的。為了方面,我先用最近玩的國產(chǎn)芯片,磐啟微的PAN1070來實現(xiàn)。
之前自己做過模組,還做了一個底板,專門用來實現(xiàn)各種小應(yīng)用。
頑鹿和zwift一樣,是一個健身類的APP,模擬了實際場景,可以鏈接上我們室內(nèi)的自行車等運動設(shè)備,通過藍(lán)牙接受到踏頻,功率和速度信息,然后就生成動畫來模擬我們戶外騎行。
同時,如果像上圖這樣,我們的室內(nèi)自行車具備阻力調(diào)劑能力,軟件還可以下發(fā)阻力信息,這樣就能夠把真實的路況信息模擬出來。對于自行車愛好者來說非常的有價值,霧霾天呀,大冬天呀都可以在家騎車了。
我不是自行車愛好者,我曾經(jīng)騎摩拜單車十公里,蛋蛋都麻木的沒有知覺了,所以還是把橢圓機模擬成自行車吧。
首先,藍(lán)牙有個標(biāo)準(zhǔn)協(xié)議族FTMS,他規(guī)定了絕大部分的健康運動方面的硬件設(shè)備協(xié)議,這也讓我們的硬件和手機等上位機軟件具備了標(biāo)準(zhǔn)的通信能力。至于ANT+,我特別不喜歡,原因在于它不夠開放,也玩不起。
我們先說廣播,我們的藍(lán)牙模塊首先要廣播一些必要信息,讓APP能夠發(fā)現(xiàn)我們的設(shè)備,進一步鏈接我們的設(shè)備。
上圖是使用nrf connect掃描出來的一個廣播包信息,近些年來我一直在幫一些公司招聘技術(shù)人員,面試藍(lán)牙相關(guān)的候選人非常之多,不過,我發(fā)現(xiàn)他們絕大部分弄不懂藍(lán)牙廣播包的數(shù)據(jù)形式,我之前的藍(lán)牙基礎(chǔ)教程中也介紹過,這里不多言,放個鏈接:
第三篇 藍(lán)牙的廣播是如何做到多樣化的?
這里解釋下,藍(lán)牙的廣播包中,每一個段數(shù)據(jù)都是從LEN長度開始,后面跟著LEN個數(shù)據(jù)。其中緊跟LEN的就是廣播類型,最后面的一坨是數(shù)據(jù)。
比如第二行,他就是說,后面12個數(shù)是我的,0x09就是說,我是名稱,在后面的一串就是名稱字符串了。
那么對于FTMS協(xié)議,我們需要再廣播中展示出來,讓頑鹿和zwift來識別。對應(yīng)的也就是我上圖中的最后一行,6個字節(jié),TYPE類型為0x16。它的數(shù)據(jù)部分是FTMS的UUID(0x1826),再后面的指示運動設(shè)備支持的類型。具體要看藍(lán)牙官方的文檔
FTMS_v1.0.pdf
簡單說,UUID后面的一個字節(jié)表示健身設(shè)備是否有效。
最后的16bit表示不同的健身設(shè)備
我上面的廣播包開始弄錯了,想要嘗試的朋友可以按照上面的表格啟用第4和5bit即可以模擬出劃船機和室內(nèi)自行車。
有了廣播數(shù)據(jù)包,啟動頑鹿APP就可以在設(shè)備列表中看到我們的設(shè)備了。
當(dāng)APP這邊鏈接好了以后,我們就可以按照APP的操作邏輯來進行數(shù)據(jù)上報了。
數(shù)據(jù)上報的指令都是Notify的,具體的可以參考官方文檔,這里有個華為開發(fā)的網(wǎng)戰(zhàn),上面是中文的,看起來會省很多力氣。
文檔中心
這里面規(guī)定了我們藍(lán)牙設(shè)備需要實現(xiàn)的服務(wù),基本上包含兩個服務(wù):
DIS標(biāo)準(zhǔn)特征值支持范圍
FTMS標(biāo)準(zhǔn)特征值支持范圍
他們詳細(xì)的列表可以打開我上面放的鏈接查看,這里不粘貼過來了。我們以Indoor bike為例來說明一下這服務(wù)的協(xié)議內(nèi)容。
這里的UUID就是我們需要在0x1826服務(wù)下面生命的特征值。頑鹿APP在讀取到0x1826下面的0x2AD2特征值時,就會訂閱我們的Notify特征,此時我們就可以發(fā)送對應(yīng)的Notify數(shù)據(jù)了。順著這個鏈接點進去就能夠看到具體協(xié)議內(nèi)容。
藍(lán)牙的很多協(xié)議,為了保證數(shù)據(jù)內(nèi)容的靈活性,都采用了類似的方式,就是先放一個長度或者標(biāo)志,來決定后面跟的數(shù)據(jù)是什么,這種架構(gòu)極大的擴展了藍(lán)牙協(xié)議的擴展性。
你看,indoor bike data中的前兩個字節(jié)是flags,這里有16個bit,每一個bit代表著某一個數(shù)據(jù)是否上傳。簡單來說,加入Flags中有兩個bit被置位了,那么后面我們應(yīng)該跟上兩個參數(shù),參數(shù)的長度類型在標(biāo)準(zhǔn)文檔里有定義。
表格中的每一個bit都做了介紹,尤其要注意第一個,它與眾不同,置0時表示有對應(yīng)的數(shù)據(jù)。不知到為了啥,我想肯定是為了提高什么效率之類的。
接下來看具體數(shù)據(jù)的類型。
這里面列出來每種數(shù)據(jù)類型格式和單位,后面的必選和可選忽略它,這只是華為這邊自己要求的,實際藍(lán)牙協(xié)議里面都是可選的。
讓人不舒服的一點就是第一項,不用instantaneous speed,非得用more data,不知到為什么,可能是因為其他的健康設(shè)備協(xié)議中,第一個bit有可能代表多個數(shù)據(jù),劃船機就是這樣。
如果你的自行車不支持阻力調(diào)節(jié),其實到這里,我們就可以在軟件中吃撐天涯了,但是如果想實現(xiàn)阻力控制,我們還需要實現(xiàn)一個特征值Fitness Machine Control Point。這里以后再說。
先來看效果。