
最近我在为我的微信小程序新增物联网通信功能时,添加了蓝牙通信功能。看了很多资料和教程,我终于写出了一个差不多能实现的微信小程序蓝牙通信功能。
但是,由于我的知识水平有限,我急急忙忙的将小程序提交审核上线后,遇到了iOS设备无法正常连接蓝牙通信的问题。经过两天的调试,我终于解决了这个问题。原来,在iOS上,微信小程序无法通过MAC地址来连接设备,并且一些方法的执行顺序和时间间隔也需要遵循特定的规则。这个问题揭示了许多其他问题,不得不让我重新编写之前的代码。
实际上,对于初学者来说,理解蓝牙通信仍然是一件困难的事情。尤其是在我之前对蓝牙通信领域没有任何了解的情况下,完成一个项目确实需要一定的基础知识,不能急于求成。
废话少说,接下来我将简单说明如何在小程序中实现蓝牙连接并发送数据。
1、关闭蓝牙
可能很多人好奇,为什么第一步是关闭蓝牙呢?其实这个坑还是微信挖的(微信开发者社区:https://developers.weixin.qq.com/community/develop/doc/000a6287404ee8c64f8888fa056800),可以看链接提到的问题,具体不好说清楚,但是在做连接之前,最好还是先关闭一下蓝牙,因为这个操作不会花费太多时间。
wx.closeBluetoothAdapter({
success: function(res) {
console.log("断开连接")
}
})2、初始化蓝牙适配器
初始化蓝牙适配器,即在使用蓝牙功能之前先进行初始化,判断设备是否支持蓝牙并且蓝牙是否已开启,否则会报错。我们使用wx.openBluetoothAdapter来执行初始化操作。如果成功,则说明蓝牙功能正常;如果失败,则说明蓝牙不可用(可以弹出一个提示框告知用户)。
此处可以设置一个5秒的延迟函数,在5秒后检查是否找到了指定设备。如果未找到,则提示设备未找到,并停止蓝牙扫描。
wx.openBluetoothAdapter({
success: function(res) {
//蓝牙正常
ble_isok=1;
},
fail(res) {
//蓝牙异常
},
complete(res) {
//这里是蓝牙开启后要干的事情
if (ble_isok == 1) {//这里判断一下蓝牙正不正常,正常才继续执行
//下一步
}
}
})这里,我们可以设定一个5s的延时执行函数,5s后看一下有没有找到我们的设备,如果没有找到,那就报设备没有找到,然后停止蓝牙。
fxble_isfound = 0; //初始化默认没有找到
fxble_startsearch(); //开始搜索周围的蓝牙设备,这里是下一个步骤
setTimeout(function () {
if (fxble_isfound == 0) {
// 代表搜不到设备
console.log("搜索不到设备");
wx.showToast({
title: "搜索不到设备",
icon: "none",
duration: 2000,
mask: true //是否有透明蒙层,默认为false
});
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log("停止搜索");
}
});
wx.closeBluetoothAdapter({
success: function (res) {
console.log("断开连接");
}
});
}
}, 5000);这样,我们就比较完美做好了初始化。
3、扫描周围的蓝牙设备,并通过一些方法来获取指定设备的serviceID
需要注意的是,Android和iOS的serviceID是不同的。Android使用MAC地址作为serviceID,而iOS使用UUID作为serviceID。而且这个UUID并不是固定的,不同设备可能不相同。之前我写的代码直接将serviceID写死了,肯定会出现兼容性问题。
这里对应你提到的fxble_startsearch()函数。由于我比较懒,没有修改ESP32上的代码来通过蓝牙广播中的特殊值判断设备,而是直接根据蓝牙设备的名称来判断。虽然这种方式并不完美,但在我的生产环境中已经足够。
wx.startBluetoothDevicesDiscovery({
services: [],
success(res) {
wx.onBluetoothDeviceFound(res => {
var devices = res.devices;
for (let i = 0; i < devices.length; i++) {
if (devices[i].localName == "你要找的设备名字") {
fxble_isfound = 1; // 标记设备找到了
deviceId = devices[i].deviceId; // 我这种方法的话其实这句可有可无的
console.log("find" + deviceId);
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
console.log("停止搜索");
}
});
wx.showToast({
title: '设备搜索成功',
icon: 'loading',
duration: 2000,
mask: true // 是否有透明蒙层,默认为false
});
fxble_connect(); // 接着下一个阶段
return 0;
}
}
});
},
fail(res) {
console.log(res);
return 0;
}
});4、连接蓝牙设备
这里我们先使用wx.createBLEConnection来连接到指定的蓝牙设备,然后wx.getBLEDeviceServices获取serviceID,notify_id,write_id,read_id(其实写数据的话,只要write_id就可以了)。
对应fxble_connect()函数。
wx.createBLEConnection({
deviceId: deviceId, // 获取到的 deviceID
success(res) {
console.log("设备连接成功!");
wx.showToast({
title: '设备连接成功',
icon: 'loading',
duration: 2000,
mask: true // 是否有透明蒙层,默认为false
});
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function(res) {
console.log("设备加载成功");
wx.showToast({
title: '设备加载成功',
icon: 'loading',
duration: 2000,
mask: true // 是否有透明蒙层,默认为false
});
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].uuid.toUpperCase().indexOf(service_id) != -1) {
service_id = res.services[i].uuid;
break;
}
}
console.log("Find Services" + service_id);
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: service_id,
success: function(res) {
console.log("设备加载成功");
for (let i = 0; i < res.characteristics.length; i++) {
let charc = res.characteristics[i];
if (charc.properties.notify) {
notify_id = charc.uuid;
}
if (charc.properties.write) {
write_id = charc.uuid;
}
if (charc.properties.write) {
read_id = charc.uuid;
}
}
console.log("Find notify_id" + notify_id + ", write_id" + write_id + ", read_id" + read_id);
setTimeout(function() {
fxble_write(); // 下一阶段,写数据
}, 1000);
},
fail(res) {
console.log(res);
}
});
},
fail(res) {
console.log(res);
return 0;
}
});
},
fail(res) {
console.log(res);
wx.showToast({
title: '设备连接失败',
icon: 'none',
duration: 2000,
mask: true // 是否有透明蒙层,默认为false
});
return 0;
}
});5、写入数据
其实已经快接近尾声了,这里有个难点就是要把字符串转换一下对应的格式(字符串转byte),然后传入buffer,不能直接发送。
对应上面的fxble_write()。
let order = stringToBytes(writetext);
let byteLength = order.byteLength;
wx.writeBLECharacteristicValue({
deviceId: deviceId,
serviceId: service_id,
characteristicId: write_id,
value: order.slice(0, 20),
success: function(res) {
// 成功
fxble_close(); // 下一阶段,关闭连接
},
fail(res) {
console.log(res);
wx.showToast({
title: '请求发送失败!',
icon: 'none',
duration: 2000,
mask: true // 是否有透明蒙层,默认为false
});
}
});
// 字符串转byte
function stringToBytes(str) {
var strArray = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
strArray[i] = str.charCodeAt(i);
}
const array = new Uint8Array(strArray.length);
strArray.forEach((item, index) => array[index] = item);
return array.buffer;
}6、关闭连接
做完所有操作之后,就要关闭连接了,以免资源占用,常规操作了。文章来源:https://www.toymoban.com/article/594.html
wx.closeBLEConnection({
deviceId: deviceId,
success(res) {
console.log("断开连接成功");
},
fail(res) {
console.log(res);
console.log("断开连接失败");
}
});
wx.closeBluetoothAdapter({
success: function (res) {
console.log("断开成功");
}
});补充
连接成功后,我们可以通过task.write方法向蓝牙设备发送数据。需要注意的是,由于蓝牙通信的特性,一次最多只能发送20个字节的数据。如果要发送更大的数据量,需要分包发送。文章来源地址https://www.toymoban.com/article/594.html
task.write({
value: data, // 要发送的数据(最多20个字节)
success: function(res) {
console.log("数据发送成功");
// 数据发送成功后的操作
},
fail: function(err) {
console.log("数据发送失败", err);
// 数据发送失败后的处理
}
});到此这篇关于在微信小程序中如何通过蓝牙BLE连接ESP32并发送数据的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!













