微信小程序蓝牙功能使用

  // 此次 serviceId characteristicId notifyId 是固定值,可以直接写在data中,如不是需要动态获取
  //  deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获
  //  serviceId 需要在 getBLEDeviceServices 接口中获取
  // characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
let bluetoothData = {
  devices: [], //搜索到的蓝牙设备列表
  chs: [],
  linkDevice: false, // 是否已经连接到当前设备
  isWrite: false, //是否写入成功
  deviceId: '',
  serviceId: '0000000000000000000000000000',  
  characteristicId: '111111111111111111111111', // 特征值
  notifyId: '333333333333333333333333333', // notifyId
  _discoveryStarted: false,
  canWrite: false, // 当前设备是否可写入
}
let timmer // 定时器

//linkData 连接当前蓝牙设备的标志, command 发送的蓝牙指令
function opereatBle(linkData, command) {
  return new Promise((resolve, reject) => {
    openBluetoothAdapter()
    // 初始化蓝牙设备
    function openBluetoothAdapter() {
      wx.openBluetoothAdapter({
        success: (res) => {
          startBluetoothDevicesDiscovery() // 开始扫描
        },
        fail: (res) => {
          console.log(res)
          if (res.errCode === 10001) { // 10001 当前蓝牙适配器不可用
            resolve(false)
          }
        }
      })
    }
    // 开始扫描
    function startBluetoothDevicesDiscovery() {
      console.log('bluetoothData._discoveryStarted,', bluetoothData._discoveryStarted)
      if (bluetoothData._discoveryStarted) {
        return
      }
      bluetoothData._discoveryStarted = true
      // 开始搜索附件的蓝牙设备
      wx.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: true,
        success: (res) => {
          console.log('开始搜索附件的蓝牙设备', res)
          onBluetoothDeviceFound() // 监听搜索到新设备的事件
        },
      })
      timmer = setTimeout(() => {
        console.log('===10 秒自动停止扫描===,扫描到当前设备蓝牙信息?', bluetoothData.linkDevice)
        stopBluetoothDevicesDiscovery()
        wx.offBluetoothDeviceFound()
        closeBluetoothAdapter()
        if (!bluetoothData.linkDevice|| !bluetoothData.isWrite) {
          console.log('10s没有连接到当前设备,结束流程')
          resolve(false)
        }
      }, 10000);
    }
    // 停止所寻附近的蓝牙设备
    function stopBluetoothDevicesDiscovery() {
      console.log('停止扫描')
      wx.stopBluetoothDevicesDiscovery()
    }
    // 监听搜索到新设备的事件
    function onBluetoothDeviceFound() {
      wx.onBluetoothDeviceFound((res) => {
        // console.log(res, 'res')
        res.devices.forEach(device => {
          if (!device.name && !device.localName) {
            return
          }
          const foundDevices = bluetoothData.devices
          foundDevices.push(device)
          bluetoothData.devices = foundDevices
          bluetoothData.devices.forEach(item => {
            if (ab2str(item.advertisData) == linkData) {
              // console.log(ab2str(item.advertisData), linkData, '扫描到当前设备')
              createBLEConnection(item) // 连接蓝牙设备
              bluetoothData.linkDevice= true  // 连接到设备
              stopBluetoothDevicesDiscovery() // 连接到设备后,停止继续扫描
              wx.offBluetoothDeviceFound() //取消监听
            }
          })
        })
      })
    }

    // 连接蓝牙低功耗设备
    function createBLEConnection(e) {
      console.log(e, '=====连接蓝牙低功耗设备=====')
      const deviceId = e.deviceId
      const name = e.name
      // 连接蓝牙低功耗设备
      wx.createBLEConnection({
        deviceId,
        success: (res) => {
          bluetoothData.connected = true
          bluetoothData.name = name
          bluetoothData.deviceId = deviceId
          getBLEDeviceCharacteristics(bluetoothData.deviceId, bluetoothData.serviceId) // 监听特征值数据
        }
      })
      stopBluetoothDevicesDiscovery() // 停止搜索蓝牙设备
    }
    // 关闭连接
    function closeBLEConnection() {
      console.log('关闭连接')
      wx.closeBLEConnection({
        deviceId: bluetoothData.deviceId
      })
      bluetoothData.connected = false 
      bluetoothData.chs = []
      bluetoothData.canWrite = false
    }
    // 获取蓝牙低功耗设备某个服务中所有特征
    function getBLEDeviceCharacteristics(deviceId, serviceId) {
      wx.getBLEDeviceCharacteristics({
        deviceId,
        serviceId,
        success: (res) => {
          console.log('获取蓝牙某个服务的所有特征')
          let data = res.characteristics.find(item => item.properties.write)
          console.log('已保存读写特征值', data)
          if (data) {
            bluetoothData.canWrite = true
          }
          wx.notifyBLECharacteristicValueChange({ 
          // 启用蓝牙低功耗设备特征值变化时的 notify 功能,
            deviceId, // 蓝牙设备 id
            serviceId, // 蓝牙特征对应服务的 UUID
            characteristicId: bluetoothData.notifyId, // 蓝牙特征的 UUID
            //characteristicId :固定值直接写入,动态值需要在getBLEDeviceCharacteristics 接口中获取
            state: true, // 是否启用 notify
            success(res) {
              console.log('获取特征')
              writeBLECharacteristicValue(command) //写入指令
              wx.onBLECharacteristicValueChange(function (res) {
                resolve(true)
                bluetoothData.isWrite = true //写入成功
                closeBLEConnection() // 写入完成,断开连接
                wx.offBluetoothDeviceFound() //停止监听
                closeBluetoothAdapter() // 结束流程
                clearTimeout(timmer) // 写入完成,停止定时器
              })
            }
          })
        },
        fail(res) {
          console.error('getBLEDeviceCharacteristics', res)
        }
      })
    }
    
    // 向蓝牙低功耗设备特征值中写入二进制数据
    function writeBLECharacteristicValue(carValue) {
      console.log('开始写入数据')
      // 向蓝牙设备发送一个0x00的16进制数据
      let _Buffer = string2buffer(carValue)
      let Num = 0;
      let ByteLength = _Buffer.byteLength;
      
      // 发送指令超过20字节,需要分包写入数据
      while (ByteLength > 0) {
        let TmpBuffer;
        if (ByteLength > 20) {
          return Delayed(0.25).then(() => {
            TmpBuffer = _Buffer.slice(Num, Num + 20);
            Num += 20;
            ByteLength -= 20;
            wx.writeBLECharacteristicValue({
              deviceId: bluetoothData.deviceId,
              serviceId: bluetoothData.serviceId,
              characteristicId: bluetoothData.characteristicId,
              value: TmpBuffer,
              success(res) {
                console.log('第一次写入', res)
                if (ByteLength) {
                  writeBLECharacteristicValue(carValue.slice(Num))
                }
              }
            })
          })
        } else {
          return Delayed(0.25).then(() => {
            TmpBuffer = _Buffer.slice(Num, Num + ByteLength);
            Num += ByteLength;
            ByteLength -= ByteLength;
            wx.writeBLECharacteristicValue({
              deviceId: bluetoothData.deviceId,
              serviceId: bluetoothData.serviceId,
              characteristicId: bluetoothData.characteristicId,
              value: TmpBuffer,
              success(res) {
                console.log('第二次写入', res)
              }
            })
          })
        }
      }
    }
    // 关闭蓝牙模块
    function closeBluetoothAdapter() {
      // console.log('关闭蓝牙模块')
      wx.closeBluetoothAdapter()
      bluetoothData._discoveryStarted = false
    }

  })
}

// ArrayBuffer转字符串实例
function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

function string2buffer(str) {
  // 首先将字符串转为16进制
  let val = ""
  for (let i = 0; i < str.length; i++) {
    if (val === '') {
      val = str.charCodeAt(i).toString(16)
    } else {
      val += ',' + str.charCodeAt(i).toString(16)
    }
  }
  let endStr = val + '0d,0a'  //  0d,0a => /r , /n
  // 将16进制转化为ArrayBuffer
  return new Uint8Array(endStr.match(/[\da-f]{2}/gi).map(function (h) {
    return parseInt(h, 16)
  })).buffer
}

//分包延迟定时器
function Delayed(ms, res) {
  return new Promise(function (Resolve, Reject) {
    setTimeout(function () {
      Resolve(res);
    }, ms);
  });
}

export {
  opereatBle
}

页面使用:

import { opereatBle } from "./opereatBle.js"; // 引入
opereatBle(xxxx, xxxx, ).then(res=>{
if(res){
	......
	console.log('success')
}else{
	......
	console.log('failure')
}
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值