從藍牙4.0開始包含了兩個標准,傳統藍牙(Classic Buletooth)和低功耗藍牙(Bluetooth Low Energy)以下簡稱 BLE。
傳統藍牙支持音頻和數據兩大類協議,所以更適合音樂等數據量大的應用場景;傳統藍牙有3個功率級別,Class1、Class2、Class3,分別支持100m、10m、1m的傳輸距離。
BLE 更適用於實時性比較高,數據傳輸量小的場景,如遙控燈;BLE 無功率級別,一般發送功率在7dBm,一般在空曠距離,達到20m應該是沒有問題的。
BLE 的基本概念
1 GATT
說到 BLE 就不得不提一下 GATT (Generic Attribute Profile) 通用屬性協議。GATT是一個在藍牙連接之上的發送和接收很短的數據段的通用規范,GATT 按照層級定義了三個概念:Service、Characteristic 和描述 Descriptor,這些合起來稱為一個 Profile。
2 GAP
GAP(Generic Access Profile)通用訪問協議,用來控制設備連接和廣播。GAP 使你的設備被其他設備可見,並決定了你的設備是否可以或者怎樣與合同設備進行交互。
在 GAP 中外圍設備通過兩種方式向外廣播數據: Advertising Data Payload(廣播數據)和 Scan Response Data Payload(掃描回復),每種數據最長可以包含 31 byte。這里廣播數據是必需的,因為外設必需不停的向外廣播,讓中心設備知道它的存在。掃描回復是可選的,中心設備可以向外設請求掃描回復,這里包含一些設備額外的信息,例如設備的名字。
3 Service
Characteristic 的集合。比如某個 Service 可能叫“電量管理”,它可能包含多個Characteristics。
4 Characteristic
Characteristic 可以理解為一個數據類型,包含了一個 value 和零至多個對該 value 的描述。
5 Descriptor (可選)
對 Characteristic 的描述,例如范圍、計量單位等。
6 UUID
統一識別碼,service 和 characteristic 都需要一個唯一的 uuid 來標識, 它是 128bit 的值。
如何在小程序中使用,第一步先開啟藍牙配器。
wx.closeBluetoothAdapter({
complete: function(res) {
console.log(res)
wx.openBluetoothAdapter({
success: function(res) {
console.log(res)
wx.getBluetoothAdapterState({
success: function(res) {
console.log(res)
}
})
第二步 開始搜索附近的藍牙設備。
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
success: function(res) {
console.log(res)
that.setData({
searching: true,
devicesList: []
})
}
})
第三步 獲取附近的藍牙設備
wx.onBluetoothDeviceFound(function(devices) {
var isnotexist = true
if (devices.devices) {
if (devices.devices[0].advertisData) {
devices.devices[0].advertisData = app.buf2hex(devices.devices[0].advertisData)
} else {
devices.devices[0].advertisData = ''
}
console.log(devices.devices[0])
for (var i = 0; i < that.data.devicesList.length; i++) {
if (devices.devices[0].deviceId == that.data.devicesList[i].deviceId) {
isnotexist = false
}
}
that.data.devicesList.push(devices.devices[0])
}
that.setData({
devicesList: that.data.devicesList
})
})
},
第四步 連接藍牙
deviceId 是對應藍牙設備信息的deviceId,系統是根據這個藍牙的deviceId,去找到這個藍牙並建立連接。在前面第三步中獲取的是所有搜索到藍牙設備列表,這個是對應的某一藍牙設備的deviceId,注意: 一個藍牙有多個服務,一個服務有多個特征值,如果我們想對藍牙進行寫、讀操作,那么我們至少需要3個參數。
1、藍牙的deviceId
2、藍牙的某一服務的 uuid
3、藍牙某一服務下的某一特征值的uuid
我們至少需要這3個,才能對藍牙的某一個功能進行操作。
Connect: function(e) {
var that = this
var advertisData, name
for (var i = 0; i < that.data.devicesList.length; i++) {
if (e.currentTarget.id == that.data.devicesList[i].deviceId) {
name = that.data.devicesList[i].name
advertisData = that.data.devicesList[i].advertisData
}
}
第五步 獲取藍牙的服務
藍牙的服務是由對應藍牙設備設定的,這個是屬於硬件的設置。一個藍牙可以開啟多個服務,我們根據對應的服務操作相對應的功能。開啟主服務isPrimary的值為true,主服務是為了與其他服務區分開來,注意: 我們這里是用對應的服務uuid去區分服務的。
wx.getBLEDeviceServices({
deviceId: that.data.connectedDeviceId,
success: function(res) {
var all_UUID = res.services;
var index_uuid = -1;
var UUID_lenght = all_UUID.length;
/* 遍歷服務數組 */
for (var index = 0; index < UUID_lenght; index++) {
var ergodic_UUID = all_UUID[index].uuid; //取出服務里面的UUID
//console.log('接收到ergodic_UUID數據:' + ergodic_UUID)
if (ergodic_UUID == '00001910-0000-1000-8000-00805F9B34FB') {
index_uuid = index;
};
};
第六步 獲取藍牙對應服務的特征值
每一個不同的藍牙服務,對應的特征值也不同,當該服務的特征值為true時,我們才與之進行對應的操作,一般我們通過判斷 read 屬性是否為真,便可以知道能不能通過該服務讀取到藍牙的值,當write為真時,我們便可以對藍牙設備進行寫數據操作。
wx.getBLEDeviceCharacteristics({
deviceId: options.connectedDeviceId,
serviceId: res.services[index_uuid].uuid,
success: function(res) {
that.setData({
characteristics: res.characteristics,
})
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: options.connectedDeviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristics[1].uuid,
success: function(res) {
console.log('啟用notify成功')
},
fail(res) {
console.log(res)
}
})
}
})
}
第七步 獲取藍牙的返回數據
我們在與藍牙進行數據交互時,藍牙也常常需要對我們傳過去的參數進行相對應的回參,也就是對我們傳過去的信息進行回復,這樣我們才知道寫數據操作有沒有成功,我們需要啟用低功耗藍牙設備特征值變化時的notify 功能,用來監聽數據的返回。
wx.onBLECharacteristicValueChange(function(res) {
console.log('接收到數據:' + app.buf2string(res.value))
var time = that.getNowTime()
that.setData({
receiveText: that.data.receiveText + time + (app.buf2string(res.value))
})
})
},
接下來測試,我們編譯w800的藍牙程序,串口命令打開藍牙功能,藍牙服務:
使用微信開發者工具,導入微信小程序源碼,導入時選自己的測試號。手機微信掃描進入測試調試。
找到WM開頭的,就是我們開發板產生的藍牙,連接。
連接成功,可以收到W800發送過來的實時數據。
點擊發送可以發數據到開發板: