当前位置:首页 > 新闻动态 > 网站文章

小程序连接低功耗蓝牙硬件的方案记录

来源: 浏览:119 时间:2023-08-06

前段时间搞了几天 小程序连接硬件蓝牙 实现读取数据 写入数据的功能。

之前没搞过还是遇到了一些问题。这次记录一下方案。

看下效果



  1. 根据小程序官方说明 大概就是
  2. 获取蓝牙设备列表
  3. 连接指定蓝牙设备
  4. 获取蓝牙设备的服务
  5. 连接指定蓝牙设备的 指定服务
  6. 根据服务获取 该服务的 特征 拿到 可读特征,可写特征,可通知特征
  7. 根据设备ID 服务ID 服务通知特征创建一个 数据监听 用来接收蓝牙响应数据
  8. 根据设备ID 服务ID 可写特征uuid 来写入数据

不说这么多 自己封装了一个函数js 文件 贴在这里 有需要的老铁可以自己领取

// 低功耗蓝牙链接 模块函数封装
// 寻找数组索引
export const inArray = (arr, key, val) => {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}
// ArrayBuffer转16进度字符串示例
export const ab2hex = (buffer) => {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}
export const readFloat16 = (bytes, offset, littleEndian) => {
  let sign = (bytes[offset + 1] & 0x80) ? -1 : 1;
  let exponent = ((bytes[offset + 1] & 0x7f) << 1) | (bytes[offset] >> 7);
  let fraction = ((bytes[offset] & 0x7f) << 8) | bytes[offset + 1];
  if (exponent === 0 && fraction === 0) {
    return 0;
  } else if (exponent === 0) {
    return sign * Math.pow(2, -14) * (fraction / Math.pow(2, 10));
  } else if (exponent === 0x1f) {
    return fraction !== 0 ? NaN : sign * Infinity;
  }
  return sign * Math.pow(2, exponent - 15) * (1 + fraction / Math.pow(2, 10));
}
// A 链接蓝牙关闭蓝牙扫描
export const stopBluetoothDevicesDiscovery = () =>{
  wx.stopBluetoothDevicesDiscovery() // 关闭蓝牙扫描
}
// 01 获取蓝牙列表 新设备 会连续查找 
export const getBluetList = (callout = null) => {
  // 初始化蓝牙模块
  wx.openBluetoothAdapter({
    success: function (res) {
      // 开始搜索设备
      wx.startBluetoothDevicesDiscovery({
        success: function (res) {
          // 找到设备后停止搜索
          wx.onBluetoothDeviceFound(function (devices) {
            callout && callout(devices.devices)
          })
        },
        fail: function (err) {
          console.log('01 搜索设备失败:', err)
        }
      })
    },
    fail: function (err) {
      console.log('01 初始化蓝牙失败:', err)
    }
  })
}
// 02 链接蓝牙
export const createBLEConnection = (deviceId, callout = null) => {
  wx.createBLEConnection({
    deviceId,
    success: (res) => {
      callout && callout(deviceId)
    },
    fail(e) {
      console.log('02 链接蓝牙失败:', e)
    }
  })
  this.stopBluetoothDevicesDiscovery()
}
// 03 获取指定蓝牙服务
export const getBLEDeviceServices = (deviceId, callout = null) =>{
     wx.getBLEDeviceServices({
       deviceId: deviceId,
       success: function (res) {
         console.log('03 获取蓝牙服务成功:', res.services)
         callout && callout(res.services)
       },
       fail(e) {
         console.log('03 获取蓝牙服务失败:', e)
       }
     })
}
// 04 获取低功耗蓝牙 某个指定服务得特征
export const getBLEDeviceCharacteristics = (deviceId, serviceId, callout = null) => {
  wx.getBLEDeviceCharacteristics({
    deviceId,
    serviceId,
    success: (res) => {
      console.log('04 获取蓝牙某个服务特征成功', res.characteristics)
      const query = {
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: '',
        writeCharacteristicId: '',
        readCharacteristicId: '',
      }
      res.characteristics.forEach(item => {
        // 获取可读特征 读取蓝牙低功耗设备特征值的二进制数据 注意:必须设备的特征支持 read 才可以成功调用
        if (item.properties.read) {
          wx.readBLECharacteristicValue({
            deviceId,
            serviceId,
            characteristicId: item.uuid,
          })
          query.characteristicId = item.uuid
        } else if (item.properties.write) {
          // 蓝牙可写特征
          query.writeCharacteristicId = item.uuid
        } else if (item.properties.notify) {
          // 蓝牙可通知特征
          query.readCharacteristicId = item.uuid
        }
      });
      callout && callout(query)
    },
    fail(res) {
      console.error('04 获取低功耗蓝牙 某个指定服务得特征 error: ', res)
    }
  })
}
// 05 启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。注意:必须设备的特征支持 notify 或者 indicate 才可以成功调用。
export const notifyBLECharacteristicValueChange = (deviceId, services_UUID, characteristic_UUID, callout = null) => {
  wx.notifyBLECharacteristicValueChange({
    deviceId: deviceId,
    serviceId: services_UUID,
    characteristicId: characteristic_UUID,
    state: true,
    type: 'notification',
    success(res) {
      console.log('启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值: 成功---', characteristic_UUID);
      wx.onBLECharacteristicValueChange((res) => {
        callout && callout(res.value)
      })
    },
    fail(res) {
      console.log('05 监听失败: ', res)
    },
  });
}
// 06 蓝牙写入函数
export const writeBufferToBLE = (deviceId, serviceId, writeCharacteristicId, sendBuffer,  callout = null) => {
    wx.writeBLECharacteristicValue({
      deviceId: deviceId,
      serviceId: serviceId, // 在这里替换成你的设备服务ID
      characteristicId:writeCharacteristicId, // 在这里替换成你的设备特征ID
      value: sendBuffer,
      success: function (res) {
        console.log('写入 writeBLECharacteristicValue success', res)
        callout && callout(res)
      }
    })
}
// B 通用连续调用方式 整合方法 ---------------------------------------------
const bluetConfig = {
  list: [],
  deviceId: '',
  services: [], 
  serviceId: null, // 指定服务的UUID
  characteristicId: '',
  writeCharacteristicId: '',
  readCharacteristicId: '',
}
export const bluetFuns = () => {
  // 获取蓝牙 列表 
  getBluetList((res) => {
    bluetConfig.list = [...bluetConfig.list, ...res]
  })
  bluetConfig.deviceId = bluetConfig.list[0]['id']
// 连接蓝牙 - 并且 监听数据 - 并模拟写入数据
  createBLEConnection(bluetConfig.deviceId, (res) => {
    // 获取蓝牙所有的服务
    getBLEDeviceServices(res, (res) => {
      bluetConfig.services = res
      // 获取指定服务的特征 xxxx 代表自己想要的 指定的服务的uuid 或 其中的某一段唯一标识
      res.forEach(box => {
        if(box.uuid.indexOf('xxxx') != -1) {
          bluetConfig.serviceId = box.uuid
          // 获取这个服务的所有特征
          getBLEDeviceCharacteristics(bluetConfig.deviceId, bluetConfig.serviceId, (res) => {
            bluetConfig.characteristicId = res.characteristicId
            bluetConfig.writeCharacteristicId = res.writeCharacteristicId
            bluetConfig.readCharacteristicId = res.readCharacteristicId
            // 服务特征变化监听
            notifyBLECharacteristicValueChange(bluetConfig.deviceId, bluetConfig.serviceId, bluetConfig.readCharacteristicId, (res) => {
              // 注意这里 是 实时响应的 在这里处理 响应数据把
              console.log('监听数据:', res)
            })
// 这里模拟一个写入方法
            let sendBuffer = new ArrayBuffer(2)
            let dataView = new DataView(sendBuffer)
            dataView.setUint8(0, 0x00)
            writeBufferToBLE(bluetConfig.deviceId, bluetConfig.serviceId, bluetConfig.writeCharacteristicId, sendBuffer, (res)=>{
              console.log('蓝牙写入回调:', res)
            })
})
        }
      })
    })
  })
}

地址 · ADDRESS

地址:建邺区新城科技园嘉陵江东街18号2层

邮箱:309474043@qq.Com

点击查看更多案例

联系 · CALL TEL

400-8793-956

售后专线:025-65016872

业务QQ:309474043    售后QQ:1850555641

©南京安优网络科技有限公司 版权所有   苏ICP备12071769号-4  网站地图