微信小程序:蓝牙通讯,搜索、发送与接收

需求背景

使用微信小程序,通过蓝牙与硬件设备产品进行交互

参考文档

微信小程序蓝牙通讯

开始

1.初始化蓝牙

initBlue: function () {
    var that = this
    wx.openBluetoothAdapter({
      success: function (res) {
        that.findBlue()
      },
      fail: function (res) {
        wx.showToast({
          title: '请打开手机蓝牙!',
          icon: 'none',
          duration: 2000
        })
      }
    })
  }

2.查找蓝牙

findBlue() {
    var that = this
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: false,
      interval: 0,
      success: function (res) {
        that.getBlue()
      }
    })
  },

  getBlue() {
    var that = this
    var searchResult = false
    var index = 0

    wx.showLoading({
      title: '搜索设备...',
    })

    //定时搜索
    var interval = setInterval(function () {
      wx.getBluetoothDevices({
        success: function (res) {
          index = index + 1
          if (!searchResult) {
            for (var i = 0; i < res.devices.length; i++) {
              //根据设备名称匹配   这里的meterId是需要匹配的设备名称
              if ((res.devices[i].name + "").substr(0, 16) == that.data.meterId ||
                (res.devices[i].localName + "").substr(0, 16) == that.data.meterId) {
                that.setData({
                  //获取蓝牙设备的deviceId
                  deviceId: res.devices[i].deviceId,
                })

                searchResult = true
                if (searchResult) {
                  clearInterval(interval)
                }
                //连接蓝牙
                that.connetBlue(res.devices[i].deviceId)
                return
              }
            }
          }

          if (index > 20) {
            clearInterval(interval)
            wx.hideLoading()
            wx.showToast({
              title: '未找到设备,请重试!',
              icon: 'none',
              duration: 2000
            })
            wx.stopBluetoothDevicesDiscovery() //关闭蓝牙搜索
          }
        }
      })
    }, 500)
  }

3.连接蓝牙设备

connetBlue(deviceId) {
    var that = this

    wx.hideLoading()
    wx.showLoading({
      title: '连接设备...',
    })

    wx.createBLEConnection({
      deviceId: deviceId,
      success: function (res) {
        wx.stopBluetoothDevicesDiscovery() //关闭蓝牙搜索
        that.getServiceId() //获取服务ID
      },
      fail: function () {
        wx.hideLoading()
        wx.showToast({
          title: '连接设备失败!',
          icon: 'none',
          duration: 2000
        })
        wx.stopBluetoothDevicesDiscovery() //关闭蓝牙搜索
      }
    })
  },

  getServiceId() {
    var that = this
    wx.getBLEDeviceServices({
      deviceId: that.data.deviceId,
      success: function (res) {
        var model = res.services[0]
        that.setData({
          serviceId: model.uuid
        })
        that.getCharacteId()
      }
    })
  },

  getCharacteId() {
    var that = this

    wx.getBLEDeviceCharacteristics({
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      success: function (res) {
        for (var i = 0; i < res.characteristics.length; i++) {
          var model = res.characteristics[i]
          if (model.properties.notify == true) {
            that.setData({
              notifyId: model.uuid
            })

            //重点:开启监听服务。监听设备数据变化
            that.startNotice(model.uuid)
          }
          if (model.properties.write == true) {
            that.setData({
              writeId: model.uuid
            })
          }
        }

        //有可写权限
        if (that.data.writeId != '') {
          wx.hideLoading()
          wx.showLoading({
            title: '通讯中...',
          })

          //这里可以完成需要下发到设备上的指令的生成
          that.sendCmd(value)
        } else {
          wx.showToast({
            title: '失败: 设备无写入权限!',
            icon: 'none',
            duration: 2000
          })
        }
      }
    })
  }

4.发送数据

 sendCmd(cmdValue) {
    var that = this

    if (cmdValue != '' && cmdValue != null && cmdValue != undefined) {
      that.writeCharacterToDevice(util.stringToArrayBuffer(cmdValue))
    } else {
      wx.showToast({
        title: '获取设备指令失败',
        icon: 'none',
        duration: 2000
      })
    }
  }

 writeCharacterToDevice(buffer) {
    var that = this

    wx.writeBLECharacteristicValue({
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      characteristicId: that.data.writeId,
      value: buffer,
      fail: function () {
        wx.showToast({
          title: '写入设备数据失败!',
          icon: 'none',
          duration: 2000
        })

      },
      success: function () {
        wx.showLoading({
          title: '指令发送成功',
          duration: 2000
        })
      }
    })
  }

5.工具函数


  function stringToArrayBuffer(str) {
  var bytes = new Array();
  var len, c;
  len = str.length;
  for (var i = 0; i < len; i++) {
    c = str.charCodeAt(i);
    if (c >= 0x010000 && c <= 0x10FFFF) {
      bytes.push(((c >> 18) & 0x07) | 0xF0);
      bytes.push(((c >> 12) & 0x3F) | 0x80);
      bytes.push(((c >> 6) & 0x3F) | 0x80);
      bytes.push((c & 0x3F) | 0x80);
    } else if (c >= 0x000800 && c <= 0x00FFFF) {
      bytes.push(((c >> 12) & 0x0F) | 0xE0);
      bytes.push(((c >> 6) & 0x3F) | 0x80);
      bytes.push((c & 0x3F) | 0x80);
    } else if (c >= 0x000080 && c <= 0x0007FF) {
      bytes.push(((c >> 6) & 0x1F) | 0xC0);
      bytes.push((c & 0x3F) | 0x80);
    } else {
      bytes.push(c & 0xFF);
    }
  }
  var array = new Int8Array(bytes.length);
  for (var i in bytes) {
    array[i] = bytes[i];
  }
  return array.buffer;
}

function arrayBufferToString(arr) {
  if (typeof arr === 'string') {
    return arr;
  }
  var dataview = new DataView(arr);
  var ints = new Uint8Array(arr.byteLength);
  for (var i = 0; i < ints.length; i++) {
    ints[i] = dataview.getUint8(i);
  }
  arr = ints;
  var str = '',
    _arr = arr;
  for (var i = 0; i < _arr.length; i++) {
    var one = _arr[i].toString(2),
      v = one.match(/^1+?(?=0)/);
    if (v && one.length == 8) {
      var bytesLength = v[0].length;
      var store = _arr[i].toString(2).slice(7 - bytesLength);
      for (var st = 1; st < bytesLength; st++) {
        store += _arr[st + i].toString(2).slice(2);
      }
      str += String.fromCharCode(parseInt(store, 2));
      i += bytesLength - 1;
    } else {
      str += String.fromCharCode(_arr[i]);
    }
  }
  return str;
}

6.开启事件监听

  /**
   * 监听水表数据变化
   * @param {水表ID} uuid 
   */
  startNotice(uuid) {
    var that = this

    wx.notifyBLECharacteristicValueChange({
      state: true, // 启用 notify 功能
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceId,
      characteristicId: uuid,
      success: function (res) {
        var deviceResult = ''
        //特征数据变化
        wx.onBLECharacteristicValueChange(function (res) {
          deviceResult = deviceResult + util.arrayBufferToString(res.value) //应答数据比较长,会触发多次
          //如果应答帧总长度大于数据包长度,并且包含“16”,则说明是完整的应答帧
          if (deviceResult.lastIndexOf('16') >= (deviceResult.length - 8) && deviceResult.indexOf('68') >= 0) {
            //解析应答帧  这里开始对设备应答数据进行处理了
            
            deviceResult = ''
          }
        })
      }
    })
  },

设备应答数据也可以发送到后台服务进行处理,根据具体业务而定

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在微信小程序中操作蓝牙发送数据,你可以按照以下步骤进行操作: 1. 在小程序的json配置文件中,添加蓝牙功能的权限声明: ```json "permissions": { "bluetooth": true, "openBluetoothAdapter": true } ``` 2. 在小程序页面的js文件中引入蓝牙模块: ```javascript const bluetooth = requirePlugin("bluetooth-plugin"); ``` 3. 初始化蓝牙适配器: ```javascript bluetooth.openAdapter({ success(res) { console.log("蓝牙适配器初始化成功"); }, fail(err) { console.error("蓝牙适配器初始化失败", err); } }); ``` 4. 开始搜索蓝牙设备: ```javascript bluetooth.startDevicesDiscovery({ success(res) { console.log("开始搜索蓝牙设备"); }, fail(err) { console.error("搜索蓝牙设备失败", err); } }); ``` 5. 监听搜索到的蓝牙设备: ```javascript bluetooth.onDeviceFound((res) => { console.log("搜索蓝牙设备", res.devices); }); ``` 6. 连接目标蓝牙设备: ```javascript bluetooth.createBLEConnection({ deviceId: "目标设备的deviceId", success(res) { console.log("连接蓝牙设备成功", res); }, fail(err) { console.error("连接蓝牙设备失败", err); } }); ``` 7. 发送数据到蓝牙设备: ```javascript bluetooth.writeBLECharacteristicValue({ deviceId: "目标设备的deviceId", serviceId: "目标设备的serviceId", characteristicId: "目标设备的characteristicId", value: ArrayBuffer.from("要发送的数据"), success(res) { console.log("发送数据成功", res); }, fail(err) { console.error("发送数据失败", err); } }); ``` 以上是一个基本的蓝牙操作流程,具体的deviceId、serviceId和characteristicId需要根据你的实际设备情况进行替换。另外,建议在页面卸载时关闭蓝牙适配器和停止蓝牙设备搜索: ```javascript onUnload() { bluetooth.closeAdapter(); bluetooth.stopDevicesDiscovery(); } ``` 希望能帮到你!如有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值