1. 程式人生 > >童話故事 --- 藍牙通信 --- 連接手機和嵌入式設備

童話故事 --- 藍牙通信 --- 連接手機和嵌入式設備

uid size otto 開啟 技術分享 一點 send ftp 高科技

高飛狗:

"常常的想,現在的你"

布魯托:

"哈羅!高飛!心情不錯嘛!"

高飛狗:

"嗨!又遇到難題了,百思不得其解,頭昏眼花的,心情糟透了!"

布魯托:

"又在研究什麽高科技項目?"

高飛狗:

"根本算不上什麽高科技,我有一個PM2.5監測裝置,就是能夠測量與記錄環境溫度、濕度和顆粒物濃度的東東,受應用條件的限制,沒有配備顯示屏,為了能夠在現場對其進行配置、管理並獲取測量數據,想在這個裝置上連接一個藍牙模塊,然後借助手機通過藍牙通信實現這些功能。"

布魯托:

"藍牙通信是很成熟的技術,應該不難解決。"

高飛狗:

"在手機上當然很容易就搜索到我的藍牙模塊並成功進行了配對,但是接下來如何開發一個AppPM2.5監測裝置通信,我是一頭霧水啊!"

布魯托:

"開發手機App,用Android Studio就可以。"

高飛狗:

"Android Studio開發出來的App無法在iOS上運行。再說,我只會C++語言,而Android Studio要用java語言開發。"

布魯托:

"我們不妨去找找黛絲博士,聽聽她有什麽高見。"

高飛狗:

"又去找她? 挺不好意思的。"

布魯托:

"黛絲博士是個熱心人,樂於助人,上次咱倆去求助,她一點架子都沒有,而且她對你的態度大為好轉,難道你沒瞧出來

? 沒準人家天天盼著你去問問題呢!"

高飛狗:

"真的嗎?你看出來轉機來了?我還有機會?"

布魯托:

"咱們這就走吧!"

高飛狗和布魯托再次來到黛絲家並按下了門鈴,"叮鈴鈴叮鈴鈴"。

黛絲:

"誰呀? 啊哦!是你們兩位,快請進!"

"快請坐,喝點咖啡還是綠茶?"

高飛狗:

"不用這麽客氣。黛絲,今天來又得麻煩你。"

黛絲:

"是什麽事呀?"

高飛狗:

"我想用C++開發一個手機App,通過藍牙通信管理我的PM2.5監測裝置,而且這個App必須在AndroidiOS上都能運行。"

黛絲:

"這有什麽難的呀。"

高飛狗:

"我就是不知該如何下手,一點思路都沒有。"

黛絲:

"最近剛剛做了一個類似的項目,正好跟你們說說,對我來說也算溫習所學知識吧。"

布魯托:

"您太謙虛了!"

黛絲:

"咱們先說藍牙通信的原理,然後再說具體實現吧。"

"藍牙通信和TCP/UDP的原理基本相同,幾乎如出一轍。參見下表。"

通信特征

TCP/UDP通信

藍牙通信

通信模式

客戶端-服務器模式

客戶端-服務器模式

通信端點

TCP端口

服務

通信端點標識方法

TCP端口號,是16位二進制數

服務UUID,是128位二進制數

客戶端通信過程

創建客戶端Socket

連接服務器

發送數據

接收數據

創建客戶端Socket

連接服務器

發送數據

接收數據

黛絲:

"看見了吧,與TCP/UDP相比,區別僅僅在於,藍牙用服務代替端口,用服務UUID代替端口號,且服務UUID較長。"

"用手機App管理嵌入式設備,手機就是客戶端,嵌入式設備上的藍牙模塊就是服務器。"

高飛狗:

"真的是一目了然!"

黛絲:

"TCP/UDP標準定義了一組固定的端口對應一組標準化服務。例如,TCP端口80用於Web服務;TCP端口21用於FTP服務。"

"類似地,藍牙標準也定義了一組固定的服務UUID對應一組標準化服務。"參見下表:

藍牙服務名稱

服務UUID

Serial Port

00001101-0000-1000-8000-00805F9B34FB

LAN Access Using PPP

00001102-0000-1000-8000-00805F9B34FB

DialupNetworking

00001103-0000-1000-8000-00805F9B34FB

OBEXObjectPush

00001105-0000-1000-8000-00805F9B34FB

OBEXFileTransfer

00001106-0000-1000-8000-00805F9B34FB

Cordless Telephony

00001109-0000-1000-8000-00805F9B34FB

Audio Source

0000110A-0000-1000-8000-00805F9B34FB

黛絲:

"由於藍牙服務UUID太長,就用16進制數表達,遵循8-4-4-4-12的方法表示。"

"藍牙通信與TCP/UDP通信的關鍵不同在於,藍牙服務器都有一個SDP服務,也就是服務發現服務,供客戶端查詢藍牙服務器能夠提供哪些服務。"

"通常,用於嵌入式設備的藍牙模塊都提供Serial Port服務,簡稱SPP,然後提供一個UART連接嵌入式設備",如下圖所示。

技術分享

黛絲:

"由此,手機App與嵌入式設備通信的基本流程如下(假設藍牙模塊已經與手機配對完畢)

步驟1:選擇要進行通信的藍牙模塊

步驟2:查詢藍牙模塊的服務。通常已配對的藍牙設備的服務列表已緩存在手機裏。

步驟3:如果存在SPP服務,恭喜你!

步驟4:用SPP服務UUID創建一個客戶端Socket

步驟5:用客戶端Socket連接藍牙模塊。

步驟6:調用客戶端SocketSendData()發送數據給藍牙模塊,藍牙模塊會將收到的數據通過UART轉發給嵌入式設備。

步驟7:如果嵌入式設備發送數據給藍牙模塊,藍牙模塊會轉發給手機,手機會緩存這些數據,App可調用客戶端SocketReceiveData()接收數據。"

黛絲:

"藍牙通信的原理就是這樣的。"

高飛狗:

"黛絲,你講得太明白了,今晚我一定要好好請請你、親親你!

黛絲:

"你就知道邪思歪想!"

高飛狗:

"那具體如何實現呢?"

黛絲:

"具體實現方法也很簡單。我們只要選擇Rad Studio作為開發工具,用C++編寫一套源代碼就可以生成適用於AndroidiOS上運行的App,是不是很酷?"

"有關Rad Studio就不在此累述,GUI界面的設計也很簡單,我們聚焦如何通過藍牙進行數據收發。"

借助藍牙SPP服務,實現手機與嵌入式設備之間的通信

1:本文旨在明晰藍牙通信原理,僅列出扼要代碼,如需完整代碼,可聯系本人。

2:確保已開啟手機藍牙

3:確保藍牙模塊已在手機的已配對設備列表中。

// 取得並保存藍牙管理器對象

TBluetoothManager *BtManager = TBluetoothManager::Current;

// 取得並保存藍牙適配器對象

BtAdapter = BtManager ->CurrentAdapter;

// 取得已配對的藍牙設備列表

TBluetoothDeviceList *PairedDevices = BtManager ->GetPairedDevices();

// 將藍牙設備列表顯示在組合框cbPairedDevices(代碼略)

// 獲取組合框中被選中的藍牙設備對象

TBluetoothDevice * SelDevice = PairedDevices ->Items[cbPairedDevices->ItemIndex];

// 獲取該藍牙設備的服務列表

TBluetoothServiceList * ListServices = SelDevice->GetServices();

// 在服務列表中查詢是否支持SPP服務(代碼略)

// 若支持SPP服務

// SPP服務UUID創建一個客戶端Socket

TBluetoothSocket *BtSocket = SelDevice ->CreateClientSocket(StringToGUID(SPP_GUI), false);

// 用客戶端Socket連接藍牙模塊。

BtSocket ->Connect();

// 調用客戶端SocketSendData()發送數據給藍牙模塊,藍牙模塊會將收到的數據通過UART轉發給嵌入式設備。

BtSocket ->SendData(DataArray); // DataArray是一個數組

// 如果嵌入式設備發送數據給藍牙模塊,藍牙模塊會轉發給手機,手機會緩存這些數據,App可調用客戶端SocketReceiveData()接收數據。"

BtSocket->ReceiveData(50); // 接收數據,限時等待50ms

黛絲:

"以上就是手機App與藍牙模塊間收發數據的基本流程及其實現。"

高飛狗:

"黛絲,你講得太深入淺出了!啊哦,快到飯點了,我請你吃個便飯,聊表謝意!"

黛絲:

"已經有人約我吃飯了,你們就趕緊回去試驗,有什麽問題隨時Call我。"

童話故事 --- 藍牙通信 --- 連接手機和嵌入式設備