在网上没有微信小程序蓝牙板块特征值读取和监听的Demo,所以自己写了一个,现在分享出来,下面是Demo的页面
发送指令后(图2)在串口调试助手上正确收到相应值:
串口调试助手上发送指令,小程序也能正确监听到(图3):
Demo源码下载地址:https://download.csdn.net/download/qq_36456827/10591811
串口调试助手下载地址:https://download.csdn.net/download/qq_36456827/10591839
下面是部分源码的介绍:
wxml:
{{isConnected?'已连接':'连接蓝牙'}}
{{serviceId&&characteristicId?'已获取设备信息':'获取设备信息'}}
发送指令
断开连接
页面布局很简单,就四个按钮和一个文本框,下面主要介绍几个比较关键的js函数
onConnect() {
let that = this;
wx.openBluetoothAdapter({
success: function(res) {
if (!that.data.isConnected) {
that.startBluetoothDevicesDiscovery();//开始搜索蓝牙设备
wx.showLoading({
title: '搜索中',
})
}
},
fail: function(res) {
wx.showToast({
title: '请先开启蓝牙',
icon: 'none',
duration: 1000
})
}
});
},
onConnect()函数首先会检查用户的蓝牙是否开启,如果开启会调用startBluetoothDevicesDiscovery()函数开始搜索蓝牙设备,否则提示用户开启蓝牙
下面是连接蓝牙的函数,间歇性多次调用搜索函数(可能需要多次搜索才能搜索到相应设备),作了超时处理,这里的搜索和连接的超时时间都设置为12秒
getConnect: function() {
let that = this;
let timer = setInterval(function() {
wx.getBluetoothDevices({
success: function(res) {
console.log("devices", res);
for (var i = 0; i < res.devices.length; i++) {
if (res.devices[i].name == that.data.deviceName) {
//因为ios和安卓搜到的deviceId不一样,所以这里用设备名来查找
wx.hideLoading();
wx.showLoading({
title: '连接中',
})
that.setData({
isFinded: true,
deviceId: res.devices[i].deviceId
});
clearInterval(timer);
console.log('设备号', that.data.deviceId);
console.log("开始尝试建立连接");
wx.createBLEConnection({
deviceId: that.data.deviceId,
timeout: 12000,
success: function(res) {
console.log(res);
if (res.errCode == 0) {
console.log('连接成功')
that.setData({
isConnected: true
});
wx.stopBluetoothDevicesDiscovery();//连接成功后停止搜索
} else {
wx.showModal({
title: '提示',
content: '不能正常对蓝牙设备进行连接',
showCancel: false
})
}
},
fail: (res) => {
wx.hideLoading();
if (res.errCode == 10012) {
wx.showModal({
title: '提示',
content: '连接超时',
showCancel: false
})
}
console.warn("fail", res);
},
complete: () => {
wx.hideLoading();
}
})
break;
}
}
}
});
},3000);
setTimeout(function() {
if (!that.data.isFinded && !that.data.isConnected) {
clearInterval(timer);
that.setData({
isFailed: false
});
wx.hideLoading();
wx.showModal({
title: '提示',
content: '搜索蓝牙超时',
showCancel: false
})
}
}, 12000);
}
接下来是获取serviceId和CharacteristicId,获取到相应的id后直接对特征值进行监听
onGetuuid(){
let that = this;
if(that.data.isConnected && that.data.isFailed){
wx.showLoading({
title: '获取serviceId',
})
console.log("开始获取设备信息");
wx.getBLEDeviceServices({
deviceId: that.data.deviceId,
success(getServicesRes) {
console.log("getServicesRes", getServicesRes);
let service = getServicesRes.services[0]
let serviceId = service.uuid
wx.showLoading({
title: '获取characteristicId',
})
wx.getBLEDeviceCharacteristics({
deviceId: that.data.deviceId,
serviceId: serviceId,
success(getCharactersRes) {
console.log("getCharactersRes", getCharactersRes);
wx.hideLoading();
let characteristic = getCharactersRes.characteristics[0]
let characteristicId = characteristic.uuid
that.setData({
serviceId: serviceId,
characteristicId: characteristicId
})
console.log('成功获取uuId', that.data.serviceId, that.data.characteristicId);
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: that.data.deviceId,
serviceId: serviceId,
characteristicId: characteristicId,
success() {
console.log('开始监听特征值')
wx.onBLECharacteristicValueChange(function (onNotityChangeRes) {
console.log('监听到特征值更新', onNotityChangeRes);
let characteristicValue = that.ab2hex(onNotityChangeRes.value);
wx.showModal({
title: '监听到特征值更新',
content: `更新后的特征值(16进制格式):${characteristicValue}`,
showCancel: false
})
})
},
fail: (res) => {
console.warn("监听特征值失败");
}
})
},
fail: (err) => {
console.warn("获取特征值信息失败", err);
},
complete: (res) => {
wx.hideLoading();
}
})
},
fail: (err) => {
console.warn("获取服务信息失败", err);
},
complete: () => {
wx.hideLoading();
}
})
}else{
wx.showToast({
title: '请先连接蓝牙',
})
}
},
这里只是简单的选取了serviceId和CharacteristicId的第一个值,可根据业务需要作更改
接下来是发送指令的函数
onSendCommand() {
let that = this;
if (that.data.serviceId && that.data.characteristicId) {
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
value: that.str2ab(that.data.command),
success: function(res) {
console.log("发送指令成功");
wx.showToast({
title: '发送成功',
icon: 'none'
})
},
fail: function(res) {
console.warn("发送指令失败", res)
}
})
}else{
wx.showModal({
title: '提示',
content: '请先获取设备信息',
showCancel:false
})
}
}
需要注意的是支持发送的数据类型为ArrayBuffer,所以先要进行转码处理
str2ab(str) {
var buf = new ArrayBuffer(str.length);
var bufView = new Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i)
}
return buf
}
除此之外,BLE数据包传输规定了一次只能传输20byte,所以如果数据量较大,需要做分包传输处理
let chunkCount = Math.ceil(command.length / 18) let subCommands = []
for (let i = 0; i < chunkCount; i++) {
subCommands.push(`${chunkCount}${i}${command.substr(i * 18, 18)}`)
}//hunkCount 表示总共多少包,i表示当前是第几个包
此外,需要前一个数据包返回结果后再发送后续数据包,否则一些安卓设备会引起发送异常,对此官方文档也有相关介绍:
所以为每个数据包发送增加相应间隔(setTimeout),减少一些安卓设备发送异常:
setTimeout(function() {
send(i + 1)
}, 20)
最后附上微信小程序官方的蓝牙模块API文档:https://developers.weixin.qq.com/miniprogram/dev/api/bluetooth.html
版权声明:本文为博主原创文章,转载请注明出处