微信小程序蓝牙通信发送指令,十六进制编码转换

更新日期: 2023-06-15 阅读次数: 11005 字数: 632 分类: 微信小程序

示例代码

这是微信小程序官方示例中的一段代码,用于向蓝牙设备发送指令。

  writeBLECharacteristicValue() {
    // 向蓝牙设备发送一个0x00的16进制数据
    let buffer = new ArrayBuffer(1)
    let dataView = new DataView(buffer)
    dataView.setUint8(0, Math.random() * 255 | 0)
    console.log("deviceId: " + this._deviceId);
    console.log("serviceId: " + this._serviceId);
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      //serviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success: (e) => {
        console.log("success ...");
        console.log(e);
      },
      fail: (e) => {
        console.log("fail ...");
        console.log(e);
      },
    })
  },

ArrayBuffer

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer

The ArrayBuffer object is used to represent a generic, fixed-length raw binary data buffer.

ArrayBuffer 就是一段定长的二机制 buffer. 但是并不能直接操作和读取,需要通过例如 DataView 类型进行读取或操作。

It is an array of bytes, often referred to in other languages as a "byte array".You cannot directly manipulate the contents of an ArrayBuffer; instead, you create one of the typed array objects or a DataView object which represents the buffer in a specific format, and use that to read and write the contents of the buffer.

ArrayBuffer 的参数代表代表什么

例如:

// 向蓝牙设备发送一个0x00的16进制数据
let buffer = new ArrayBuffer(1)

这里的参数 1 代表一个 byte,即 8 个bit 位。对应两个 16 进制字符。

DataView

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView

The DataView view provides a low-level interface for reading and writing multiple number types in a binary ArrayBuffer。

dataView.setUint8

dataView.setUint8(0, 255 | 0)

例如,上面这段代码,如果直接发给蓝牙设备,解析出来是两个字符,"FF"。

setUint8(byteOffset, value)

The setUint8() method stores an unsigned 8-bit integer (byte) value at the specified byte offset from the start of the DataView.

  • 第一个参数是 offset
  • 第二个参数是值

但是为何要写成 255 | 0 这样的格式呢?

这得看原来的代码

Math.random() * 255 | 0

这里的竖杠 0 起到了取整的作用。Chrome Console 里测试:

> 3.1415 | 0
3

如果不是 0 呢,参考 https://www.haorooms.com/post/js_dsg_ysf

3|4
转换为二进制之后011|100  相加得到111=7

4|4
转换为二进制之后100|100  相加得到100=4

8|3
转换为二进制之后1000|011  相加得到1011=11

所以,我在蓝牙通信的使用场景中,我用不到这个操作。

setUint8 的人类肉眼可辨的写法

例如,第一个字节,我想写入“23”两个字符

dataView.setUint8(0,0x23)

蓝牙通信中 ArrayBuffer 长度多少合适

https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth-ble/wx.writeBLECharacteristicValue.html

  • 小程序不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
  • 若单次写入数据过长,iOS 上存在系统不会有任何回调的情况(包括错误回调)。

调试中遇到的诡异问题

如果使用 Feasycom serial port 1.0.3 客户端调试工具来接收指令, 会发现所有 00 后的数据都被截断,例如:

在微信小程序中向蓝牙设备写入

AA 12 00 BB

Feasycom serial port 1.0.3 只会显示

AA 12

00 及后面的均消失不见。

我以为是我 js 代码写的有问题,一直没有头绪,切换为 XCOM V2.6 工具之后就正常了。

继续阅读 🌳

微信小程序中显示关注公众号按钮

tags: 微信小程序蓝牙通信

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式