一個(gè)藍(lán)牙實(shí)戰(zhàn)項(xiàng)目的掏肺總結(jié)丨【拜托了,物聯(lián)網(wǎng)!】
前不久一個(gè)在深圳的大學(xué)好友聯(lián)系到我,他們公司需要做一個(gè)USB藍(lán)牙接收器,功能大體如下:
USB藍(lán)牙接收器插在電腦上使用,被識(shí)別為鍵盤
手機(jī)程序連接該USB藍(lán)牙接收器
手機(jī)程序向電腦發(fā)送鍵盤輸入指令
配一張使用場(chǎng)景的圖片:
他這個(gè)需求多少有點(diǎn)非主流,看著像是藍(lán)牙鍵盤,但是物理上卻是USB接口的HID設(shè)備,并不是BLE的HID,BLE在這里只是用來接收手機(jī)發(fā)送的數(shù)據(jù)。
起初我也沒太認(rèn)真想如何實(shí)現(xiàn),就隨手發(fā)到我們的嵌入式交流群里,各路高手們紛紛提出了自己的方案:
群友喵了個(gè)咪的方案是:?jiǎn)纹瑱C(jī)模擬USB鍵盤+藍(lán)牙串口透?jìng)鳎梢杂肅H551+KT6368A,KT6368A可以參考之前寫的文章:嘗鮮1.6元的藍(lán)牙芯片KT6368A
群友heibus的方案是:串口轉(zhuǎn)USB HID芯片+藍(lán)牙串口透?jìng)鳎梢杂肅H9328+KT6368A。
群友oxlm、Pengfei的方案是:使用單顆藍(lán)牙SOC,可以用Nordic的NRF52840、NXP的QN9080等,藍(lán)牙芯片自帶USB接口,一顆芯片搞定。
群友baolei的方案是:CH340+KT6368A,通過Device Simulation Framework在PC端寫個(gè)上位機(jī)軟件,將串口收到的數(shù)據(jù)轉(zhuǎn)換成虛擬HID。
這4種方案從原理上來說都可以實(shí)現(xiàn)我這個(gè)同學(xué)的需求,說到我這個(gè)大學(xué)同學(xué),請(qǐng)?jiān)试S我臨時(shí)跑個(gè)題,當(dāng)年上學(xué)時(shí),他住我宿舍正對(duì)面,是個(gè)不折不扣的單片機(jī)迷,最初玩51單片機(jī),后來?yè)v鼓AVR單片機(jī)、然后自學(xué)uCosII操作系統(tǒng),后來不知道怎么又自學(xué)了Java,技術(shù)上特別愛專研。大學(xué)畢業(yè)后,我們就一南一北各自闖天涯了,他南下深圳直接工作了,從事安卓相關(guān)研發(fā)工作,這么多年一直在這個(gè)領(lǐng)域,在深圳也是純憑借個(gè)人能力攢錢買了房子。不得不感慨,干移動(dòng)互聯(lián)網(wǎng)的就是比干嵌入式的更容易搞錢啊。
那他為什么要整這個(gè)USB藍(lán)牙接收器呢?因?yàn)樗麄冃麻_發(fā)的這款A(yù)PP用在國(guó)外,而這個(gè)藍(lán)牙接收器是用來控制彩票機(jī)的,大概意思就是在手機(jī)點(diǎn)一點(diǎn),實(shí)現(xiàn)在彩票機(jī)購(gòu)買彩票的功能。至于為什么不直接在彩票機(jī)上購(gòu)買,他給我解釋了所謂智能的概念,聽的我一頭懵逼。
神奇了,最近老和BLE打交道,前段時(shí)間才研究了那個(gè)超便宜的BLE芯片KT6368A,這又來了一個(gè)BLE的相關(guān)需求,索性就考慮用群友heibus提出的CH9328+KT6368A方案來實(shí)現(xiàn)看看。
不過隨著后來進(jìn)一步的需求溝通,發(fā)現(xiàn)用CH9328+KT6368A還不行,原因是它手機(jī)端發(fā)送的指令并不是原封不動(dòng)的透?jìng)鬟^去就行了,實(shí)際上需要做轉(zhuǎn)換,比如說手機(jī)端發(fā)送十進(jìn)制1,對(duì)應(yīng)到USB HID 的是兩組8字節(jié)的16進(jìn)制數(shù)據(jù):00 00 08 00 00 00 00 00和00 00 00 00 00 00 00 00,這樣單純靠硬件就完成不了了,需要涉及到軟件開發(fā)。
關(guān)于00 00 08 00 00 00 00 00和00 00 00 00 00 00 00 00這兩組數(shù)據(jù)的含義,那就得簡(jiǎn)單補(bǔ)習(xí)點(diǎn)USB HID的基礎(chǔ)知識(shí)了。
鍵盤發(fā)送給PC的數(shù)據(jù)每次是8個(gè)字節(jié):
BYTE1 BYTE2 BYTE3 BYTE4 BYTE5 BYTE6 BYTE7 BYTE8
定義分別是:
BYTE1 :特殊按鍵,具體各位含義如下:
|–bit0: Left Control是否按下,按下為1
|–bit1: Left Shift 是否按下,按下為1
|–bit2: Left Alt 是否按下,按下為1
|–bit3: Left GUI 是否按下,按下為1
|–bit4: Right Control是否按下,按下為1
|–bit5: Right Shift 是否按下,按下為1
|–bit6: Right Alt 是否按下,按下為1
|–bit7: Right GUI 是否按下,按下為1
BYTE2:保留
BYTE3-BYTE8 :這六個(gè)為普通按鍵,鍵值可以參考USB HID to PS/2 Scan Code Translation Table.
舉個(gè)例子,比如按鍵a對(duì)應(yīng)的一幀數(shù)據(jù)是:00 00 0x04 0x00 00 00 00 00,第3字節(jié)04就是由下面這個(gè)表定義的:
這么說還是有點(diǎn)抽象,來點(diǎn)更直觀的,電腦端我們可以用Bushound等USB分析軟件,我這里用的是Free USB Analyzer :
我用的是筆記本電腦,先外接一個(gè)USB鍵盤
在軟件左側(cè)找到USB鍵盤對(duì)應(yīng)的設(shè)備,開始監(jiān)控,這里只選擇Daw Data View
按一下按鍵a并松開,這時(shí)軟件界面就會(huì)顯示收到了一串?dāng)?shù)據(jù),它其實(shí)是對(duì)應(yīng)了兩組8字節(jié)數(shù)據(jù),可以看到a確實(shí)對(duì)應(yīng)04,另外00 00 00 00 00 00 00 00表示的是按鍵彈起
如果一直按住a不松手,那么顯示的就會(huì)是如下信息:
只有當(dāng)你彈起按鍵a時(shí)才會(huì)顯示00 00 00 00 00 00 00 00
如果你要同時(shí)按下SHIFT+a組合按鍵再同時(shí)松開,那么對(duì)應(yīng)的數(shù)據(jù)就如下:
第一個(gè)字節(jié)就表示左側(cè)的Shift鍵。
當(dāng)然如果是你先按下Shift鍵,再按下a鍵,再松開a鍵,最后松開Shift鍵,那么就對(duì)應(yīng)4組數(shù)據(jù),分別為:
為了搞清楚這個(gè),我就花了好久的時(shí)間,畢竟以前也沒有怎么用過USB。再次回到他的藍(lán)牙接收器需求,手機(jī)端輸入的范圍是數(shù)字1-83,有的數(shù)字是對(duì)應(yīng)2個(gè)8字節(jié)數(shù)據(jù),表示的是一個(gè)按鍵的按下和松開,有的數(shù)字是對(duì)應(yīng)4個(gè)字節(jié),表示的是Shift+按鍵的組合按下與松開,并且每8個(gè)字節(jié)數(shù)據(jù)之間的時(shí)間間隔是200ms。
既然KT6368A不行,那就換一個(gè)可以編程的藍(lán)牙模塊,比如TI的CC2541模塊、Nordic NRF51822模塊都可以,因?yàn)槲以瓉碇С诌^NXP的QN9021芯片,對(duì)它相對(duì)熟一點(diǎn),所以就用QN9021來實(shí)現(xiàn)了。
用QN9021來實(shí)現(xiàn)上述軟件功能(藍(lán)牙接收手機(jī)發(fā)送過來的一串?dāng)?shù)據(jù),然后轉(zhuǎn)碼輸出)我本來以為分分鐘就搞定了,結(jié)果實(shí)際調(diào)試起來并不是想象的那么簡(jiǎn)單。因?yàn)槌R?guī)的藍(lán)牙透?jìng)魇褂梅绞绞谴诮邮諗?shù)據(jù)然后藍(lán)牙發(fā)送,這個(gè)需求正好是一個(gè)反向的操作。其中涉及到幾個(gè)關(guān)鍵的問題:
手機(jī)端發(fā)送過來的是一串長(zhǎng)度可能長(zhǎng)、可能短的數(shù)據(jù)。因?yàn)镼N9021是BLE 4.0芯片,一次發(fā)送字節(jié)最多是20個(gè)字節(jié),所以要考慮超過20字節(jié)的情況。
藍(lán)牙芯片一邊藍(lán)牙接收數(shù)據(jù),一邊串口發(fā)送數(shù)據(jù),要考慮串口沒有發(fā)送完,藍(lán)牙又來數(shù)據(jù)的的情況。
手機(jī)發(fā)送的不同鍵值,程序里要實(shí)現(xiàn)轉(zhuǎn)碼(有的是對(duì)應(yīng)發(fā)送2個(gè)8字節(jié)數(shù)據(jù),有的是對(duì)應(yīng)4個(gè)8字節(jié)數(shù)據(jù),每個(gè)8字節(jié)數(shù)據(jù)中間都是200ms)的代碼實(shí)現(xiàn)問題。
有經(jīng)驗(yàn)的程序高手可能不覺得是什么問題,但是對(duì)我這樣好久沒實(shí)際寫代碼的人,還是折騰了不少時(shí)間。
上述問題1只能通過手機(jī)端分包來解決,問題2解決辦法是加一個(gè)隊(duì)列,把藍(lán)牙接收的數(shù)據(jù)放到隊(duì)列里緩存起來,串口從隊(duì)列取數(shù)發(fā)送。問題3我是在200ms定時(shí)器函數(shù)里通過設(shè)置標(biāo)志位做了一個(gè)小狀態(tài)機(jī)來實(shí)現(xiàn)的。
最后我們?cè)賮砜偨Y(jié)下這幾種方案,
這幾種方案從硬件角度來看,都具備BLE和USB功能,只不過軟件部分跑的地方不同,最終都可以實(shí)現(xiàn)所需要的功能。
至于在實(shí)際項(xiàng)目或產(chǎn)品中,到底選取哪一種方案,實(shí)際上是需要綜合考慮多方面的因素的,比如開發(fā)周期、成本、軟件開發(fā)難易、甚至芯片是否好買等。
下一步我會(huì)再研究第一個(gè)方案的實(shí)現(xiàn),即CH551+KT6368A,后面大概率用這個(gè)方案,原因大家應(yīng)該都明白吧。
【拜托了,物聯(lián)網(wǎng)!】有獎(jiǎng)?wù)魑幕馃徇M(jìn)行中:https://bbs.huaweicloud.com/blogs/299476
IoT 單片機(jī) 嵌入式
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。