项目场景:
提示:这里简述项目相关背景:
微信小程序连接电子秤【品牌:弓正】
流程:
- 初始化
- 搜索蓝牙设备
- 获取蓝牙设备信息
- 连接蓝牙设备
- 获取蓝牙设备所有的服务
- 获取蓝牙设备特征值
- 监听蓝牙设备特征值变化
注意:
这里我踩了两个坑
蓝牙设备主 service 的 uuid不要使用变量存起来,建议直接用函数传参的方式传入。
在启用notify订阅特征值功能后,先延时1s,2s,在调用监听变化的函数
代码:
// 初始化蓝牙设备
initBlue() {
uni.openBluetoothAdapter({
success:(res)=> {
// 去搜索
this.findBlue();
},
fail:()=> {
//如果手机上的蓝牙没有打开,可以提醒用户
uni.showToast({
title: '请开启蓝牙',
icon: 'none',
duration: 1000
});
}
});
},
// 搜索蓝牙设备
findBlue() {
uni.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false,
interval: 0,
success:(res)=> {
uni.showLoading({
title: '正在搜索设备',
mask: true
});
// 获取搜索结果的设备信息
this.getBlue();
}
});
},
// 获取搜索结果的设备信息
getBlue() {
uni.getBluetoothDevices({
success:(res)=> {
console.log('设备信息', res.devices);
},
fail: function() {
console.log('搜索蓝牙设备失败');
}
});
},
提示
因为我连接的蓝牙秤,厂家说的是有固定前缀名称,所以我直接用名称搜索,你看你需要啥就用啥。
注意
可能只是这个厂家的秤,安卓和ios搜索出来不一致,所以这里我做了两个判断。
场景是:多可能会有多台蓝牙秤,所有这里会有一个list。如果你只有一台蓝牙电子秤,就不用存入list,直接
// this.connetBlue(设备id)
getBlue() {
uni.getBluetoothDevices({
success: function(res) {
console.log('设备信息', res.devices);
//res.devices.deviceId 设备id
// this.connetBlue(设备id)
this.ming = []
this.lanyalist = []
let ming = []
let lanyalist = []
res.devices.map(v => {
let reg = new RegExp('RFstar_') // 设备名称前缀
if (v.name !== undefined) {
if(v.name.match(reg)){
ming.push(v.name)
lanyalist.push(v)
}
}
else if(v.localName !== undefined) {
if(v.localName.match(reg)){
ming.push(v.localName)
lanyalist.push(v)
}
} else {
uni.showToast({
title: '没有找到可用设备',
icon: 'none'
})
}
});
this.ming = ming
this.lanyalist = lanyalist
uni.hideLoading();
},
fail: function() {
console.log('搜索蓝牙设备失败');
}
});
},
// 获取到设备之后连接蓝牙设备
connetBlue(deviceId) {
uni.createBLEConnection({
deviceId: deviceId, //设备id
success: function(res) {
uni.showToast({
title: '连接成功',
icon: 'fails',
duration: 800
});
this.getServiceId(deviceId)
uni.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log('连接蓝牙成功之后关闭蓝牙搜索');
}
});
}
});
},
// 获取蓝牙设备所有服务
getServiceId(deviceId) {
uni.getBLEDeviceServices({
deviceId: deviceId,
success: (res)=> {
console.log('服务', res);
this.getCharacteId(deviceId, res.services[2].uuid);
}
});
},
注意
不是每一个uuid的服务都能监听,这里需要看蓝牙秤的文档。
获取监听值,需要先连接蓝牙秤,称重点击蓝牙秤上面的按钮,“完成”按钮或者是“打印”按钮,【具体看厂商给的文档】然后才能获取到监听值
// 获取特征值
getCharacteId(deviceId, serviceId) {
uni.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: serviceId,
success:(res)=> {
console.log('特征值', res);
res.characteristics.map(v => {
if (v.properties.notify==true) {
this.notifyId = v.uuid; //监听的值
this.startNotice(deviceId, serviceId,v.uuid);
}
});
}
});
},
// 监听值需要延迟几秒
startNotice(deviceId, serviceId,uuid) {
setTimeout(()=> {
uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: deviceId,
serviceId: serviceId,
characteristicId: uuid,
success: (res)=> {
console.log(res)
// 监听低功耗蓝牙设备的特征值变化事件。
uni.onBLECharacteristicValueChange(function(data) {
console.log('特征值变化', data);
});
},
fail: (err) => {
console.log('错误',err)
}
});
},2000)
},
‘特征值变化’, data大概长这样
这里需要转码
ab2hex(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},