引言
蓝牙低功耗是从蓝牙 4.0 起支持的协议,与经典蓝牙相比,功耗极低、传输速度更快,但传输数据量较小。常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。
本文将详细描述微信小程序如何连接设备蓝牙以及需要注意的事宜。
微信官方文档。在遇到问题前或者你想查阅某些API的具体作用和参数、回调函数、错误状态码等可查阅 developers.weixin.qq.com/minigame/de…
连接蓝牙和搜索到蓝牙设备的前提是打开手机蓝牙和定位(包括微信中蓝牙权限和定位权限)
1、连接蓝牙入口方法
在methods中定义以下方法,以下均为按步骤定义每个步骤的方法(一步一步套娃即可)
methods: {
connectBlueTooth() {
// 2、初始化蓝牙模块方法
this.openBluetoothAdapter();
},
}
2、初始化蓝牙模块
这里需要注意iOS上开启主机/从机模式时需分别调用一次 第一次的mode为central(开启主机) 第二次的mode为peripheral(可以理解代码就是为了同时兼容安卓和ios)。
openBluetoothAdapter() {
var that = this;
wx.openBluetoothAdapter({
mode: "central", //开启主机
success: function (res) {
console.log("初始化主机模式蓝牙成功", res);
wx.openBluetoothAdapter({
mode: "peripheral", //开启从机
success: function () {
console.log("初始化从机模式蓝牙成功", res);
//3、搜索蓝牙设备
that.startBluetoothDevicesDiscovery();
},
fail: function (err) {
console.log("初始化蓝牙模块失败", err);
},
});
// 2. 开始搜索BLE设备
},
fail: function (err) {
console.log("初始化蓝牙模块失败", err);
},
});
},
3、搜索蓝牙设备
嵌入式工程师会告诉你设备的特征值(UUIDs)。需要用搜索出来的蓝牙是否与提供的UUIDs一致 搜索到目标蓝牙时你需要马上关闭蓝牙扫码搜索功能 ( 官方的解释是扫描周围蓝牙很耗性能 )
startBluetoothDevicesDiscovery() {
var that = this;
wx.startBluetoothDevicesDiscovery({
success: function (res) {
console.log("开始搜索BLE设备成功", res);
// 监听搜索到的设备
wx.onBluetoothDeviceFound(function (device) {
// 遍历搜索到的设备
if (device.devices.length) {
device.devices.forEach((item) => {
//搜到的每个设备
if (
item.advertisServiceUUIDs?.includes(
//此处需要与嵌入式工程师沟通设备的特征值
"0000FF01-****-****-****-00805F9B****"
)
) {
console.log("找到目标设备", item);
//取消扫描
wx.stopBluetoothDevicesDiscovery();
//4、连接目标蓝牙设备
that.createBLEConnection(item);
}
});
}
});
},
fail: function (err) {
console.error("开始搜索BLE设备失败", err);
},
});
},
4、连接目标蓝牙设备
createBLEConnection(item) {
var that = this;
wx.createBLEConnection({
deviceId: item.deviceId,
success: function (res) {
console.log("连接BLE设备成功", res);
// 5、获取蓝牙设备可用服务
that.getBLEDeviceServices(item);
},
fail: function (err) {
console.error("连接BLE设备失败", err);
},
});
}
5、获取蓝牙设备可用服务
getBLEDeviceServices(item) {
var that = this;
wx.getBLEDeviceServices({
deviceId: item.deviceId,
success: (res) => {
console.log("获取BLE设备服务", res);
for (let i = 0; i < res.services.length; i++) {
if (
res.services[i].isPrimary &&
//此处需要与嵌入式工程师沟通设备服务的UUID
res.services[i].uuid == "***FF01-***********"
) {
let deviceId = item.deviceId;
let serviceId = res.services[i].uuid;
//6、获取BLE设备特征值以及读写服务
that.getBLEDeviceCharacteristics(deviceId, serviceId);
}
}
},
});
},
6、获取BLE设备特征值和读写服务
这是嵌入式工程师提供的数据格式,代码块中的wifiInfo需要处理成如下16进制数据格式
代码中有很多复杂数据和业务处理与本文无关所以已被注释和简化
getBLEDeviceCharacteristics(deviceId, serviceId) {
var that = this;
wx.getBLEDeviceCharacteristics({
// 搜索到设备的 deviceId
deviceId,
// 上一步中找到的某个服务
serviceId,
success: (res) => {
console.log("搜索FF01的服务", res);
//遍历当前服务。嵌入式工程师会提供读写对应服务
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i];
setTimeout(() => {
//写
if (item.uuid == "*****FF02*********") {
// 该特征值可写 FF02写
// 本示例是向蓝牙设备发送一个 0x00 的 16 进制数据
// 实际使用时,应根据具体设备协议发送数据
var wifiInfo = `wifi:123123, 密码:123456789`;
wx.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId: item.uuid,
//这的wifiInfo根据与嵌入式沟通好wifiInfo数据格式,因为公司需求需要让设备连接wifi 我需要将当前可用wifi的账号密码通过处理后写入蓝牙特征值
value: wifiInfo,
success: function (res) {
console.log("Wi-Fi信息发送成功", res);
},
fail: function (err) {
console.log("Wi-Fi信息发送失败", err);
},
});
}
//读
if (item.uuid == "*****FF03*********") {
// 改特征值可读 FF03读
wx.readBLECharacteristicValue({
deviceId,
serviceId,
characteristicId: item.uuid,
success: function (res) {
console.log("获取读的数据: ", res);
},
});
}
}, 1000);
//通知
if (item.properties.notify) {
// 必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 onBLECharacteristicValueChange 事件
wx.notifyBLECharacteristicValueChange({
deviceId,
serviceId,
characteristicId: item.uuid,
state: true,
success: function (res) {
wx.onBLECharacteristicValueChange((result) => {
console.log(
"拿到数据: ",
result,
);
//此处我根据result判断设备 的3个步骤状态
// 1连接wifi 2设备配网 3连接服务器
// 服务器注册数据后在合适的时机断开连接和关闭蓝牙适配器
console.log("关闭蓝牙");
wx.closeBLEConnection({
deviceId,
});
wx.closeBluetoothAdapter({});
});
},
});
}
}
},
});
},