Skip to content

微信小程序蓝牙通讯

简单说下个人理解 每个蓝牙设备(BLE) 都有一个主服务还有设备ID, 小程序连接设备需要用到设备ID 连接后小程序可以获取设备的 服务 再由服务 获取到蓝牙设备的 特征值

这个主服务serviceId 应该指的是同一个东西

主服务特征值一般都是蓝牙厂商提前定义好的固定值

一个服务下有 多个 特征值 这些 特征值 有的可读, 有的可写, 还有通知的 就是特征值的 read、write、notify 操作

(官方文档)[https://developers.weixin.qq.com/miniprogram/dev/framework/device/ble.html]

js
// 初始化蓝牙模块
wx.openBluetoothAdapter;

// 开始搜索附近的蓝牙外围设备
wx.startBluetoothDevicesDiscovery;

// 连接设备获取服务
wx.createBLEConnection({
  deviceId, // 搜索到设备的 deviceId
  success: () => {
    // 连接成功,获取服务
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        wx.getBLEDeviceCharacteristics({
          deviceId, // 搜索到设备的 deviceId
          serviceId, // 上一步中找到的某个服务
          success: (res) => {
            for (let i = 0; i < res.characteristics.length; i++) {
              let item = res.characteristics[i];
              if (item.properties.write) {
                // 该特征值可写
                // 本示例是向蓝牙设备发送一个 0x00 的 16 进制数据
                // 实际使用时,应根据具体设备协议发送数据
                let buffer = new ArrayBuffer(1);
                let dataView = new DataView(buffer);
                dataView.setUint8(0, 0);
                wx.writeBLECharacteristicValue({
                  deviceId,
                  serviceId,
                  characteristicId: item.uuid,
                  value: buffer,
                });
              }
              if (item.properties.read) {
                // 该特征值可读
                wx.readBLECharacteristicValue({
                  deviceId,
                  serviceId,
                  characteristicId: item.uuid,
                });
              }
              if (item.properties.notify || item.properties.indicate) {
                // 必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 onBLECharacteristicValueChange 事件
                wx.notifyBLECharacteristicValueChange({
                  deviceId,
                  serviceId,
                  characteristicId: item.uuid,
                  state: true,
                });
              }
            }
          },
        });
      },
    });
  },
});

常见问题

  • iOS 上,对特征值的 read、write、notify 操作,由于系统需要获取特征值实例,传入的 serviceId 与 characteristicId 必须由 wx.getBLEDeviceServices 与 wx.getBLEDeviceCharacteristics 中获取到后才能使用。建议统一在建立连接后先执行 wx.getBLEDeviceServices 与 wx.getBLEDeviceCharacteristics 后再进行与蓝牙设备的数据交互。
  • 考虑到蓝牙功能可以间接进行定位,安卓 6.0 及以上版本,无定位权限或定位开关未打开时,无法进行设备搜索。
  • 安卓上,部分机型获取设备服务时会多出 00001800 和 00001801 UUID 的服务,这是系统行为,注意不要使用这两个服务。
  • 建立连接和关闭连接必须要成对调用。如果未能及时关闭连接释放资源,安卓上容易导致 state 133 GATT ERROR 的异常。
  • 在与蓝牙设备传输数据时,需要注意 MTU(最大传输单元)。如果数据量超过 MTU 会导致错误,建议根据蓝牙设备协议进行分片传输。安卓设备可以调用 wx.setBLEMTU 进行 MTU 协商。在 MTU 未知的情况下,建议使用 20 字节为单位传输。