乐趣区

微信小程序连接蓝牙设备并传递数据体脂秤

流程

流程图

分步详解

wx.getSystemInfo(Object object) 获取系统信息 获取操作系统及版本 页面加载的时候(或者 app.js 中)

初始化蓝牙模块 wx.openBluetoothAdapter(Object object)

在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,通过错误码(errCode=10001),提示打开蓝牙或蓝牙功能不可用。此时小程序蓝牙模块已经初始化完成,可通过 wx.onBluetoothAdapterStateChange监听手机蓝牙是否可用或是否在搜索状态。

关闭蓝牙模块 wx.closeBluetoothAdapter。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,以及onhideonUnload

开始搜索蓝牙 wx.startBluetoothDevicesDiscovery(OBJECT) 开始搜寻附近的蓝牙外围设备,初始化完成或点击事件里调用。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery方法停止搜索, 以及 onhideonUnload

监听寻找到新设备的事件 wx.onBluetoothDeviceFound(CALLBACK)
通过设备名(设备方提供)过滤设备,deviceId 一般不作为判断条件,因为开发者工具和 Android 上获取到的 deviceId 为设备 MAC 地址;iOS 上则为设备 uuid。

但是如果附近有多个同名的设备时,就需要通过 mac 地址来匹配对应的蓝牙设备了。ios 不同手机搜索到的设备 deviceId 经过处理后是不同的。如果需要处理这种情况可以联系蓝牙设备硬件方,将 mac 地址存入当前蓝牙设备的广播数据段中的 ManufacturerData 数据段中,我们通过 res.devices.advertisData 的值去匹配 & 连接蓝牙。

⚠️ 安卓下部分机型需要有位置权限才能搜索到设备,需留意是否开启了位置权限

连接低功耗蓝牙设备wx.createBLEConnection(OBJECT) 

若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。

断开连接:wx.closeBLEConnection(),在 onhideonUnload 时候;

wx.onBLEConnectionStateChange(function callback) 
监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等

获取蓝牙设备所有服务 (service) wx.getBLEDeviceServices(OBJECT) 
过滤出需要的 service uuid,设备方提供,比如包含某一个字段

获取蓝牙设备某个服务中的所有 characteristic(特征值)wx.getBLEDeviceCharacteristics(OBJECT)

过滤特征值,找到 用来写入 / 读取的特征值的 uuid 设备方提供  

特征值是什么 :每个服务都包含了一组特征值用来描述服务的一些属性,跟蓝牙通信时需要这些特征值 ID 来传递数据。

启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值  wx.notifyBLECharacteristicValueChange(OBJECT),这里需要用来读取的特征值的 uuid

注意⚠️:必须设备的特征值支持 notify 或者 indicate 才可以成功调用。

写入wx.writeBLECharacteristicValue(OBJECT) 向低功耗蓝牙设备特征值中写入数据,需写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。

wx.onBLECharacteristicValueChange 监听低功耗蓝牙设备的特征值变化事件(返回的多个数据包)

监听低功耗蓝牙设备的特征值变化事件。必须先启用 wx.notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。

BLE

小程序蓝牙是搜索不到手机蓝牙的。

经典蓝牙和 BLE(Bluetooth Low Energy)低功耗蓝牙的区别
蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙 3.0 之前的 BR/EDR 蓝牙称为传统蓝牙,而将蓝牙 4.0 规范下的 LE 蓝牙称为低功耗蓝牙。区别于传统模块,最大的特点就是成本和功耗降低,应用于实时性要求比较高。

蓝牙低功耗(BLE)功能,是利用蓝牙低功耗特性新发展的技术。
手机上要利用蓝牙低功耗技术,一般是通过 BLE 配件厂商发布的 BLE 配件和其配套 APP,配合使用。比如:BLE 运动手环、运动手表、体重计、计步器、智能腕带等。

二进制相关数据类型

ArrayBuffer & TypedArray

ArrayBuffer 对象、TypedArray 视图和 DataView 视图是 JavaScript 操作二进制数据的一个接口。ES6 将它们纳入了 ECMAScript 规格,并且增加了新的方法。它们都是以数组的语法处理二进制数据,所以统称为二进制数组。但是,二进制数组并不是真正的数组,而是类似数组的对象。

(1)ArrayBuffer 对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。

(2)TypedArray 视图:共包括 9 种类型的视图。比如 Uint8ArrayInt16ArrayFloat32Array 数组视图等等。Uint8Array 代表数组的每一项是无符号整型 8 代表数据的每一项占 8 个比特位,即一个字节(8bits=1byte)

通过 Uint8Array,即可知道其他视图如 Uint16ArrayInt8Array 等所代表的意义。

  • Int8Array 8 位有符号整数的数组
  • Uint16Array 16 位无符号整数数组 16 代表数据的每一项占 16 个比特位,即 2 个字节
  • Int16Array 16 位有符号整数数组

小概括

简单说,ArrayBuffer 对象代表原始的二进制数据,「并且只读」,而 TypedArray 视图可以进行改写操作。

// new ArrayBuffer 1
var cmdBuffer1 = new ArrayBuffer(15) // new ArrayBuffer(Bytelength); 15 个字节
//cmdBuffer1
ArrayBuffer(15) {}
    [[Int8Array]]: Int8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Uint8Array]: Uint8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
    byteLength: (...)  
    __proto__: ArrayBuffer
       
// new ArrayBuffer 2
var cmdBuffer2 = new ArrayBuffer(16)
// cmdBuffer2
ArrayBuffer(16) {}
    [[Int8Array]]: Int8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Int16Array]]: Int16Array(8)[0, 0, 0, 0, 0, 0, 0, 0]  
    [[Int32Array]]: Int32Array(4) [0, 0, 0, 0]   
    [[Uint8Array]]: Uint8Array(16)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   
    byteLength: (...)
    __proto__: ArrayBuffer
        
// ArrayBuffer -> TypedArray
var cmd1 = new Uint8Array(cmdBuffer1)
//cmd1
Uint8Array(15) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

// TypedArray -> ArrayBuffer
cmd1.buffer
// cmd1.buffer
ArrayBuffer(15) {}
    [[Int8Array]]: Int8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Uint8Array]]: Uint8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    byteLength: (...)
    __proto__: ArrayBuffer

数据写入和读取

数据写入

0x 是 16 进制的前缀,H 是 16 进制的后缀。另后缀

  • B,Binary(二进制);
  • H,Hex(十六进制);
  • O,Octal(八进制);
  • D,Decimal(十进制)。
// eg.
cmd1[10] = 0x20 //(数据定义来自产品说明)高四位是用户组数:2 表示用户组号是 P2;低四位是用户身体素质;0:普通人;1:业余运动员;2:专业运动员;0x20 转换为二进制为 100000,即 00100000,从左到右为高位到低位。高四位是用户组数,即 0010 转换为 10 进制是 2,表示用户组号是 P2,低四位是用户身体素质,0000 转换为 10 进制是 0,表示普通人,所以是 0x20 是 p2 普通人

数据读取

BLE 数据包传输规定了一次只能传输 20byte,所以如果数据量较大,需要做分包传输处理

小程序生命周期

隐藏 / 卸载 显示 / 加载

onLoad: wx.navigateTowx.redirectTowx.reLaunch
onShow: wx.navigateTowx.redirectTowx.navigateBackwx.reLaunch、选择照片

onHide: wx.navigateTo、选择照片
onUnload:wx.redirectTowx.navigateBackwx.reLaunch

小概括

wx.navigateBack只会 onshow 不会 onload,其余(除了 wx.switchTab)两者都会
wx.navigateTo 只会 onhide 不会 onunload,其余都是 onunload

小程序官方文档 - 蓝牙 api

https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth/wx.openBluetoothAdapter.html

退出移动版