微信WX小程序連電子秤及稱重設(shè)備的藍(lán)牙調(diào)取連接讀取數(shù)據(jù)相關(guān)代碼及說(shuō)明小程序藍(lán)牙親身總結(jié)
問(wèn)題:
1.小程序藍(lán)牙搜索能不能搜到手機(jī)設(shè)備
2.如何判斷藍(lán)牙是否打開(kāi)
3.搜索指定設(shè)備
4.開(kāi)發(fā)者工具和 Android 上獲取到的deviceId為設(shè)備 MAC 地址,iOS 上則為設(shè)備 uuid。因此deviceId不能硬編碼到代碼中,如何連接藍(lán)牙
5.serviceId如何去選擇
6.characteristic(特征值)干嘛的,怎么用
7.開(kāi)啟notify
8.如何寫入數(shù)據(jù)
---------------------
原文:https://blog.csdn.net/caohoucheng/article/details/81633822
問(wèn)題:
最近做了一個(gè)涉及到藍(lán)牙模塊小程序,做一下總結(jié),為自己的成長(zhǎng)做一份記錄,如果能幫到大家的話是再好不過(guò)的了;
1.小程序藍(lán)牙搜索能不能搜到手機(jī)設(shè)備
2.如何判斷藍(lán)牙是否打開(kāi)
3.搜索指定設(shè)備
4.開(kāi)發(fā)者工具和 Android 上獲取到的deviceId為設(shè)備 MAC 地址,iOS 上則為設(shè)備 uuid。因此deviceId不能硬編碼到代碼中,
如何連接藍(lán)牙
5.設(shè)備服務(wù)所有 service(服務(wù)) 如何去選擇
6.設(shè)備characteristic(特征值)干嘛的,怎么用
7.開(kāi)啟notify
8.寫入數(shù)據(jù)
1.小程序藍(lán)牙搜索能不能搜到手機(jī)設(shè)備
搜不到!!!
小程序藍(lán)牙只支持BLE低功耗藍(lán)牙
什么是低功耗藍(lán)牙設(shè)備呢?百度一下,你就知道(^__^) 嘻嘻
2.如何判斷藍(lán)牙是否打開(kāi)
利用wx.openBluetoothAdapter(OBJECT)判斷藍(lán)牙是否可用
在用戶藍(lán)牙開(kāi)關(guān)未開(kāi)啟或者手機(jī)不支持藍(lán)牙功能的情況下,調(diào)用wx.openBluetoothAdapter會(huì)返回錯(cuò)誤,表示手機(jī)藍(lán)牙功能不可用;
wx.openBluetoothAdapter({
success: function (res) {
console.log(res)
},
fail: function (res) {
wx.showModal({
content: '請(qǐng)開(kāi)啟手機(jī)藍(lán)牙后再試'
})
}
})
注意:建議wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成對(duì)使用
wx.closeBluetoothAdapter:關(guān)閉藍(lán)牙模塊,使其進(jìn)入未初始化狀態(tài)。調(diào)用該方法將斷開(kāi)所有已建立的鏈接并釋放系統(tǒng)資源;
3.搜索指定設(shè)備
wx.startBluetoothDevicesDiscovery(OBJECT)開(kāi)始搜尋附近的藍(lán)牙外圍設(shè)備
wx.getBluetoothDevices(OBJECT)獲取在小程序藍(lán)牙模塊生效期間所有已發(fā)現(xiàn)的藍(lán)牙設(shè)備
wx.onBluetoothDeviceFound(CALLBACK) 監(jiān)聽(tīng)尋找到新設(shè)備的事件
注意:搜索藍(lán)牙wx.startBluetoothDevicesDiscovery(OBJECT)操作比較耗費(fèi)系統(tǒng)資源,在搜索并連接到設(shè)備后調(diào)用 wx.stopBluetoothDevicesDiscovery(OBJECT) 方法停止搜索。
//開(kāi)始搜索藍(lán)牙
wx.startBluetoothDevicesDiscovery({
success: function (res) {
console.log('search', res)
}
})
//發(fā)現(xiàn)設(shè)備
wx.getBluetoothDevices({
success: function (res) {
console.log('發(fā)現(xiàn)設(shè)備', res)
if (res.devices[0]) {
console.log(that.ab2hext(res.devices[0].advertisData))
}
//5s內(nèi)未搜索到設(shè)備,關(guān)閉搜索,關(guān)閉藍(lán)牙模塊
setTimeout(function(){
if (!that.data.deviceId){
wx.hideLoading()
app.showToast('搜索設(shè)備超時(shí)','none');
//關(guān)閉搜索
that.stopBluetoothDevicesDiscovery();
//關(guān)閉藍(lán)牙
that.closeBluetoothAdapter();
}
},5000)
}
})
//監(jiān)聽(tīng)發(fā)現(xiàn)設(shè)備
wx.onBluetoothDeviceFound(function (devices) {
console.log('發(fā)現(xiàn)設(shè)備:', devices.devices)
for (let i = 0; i < devices.devices.length; i++) {
//檢索指定設(shè)備
if (devices.devices[i].name == '設(shè)備name') {
that.setData({
deviceId: devices.devices[i].deviceId
})
//關(guān)閉搜索
that.stopBluetoothDevicesDiscovery();
console.log('已找到指定設(shè)備:', devices.devices[i].deviceId);
}
}
})
ab2hext: function(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
這段代碼是通過(guò)設(shè)備名name去匹配配對(duì)設(shè)備,若5s內(nèi)未搜到指定設(shè)備則關(guān)閉搜索,關(guān)閉藍(lán)牙模塊;
設(shè)備名是已發(fā)現(xiàn)的藍(lán)牙設(shè)備device 對(duì)象中的name
4.開(kāi)發(fā)者工具和 Android 上獲取到的deviceId為設(shè)備 MAC 地址,iOS 上則為設(shè)備 uuid。因此deviceId不能硬編碼到代碼中,如何連接藍(lán)牙
搜索我們可以拿到了設(shè)備的deviceId,通過(guò)deviceId去連接藍(lán)牙
Android 上獲取到的deviceId為設(shè)備 MAC 地址,iOS 上獲取到的deviceId則為設(shè)備 uuid,因此deviceId不能硬編碼到代碼中
那么可能就有機(jī)智的小伙伴說(shuō)了,設(shè)置兩個(gè)變量,一個(gè)為設(shè)備MAC,一個(gè)為設(shè)備uuid
在連接設(shè)備的之前判斷下機(jī)型,ios設(shè)備deviceId取:設(shè)備uuid,android設(shè)備deviceId:MAC地址!!!
我原本也是這樣想的,因?yàn)槲覀冏龅倪@個(gè)小程序是掃碼連接指定設(shè)備(就好像共享單車一樣),所以本來(lái)是想在二維碼中直接放入mac和uuid然后連接的時(shí)候去根據(jù)機(jī)型去取對(duì)應(yīng)值
但是!!!但是!!!但是!!!
在實(shí)現(xiàn)過(guò)程中發(fā)現(xiàn),ios不同手機(jī)搜索到的設(shè)備deviceId還是不同的.
所以還是乖乖通過(guò)設(shè)備name(廣播名),去獲取deviceId去連接
只怪自己經(jīng)驗(yàn)不足,還總想走捷徑
正確的流程是
初始化藍(lán)牙wx.openBluetoothAdapter(OBJECT)
↓
開(kāi)始搜索藍(lán)牙 wx.startBluetoothDevicesDiscovery(OBJECT)
↓
所有已發(fā)現(xiàn)的藍(lán)牙設(shè)備wx.getBluetoothDevices(OBJECT)
↓
監(jiān)聽(tīng)尋找到新設(shè)備的事件wx.onBluetoothDeviceFound(CALLBACK)
↓
連接低功耗藍(lán)牙設(shè)備wx.createBLEConnection(OBJECT)
↓
獲取藍(lán)牙設(shè)備所有 service(服務(wù)) wx.getBLEDeviceServices(OBJECT)
↓
獲取藍(lán)牙設(shè)備某個(gè)服務(wù)中的所有 characteristic(特征值)wx.getBLEDeviceCharacteristics(OBJECT)
↓
啟用低功耗藍(lán)牙設(shè)備特征值變化時(shí)的 notify 功能wx.notifyBLECharacteristicValueChange(OBJECT)
↓
寫入wx.writeBLECharacteristicValue(OBJECT)
在搜索到設(shè)備后通過(guò)拿到的設(shè)備的deviceId去連接設(shè)備
wx.createBLEConnection({
deviceId: that.data.deviceId,//搜索設(shè)備獲得的藍(lán)牙設(shè)備 id
success: function (res) {
console.log('連接藍(lán)牙:', res.errMsg);
},
fail: function (res) {
app.showToast('連接超時(shí),請(qǐng)重試或更換車輛', 'none');
that.closeBluetoothAdapter();
}
})
5.serviceId如何去選擇
連接成功以后就可以去獲取設(shè)備的服務(wù)列表,我這邊拿的是FEE7的服務(wù)ID
wx.getBLEDeviceServices({
deviceId: that.data.deviceId,//搜索設(shè)備獲得的藍(lán)牙設(shè)備 id
success: function (res) {
let service_id = "";
for(let i = 0;i<res.services.length;i++){
if(services[i].uuid.toUpperCase().indexOf("FEE7") != -1){
service_id = services[i].uuid;
break;
}
}
console.log('fee7-service_id:', that.data.service_id);
},
fail(res){
console.log(res);
}
})
6.characteristic(特征值)干嘛的,怎么用
服務(wù)特征值是干嘛的:每個(gè)服務(wù)都包含了一組特征值用來(lái)描述服務(wù)的一些屬性,獲取是否可讀,是否可寫,是否可以開(kāi)啟notify通知等,當(dāng)你跟藍(lán)牙通信時(shí)需要這些特征值ID來(lái)傳遞數(shù)據(jù)。
服務(wù)特征值怎么用:
//獲取特征值
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,//搜索設(shè)備獲得的藍(lán)牙設(shè)備 id
serviceId: that.data.service_id,//服務(wù)ID
success: function (res) {
console.log('device特征值:', res.characteristics)
for (let i = 0; i < res.characteristics.length; i++) {
let charc = res.characteristics[i];
if (charc.properties.indicate) {
that.setData({indicate_id: charc.uuid});
console.log('indicate_id:', that.data.indicate_id);
}
if (charc.properties.write) {
that.setData({write_id: charc.uuid});
console.log('寫write_id:', that.data.write_id);
}
if (charc.properties.read) {
that.setData({read_id: charc.uuid});
console.log('讀read_id:', that.data.read_id);
}
}
}
});
篩選出你所需要的服務(wù)特征值
在得到對(duì)應(yīng)特征值后可以在執(zhí)行相關(guān)操作時(shí)使用
例如:
開(kāi)啟notify:必須設(shè)備的特征值支持notify或者indicate才可以成功調(diào)用
支不支持notify或者indicate就是我們上面篩選出來(lái)的對(duì)應(yīng)值
if (charc.properties.indicate) {
that.setData({indicate_id: charc.uuid});
console.log('indicate_id:', that.data.indicate_id);
}
7.開(kāi)啟notify
開(kāi)啟notify后可以監(jiān)聽(tīng)低功耗藍(lán)牙設(shè)備的特征值變化。必須先啟用notify接口才能接收到設(shè)備推送的notification
//開(kāi)啟notify
wx.notifyBLECharacteristicValueChange({
state: true, // 啟用 notify 功能
deviceId: that.data.deviceId,//藍(lán)牙設(shè)備id
serviceId: that.data.service_id,//服務(wù)id
characteristicId: that.data.indicate_id,//服務(wù)特征值indicate
success: function (res) {
console.log('開(kāi)啟notify', res.errMsg)
//監(jiān)聽(tīng)低功耗藍(lán)牙設(shè)備的特征值變化
wx.onBLECharacteristicValueChange(function (res) {
console.log('特征值變化', that.arrayBufferToHexString(res.value));
})
//寫入數(shù)據(jù)
}
});
8.如何寫入數(shù)據(jù)
如何寫入數(shù)據(jù)呢,通過(guò)獲取到的write特征值write_id
注意:必須設(shè)備的特征值支持write才可以成功調(diào)用
let buffer = that.hexStringToArrayBuffer(ArrayBuffer);
//寫入數(shù)據(jù)
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,//設(shè)備deviceId
serviceId: that.data.service_id,//設(shè)備service_id
characteristicId: that.data.write_id,//設(shè)備write特征值
value: buffer,//寫入數(shù)據(jù)
success: function (res) {
console.log('發(fā)送數(shù)據(jù):', res.errMsg)
}
});
hexStringToArrayBuffer:function (str) {
if(!str) {
return new ArrayBuffer(0);
}
var buffer = new ArrayBuffer(str.length);
let dataView = new DataView(buffer)
let ind = 0;
for (var i = 0, len = str.length; i < len; i += 2) {
let code = parseInt(str.substr(i, 2), 16)
dataView.setUint8(ind, code)
ind++
}
return buffer;
}
總結(jié):有幾點(diǎn)特別需要注意,快拿出小本本
1.IOS里面藍(lán)牙狀態(tài)變化以后不能馬上開(kāi)始搜索,否則會(huì)搜索不到設(shè)備,必須要等待2秒以上
2.開(kāi)啟notify以后并不能馬上發(fā)送消息,藍(lán)牙設(shè)備有個(gè)準(zhǔn)備的過(guò)程,需要在setTimeout中延遲1秒以上才能發(fā)送,否則會(huì)發(fā)送失敗
setTimeout(function () {
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.service_id,
characteristicId: that.data.write_id,
value: buffer,
success: function (res) {
console.log('發(fā)送數(shù)據(jù):', res.errMsg)
}
});
}, 1100);
3.搜索到設(shè)備后記得釋放資源stopBluetoothDevicesDiscovery
4.不需要使用藍(lán)牙的時(shí)候一定要關(guān)閉藍(lán)牙.wx.openBluetoothAdapter(OBJECT)和wx.closeBluetoothAdapter(OBJECT)成對(duì)使用
---------------------
作者:Cc_JoJo
來(lái)源:CSDN
原文:https://blog.csdn.net/caohoucheng/article/details/81633822
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
聯(lián)系人:黃金
手 機(jī):153 0755 0221
郵 箱:jane@dzc.hk
公 司:深圳市山星盛電子科技有限公司-稱重產(chǎn)品官方展示網(wǎng)站
地 址:廣東省深圳市寶安鳳塘大道25號(hào)(山星盛電子秤)