物联网关于蓝牙传输的那些事

496 阅读2分钟

需求背景 (低耗蓝牙设备,通过app控制,实现设备绑定、数据采集、数据上传、数据清空...)嗯...瑟瑟发抖最终选定uniapp愉快的开启懵逼握草搬砖。

开机最高仪式感当然是看文档 uniapp.dcloud.net.cn/api/system/… en...,文档是好文档,一个一个看挺清晰的,沉下心,问问度娘,大概有点谱,离离原上谱的那种,哈哈哈。

正经事来啦

流程图.png

总结:就是找到蓝牙的提供的通知的那个特征值 特征值支持读、写、通知等特征,发送指令无非就是操作该特征值的写入属性,通知类似于回调(uni.onBLECharacteristicValueChange)。

en...............................流程看着没毛病,实际调试设备,麻

设备约定的协议是CRC-16/IBM校验 16进制进行传输 分包发送

主要实现

1. 分包

function delayed(ms, res) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      resolve(res);
    }, ms)
  });
}

function writeDevice(deviceId, serviceId, characteristicId, arrayBuffer) {
  for (let index = 0; index < arrayBuffer.length; index++) {
    const buf = arrayBuffer[index];
    delayed(200 * index).then(() => {
      uni.writeBLECharacteristicValue({
        deviceId,
        serviceId,
        characteristicId,
        value: buf,
        success: (res) => {
          /* 发送成功 */
          console.log(`第${index + 1}包成功`, res);
        },
        fail: (error) => {
          /* 发送失败 */
          console.log(`第${index + 1}包失败`, error);
        },
      });
    });
  }
}

2.数据转化 10进制转16进制 ASCII码转16进制 16进制转10进制

// ArrayBuffer转16进制字符串 主要解析回传的数据
function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ("00" + bit.toString(16)).slice(-2);
    }
  );
  return hexArr.join("");
}

3.数据回传处理(设备返回的数据跟传统的数据对象不同,都是一串串编码回码)
let data = []
let flag = false // 传输完毕
for (let index = 0; index < result.length; index++) {
  let item = result[index]
  // 约定的数据开头标识
  if (item.match(RegExp(/XXXXXXX/))) {
    let str = ''
    for (let i = 0; i < 4; i++) {
      str += result[index + i]
    }
    data.push(str)
  }
  // 检验是不是传输完毕 约定的结束标识
  if (item.match(RegExp(/XXXXXXX/))) {
    console.log('--------------------------传输完毕------------------------')
    let str = item.slice(-4);
    let token = item.slice(0, item.length - 4)
    let match = getCrc_16_ibm(token.replace(/\s*/g, ""))
    if (str === match) {
      flag = true
    }
  }
}

优化及考虑

1. 设备传输数据 数据量过大或者意外中断(设备存储有限)
处理:检测到传输完毕,执行上传数据操作,在其中过程中,如有中断,提示是否需要继续尝试拉取 确定需要继续拉取,则执行拉取指令,手动去重追加新数据

2. 数据上传
处理:先将数据切割分包,分包上传

3. 蓝牙未开启及异常
处理:错误页处理逻辑,根据情况处理是否需要初始化,是否直接连接等

4. 蓝牙调试 
处理:nRf connect 调试软件

哈哈哈,记录一下。