小程序低功耗蓝牙控制开门

整体流程

  1. 初始化蓝牙模块openBluetoothAdapter
  2. 获取本机蓝牙适配器状态getBluetoothAdapterState
  3. 搜索外围蓝牙设备startBluetoothDevicesDiscovery
  4. 监听寻找到新设备onBluetoothDeviceFound
  5. 连接蓝牙createBLEConnection
  6. 获取蓝牙设备的服务getBLEDeviceServices
  7. 获取服务中的特征值getBLEDeviceCharacteristics
  8. 启用特征值变化时的notify功能notifyBLECharacteristicValueChange
  9. 向蓝牙设备写入数据writeBLECharacteristicValue
  10. 关闭蓝牙模块closeBluetoothAdapter

1. 初始化蓝牙模块

  • 初始化蓝牙模块使用的是:wx.openBluetoothAdapter,初始化之前对蓝牙功能做一个判断,看手机微信版本是否支持此功能
  • 初始化之前需要关闭蓝牙模块:wx.closeBluetoothAdapter,否则容易搜索失败
var _this = this
if (!wx.openBluetoothAdapter) {wx.showModal({title: '提示',showCancel: false,content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试',})
} else {wx.closeBluetoothAdapter({success: res => {wx.openBluetoothAdapter({ // 初始化蓝牙模块success: res => {console.log('初始化蓝牙成功')_this.getBluetoothAdapterState()},fail: err => {console.log(err)}})},})
}

2. 获取本机蓝牙适配器状态

  • 获取本机蓝牙适配器状态使用的是wx.getBluetoothAdapterState,调用成功后,会返回两个参数

    • discovering判断是否正在搜索设备
    • available判断蓝牙适配器是否可用
getBluetoothAdapterState: function(){var _this = thiswx.getBluetoothAdapterState({success: res => {if (res.available == false) {wx.showToast({title: '设备无法开启蓝牙连接',icon: 'none',duration: 2000})wx.closeBluetoothAdapter()} else if (res.discovering == false) {_this.startBluetoothDevicesDiscovery() // 开启搜索外围设备} else if (res.available){_this.startBluetoothDevicesDiscovery() // 蓝牙适配器正常,去执行搜索外围设备}}})
}

3. 搜索外围蓝牙设备

  • 搜索外围蓝牙设备使用的是wx.startBluetoothDevicesDiscovery,连接设备后一定要使用wx.stopBluetoothDevicesDiscovery停止搜索
startBluetoothDevicesDiscovery: function(){var _this = thiswx.startBluetoothDevicesDiscovery({allowDuplicatesKey: false,success: res => {if(!res.isDiscovering){ // 是否在搜索设备_this.getBluetoothAdapterState()}else{_this.onBluetoothDeviceFound() // 搜索成功后,执行监听设备的api}},fail: err => {console.log("蓝牙搜寻失败")wx.stopBluetoothDevicesDiscovery() // 没有搜索到设备wx.closeBluetoothAdapter() // 关闭蓝牙模块}})
}

4. 监听寻找到新设备

  • 监听寻找到新设备使用的是wx.onBluetoothDeviceFound,每搜到一个新设备就会触发一次,然后返回一个搜索到的设备列表,包含了设备名称和mac地址,一般都是使用设备名称和mac地址来匹配设备的

    • 安卓和IOS返回的deviceId不一样,安卓返回的是mac地址,IOS返回的是UUID,如果想通过mac地址来匹配设备,可以让mac地址存储在advertisData数据段中,然后解析这个数据段得到mac地址
    • 我使用的是通过设备名称来进行匹配
onBluetoothDeviceFound: function(){var _this = thiswx.onBluetoothDeviceFound(res => {for(let i=0; i<res.devices.length; i++){if(res.devices[i].name == "设备名称" || res.devices[i].localName == "设备名称"){_this.setData({deviceId: res.devices[i].deviceId // 把匹配设备的deviceId存到data中})wx.stopBluetoothDevicesDiscovery() // 匹配到设备后关闭搜索_this.createBLEConnection() // 连接蓝牙}}})
}

5. 连接蓝牙

  • 连接蓝牙使用的是wx.createBLEConnection,连接蓝牙是通过deviceId连接,deviceId是通过wx.onBluetoothDeviceFound获取的
  • 连接蓝牙容易失败,所以可以定一个变量count用来计算连接的次数,如果超出特定的次数就判断为连接失败,关闭蓝牙模块
createBLEConnection: function () { // 连接低功耗蓝牙var _this = thiswx.createBLEConnection({deviceId: _this.data.deviceId,success: res => {_this.getBLEDeviceServices()},fail: err => {console.log("连接失败")if( count < 6 ){count++_this.createBLEConnection()}else{wx.closeBluetoothAdapter() // 连接失败关闭蓝牙模块}}})
}

6. 获取蓝牙设备的服务

  • 获取蓝牙设备的服务列表使用的是wx.getBLEDeviceServices
  getBLEDeviceServices: function () {var _this = thiswx.getBLEDeviceServices({deviceId: _this.data.deviceId,success: res => {for(let i=0; i<res.services.length; i++){// 如果提前得知可以直接判断,如果不知道可以用蓝牙工具看一下服务所需的功能if(res.services[i].uuid == _this.data.service){_this.setData({serviceId: res.services[i].uuid})_this.getBLEDeviceCharacteristics()}   }},fail: err => {console.log("获取服务失败")wx.closeBluetoothAdapter() // 关闭蓝牙模块}})},

7. 获取服务中的特征值

  • 获取服务中的特征值使用的是wx.getBLEDeviceCharacteristics
  getBLEDeviceCharacteristics: function () { // 获取服务中的特征值var _this = thiswx.getBLEDeviceCharacteristics({deviceId: _this.data.deviceId,serviceId: _this.data.serviceId,success: res => {for(let i=0; i<res.characteristics.length; i++){let model = res.characteristics[i]if ((model.properties.notify || model.properties.indicate) && (model.properties.read && model.properties.write)){_this.setData({characteristicId: model.uuid})_this.notifyBLECharacteristicValueChange()}}},fail: err => {console.log("获取服务中的特征值失败")wx.closeBluetoothAdapter() // 关闭蓝牙模块}})},

8. 启用特征值变化时的notify功能

  • 启用特征值变化时的notify功能使用的是wx.notifyBLECharacteristicValueChange
notifyBLECharacteristicValueChange: function () { // 启用蓝牙特征值变化时的notify功能var _this = thiswx.notifyBLECharacteristicValueChange({deviceId: _this.data.deviceId,serviceId: _this.data.serviceId,characteristicId: _thisa.characteristicId,state: true,success: res => {wx.onBLECharacteristicValueChange(res => {console.log(如果要打印需要从arraybuffer格式转为字符串或16进制)})_this.writeBLECharacteristicValue() // 向蓝牙设备写入数据},fail: err => {console.log("启用BLE蓝牙特征值变化时的notify功能错误")wx.closeBluetoothAdapter() // 关闭蓝牙模块}})

9. 向蓝牙设备写入数据

  • 向蓝牙设备写入数据wx.writeBLECharacteristicValue,这时候就是输入提前设定好的指令
  writeBLECharacteristicValue: function () { // 向蓝牙设备写入数据var _this = thiswx.writeBLECharacteristicValue({deviceId: _this.data.deviceId,serviceId: _this.data.serviceId,characteristicId: _this.data.characteristicId,value: buffer, // 这个输入的指令,需要转换成ArrayBuffersuccess: res => {console.log("成功")wx.closeBluetoothAdapter() // 关闭蓝牙模块},fail: err => {console.log("输入指令失败")wx.closeBluetoothAdapter() // 关闭蓝牙模块}})}

转换格式

  • 字符串转为arraybuffer
string2buffer: function (str) {// 首先将字符串转为16进制let val = ""for (let i = 0; i < str.length; i++) {if (val === '') {val = str.charCodeAt(i).toString(16)} else {val += ',' + str.charCodeAt(i).toString(16)}}// 将16进制转化为ArrayBufferreturn new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {return parseInt(h, 16)})).buffer
}
  • arraybuffer转为字符串
function ab2str(u,f) {var b = new Blob([u]);var r = new FileReader();r.readAsText(b, 'utf-8');r.onload = function (){if(f)f.call(null,r.result)}
}

蓝牙遇见的坑

  • 1.苹果手机有时候输入指令会显示发送成功,但是设备并没有反应

    • 解决方法:把需要输入的指令改成每10毫秒输入一个字节
    • 如果改成每10毫秒输入一个字节,安卓手机就会频繁出现10008错误
    • 针对这个问题我用了一个不太好的方法,我判断了一下手机的类型,如果是ios的就分10毫秒输入,如果是安卓的就一次性输入
  • 2.在调用wx.onBluetoothDeviceFound这个api时ios会监听两次,然后就会导致最后设备会有两次指令输入
    • 解决方法:我在搜索蓝牙设备之前做了一个定时器,然后用getBluetoothDevices来查看所有已搜索到的蓝牙,在这个里面做判断来连接蓝牙设备
  • 我上面的步骤没有把这些坑的解决步骤加上,如果碰见此类问题,可以自己在合适的位置修改一下

二维码

我自己做了一个小程序的蓝牙调试器,下面是小程序码,欢迎大家体验

微信小程序蓝牙控制开门相关推荐

  1. 泰凌微ble mesh蓝牙模组天猫精灵学习之旅 ② 如何实现 微信小程序蓝牙控制 Ble Mesh模组 安信可TB02,全部开源!

    本<泰凌微ble mesh蓝牙模组天猫精灵学习之旅>系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1.小 ...

  2. 【微信小程序控制硬件 第12篇-项目篇】微信小程序蓝牙控制硬件应如何开始动手?为您全面解析微信小程序蓝牙API的使用;(附带demo)

    [微信小程序控制硬件第1篇 ] 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件! [微信小程序控制硬件第2篇 ] 开始微信小程序之旅,导入小程序Mqtt客户 ...

  3. 【微信小程序控制硬件14 】 微信小程序蓝牙+WiFi双控制ESP32-C3应用示范;(附带Demo)

    文章目录 一.前言 二.设备核心代码 2.1 蓝牙控制 2.2 WiFi控制 2.3 外设驱动 三.微信小程序核心代码 3.1 蓝牙搜索 3.2 蓝牙服务发现 四.感谢 另外,不要把我的博客作为学习标 ...

  4. 标签云打印/微信小程序蓝牙标签打印开放平台功能

    ​微信小程序蓝牙标签打印/标签云打印开放平台(www.herro.cn),是在云端部署的云平台,支持开发者通过API调用完成标签蓝牙打印或标签云打印功能. 平台蓝牙打印模块支持各厂商各品牌蓝牙标签打印 ...

  5. 微信小程序蓝牙ibeacon_微信开放蓝牙iBeacon接口小程序靠近原生APP功能

    腾讯一直要连接一切,特别是新的物联网浪潮涌来的时候,不管大众重视程度与否,微信已经又走在了我们前面.在物联网中最基础最通用的当属每个人手机上都具有的蓝牙功能.所以,继2014年微信开放了基于低功耗蓝牙 ...

  6. 微信小程序蓝牙BLE开发——关于进制转换(四)

    微信小程序蓝牙BLE开发--进制转换 这段时间开发共享设备,对接蓝牙BLE设备通信协议,过程中用到一些进制转换, 记录下方便使用. 有些参考大神们,感谢分享. 文章目录 微信小程序蓝牙BLE开发--进 ...

  7. 微信小程序蓝牙BLE开发实战——案例(二)

    微信小程序蓝牙BLE开发实战(二) 上篇主要介绍在开发过程中应用到相关API操作.接下来介绍个人在项目开发中应用蓝牙BLE一些事情. 由于时间比较仓促, 有些注释没那么详细.请理解~写的不好欢迎各位大 ...

  8. 【TB-02模组专题③】微信小程序蓝牙通讯 Ble 蓝牙Mesh TB02模组;

    本<安信可ble mesh蓝牙模组TB-02模组专题>系列博客学习由官方博客 CSDN安信可博客 潜心所力所写.如有不对之处,请留言,我们及时更改. 1.BLE MESH开发环境linux ...

  9. wx.getBLEDeviceCharacteristics 微信小程序蓝牙 微信小程序热敏打印机

    1 微信小程序蓝牙功能开发概述 第一步 判断当前微信版本,是否支持蓝牙 通信 第二步 打开蓝牙 第三步扫描设备 第四步连接设备 第五步 获取服务与特征值 看是否支持读写数据操作 第六步 发送数据 本文 ...

  10. 微信小程序蓝牙模块BLE开发说明基础知识

    微信小程序蓝牙模块说明 一.简介 微信小程序作为轻量级应用的载体,确实方便了很多的应用场景.传统的产品如果要和手机互联互通,那么必须要开发两套APP,即IOS和安卓.十分的麻烦和成本巨高.但是微信小程 ...

最新文章

  1. 机房管理系列之文件服务器管理
  2. excel 怎么让数字不用科学计数法
  3. 阿里BCG重磅报告《人工智能,未来致胜之道》
  4. 系统消息是放客户端还是服务器,系统消息是放客户端还是服务器
  5. Linux Shell常用技巧(九) 系统运行进程
  6. 用为知发布博客到博客园、使用Wiz编写和发布博客园(cnblogs)博客
  7. P2278-[HNOI2003]操作系统【堆】
  8. 使用MRUnit测试Hadoop程序
  9. SVN使用过程中遇到的一些问题
  10. 已知段地址,求CPU寻址范围
  11. xml-treeview转换
  12. 【springboot基础】配置日志输出级别以及输出位置
  13. redhat怎样修改语言_硕士博士个人陈述(PS)辅导及修改服务带你极速前进!
  14. 【openjudge】 CDQZ challenge 4
  15. 作为餐饮店长最需要什么能力?
  16. perl删除文件_Perl小知识语法重点和数据类型
  17. JAVA-JSP内置对象之request获得所有的参数名称
  18. R语言读取Excel的神器——openxlsx
  19. Three.js地图轮廓分割效果
  20. 20110609 WindowsLive Writer插件 测试

热门文章

  1. 眼睛容易干燥疲劳怎么办?
  2. electron 读取文件夹内容_读写本地文件
  3. 技能提升----直流有刷电机控制方案之经典
  4. html编辑器菜鸟工具,富文本编辑器TinyMCE菜鸟使用教程
  5. 在计算机操作中粘贴的快捷键是什么,电脑复制粘贴的快捷键是什么
  6. keras实现声音二分类
  7. 2020年书法落款_书法落款时间查询表整理,太赞了
  8. mma7660(gsensor)的hwmon驱动
  9. 3种方法设置PPT文件保护
  10. 第5章、解析Hello,world!知其然,更要知其所以然(从零开始学Android)