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

文章目录

    示例代码

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

      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 工具之后就正常了。

    继续阅读 🌳

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

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式