终于实现了蓝牙的功能,也找到了合适的硬件,记录一下自己需要注意和总结的地方
具体的搜索、连接、断开、消息传输都已经实现了,作为项目的一个页面完成了

相应的代码地址,具体的蓝牙代码在pages/bluetooth当中

蓝牙部分代码地址

一.硬件部分

  1. HC-08 蓝牙模块 4.0BLE主从一体 CC2540 无线串口透传模块 BLE串口通信
  2. 硬件官网
    汇承官网
  3. 基本连接教程
    连接测试过程
    注意:串口模块和usb to ttl的连接方式

二. Windows串口调试助手

  1. 下载串口调试助手
  2. 设置默认波特率为9600

三.手机App测试

  1. LightBlue和Windows的调试
    bluetooth1bluetooth2
    bluetooth3
    bluetooth4注意:由图4可以看出串口通信的serviceId的UUID为FFE0(读写UUID)

四.微信小程序初始化连接(重头戏来了)

  1. 初始化蓝牙适配器
        wx.openBluetoothAdapter({
          success: function (res) {
            console.log(\'初始化蓝牙适配器成功\' + JSON.stringify(res))
            that.msg = \'初始化蓝牙适配器成功\'
            wx.showModal({
              title: \'蓝牙适配情况\',
              content: \'初始化蓝牙适配器成功\'
            })
          },
          fail: function () {
            that.msg = \'初始化蓝牙适配器失败\'
            wx.showModal({
              title: \'蓝牙适配情况\',
              content: \'蓝牙适配失败,请检查手机蓝牙和定位功能是否打开\'
            })
          },
          complete: function () {
            console.log(\'初始化蓝牙适配器完成\')
          }
        })
  1. 开启蓝牙搜索,并获取蓝牙设备列表 wx.getBluetoothAdapterState –> wx.onBluetoothAdapterStateChange –> wx.startBluetoothDevicesDiscovery –> wx.onBluetoothDeviceFound –> getBluetoothDevices
  2. 选择蓝牙设备获取相应的deviceId
  3. 连接蓝牙设备 wx.createBLEConnection –> wx.getBLEDeviceService(获取设备的ServiceId)
wx.createBLEConnection({
          deviceId: deviceId,
          success: function (res) {
            console.log(\'蓝牙设备连接成功\')
            wx.hideLoading()
            wx.getBLEDeviceServices({
              deviceId: deviceId,
              success: function (res) {
                that.deviceService = res.services
                for (var t = 0; t < that.deviceService.length; t++) {
                  var service = that.deviceService[t]
                  var serviceId = service.uuid.substring(4, 8)
                  if (serviceId === \'FFE0\') {                  //‘FFE0’为设备定义的读写UUID
                    that.serviceId = service.uuid
                  }
                }
                that.nowDevice = !that.nowDevice
                that.nowService = !that.nowService
                console.log(\'获取蓝牙设备Service\' + res.errMsg)
              },
              fail: function (res) {
                wx.showModal({
                  title: \'设备Service信息\',
                  content: \'蓝牙设备连接成功\' + \'\n\' + \'设备信息获取错误\' + res.errMsg
                })
              }
            })
          },
          fail: function (res) {
            console.log(\'蓝牙设备连接失败,请稍后重试\')
            wx.hideLoading()
            wx.showModal({
              title: \'提示\',
              content: \'蓝牙设备连接失败,请稍后重试\',
              duration: 2000
            })
          },
          complete: function () {
            console.log(\'蓝牙设备连接完成\')
            wx.hideLoading()
          }
        })
  1. 连接设备同时关闭蓝牙搜索 wx.stopBluetoothDevicesDiscovery
  2. 向串口发送数据(重要)
    wx.getBLEDeviceCharacteristics –> success: wx.notifyBLECharacteristicValueChang (启用notify功能) –> success:wx.writeBLECharacteristicValue –> success:wx.readBLECharacteristicValue(必须读取,否则Android设备无法正常向串口发送数据
wx.getBLEDeviceCharacteristics({
          deviceId: that.deviceId,
          serviceId: that.serviceId,
          success: function (res) {
            console.log(res.characteristics)
            that.deviceCharacteristics = res.characteristics
            for (var i = 0; i < that.deviceCharacteristics.length; i++) {
              that.characteristic = that.deviceCharacteristics[i]
              that.characteristicProperties = that.characteristic.properties
              if (that.characteristicProperties.notify === true) {
                that.characteristicId = that.characteristic.uuid
                wx.notifyBLECharacteristicValueChange({
                  state: true, // 启用 notify 功能
                  deviceId: that.deviceId,
                  serviceId: that.serviceId,
                  characteristicId: that.characteristicId,
                  success: function (res) {
                    console.log(\'开启notify成功\' + that.characteristic.uuid)
                    for (let i = 0; i < dataView.byteLength; i++) {
                      var writeData = \'0x\' + dataView.getUint8(i).toString(16)
                      that.writeDatas = that.writeDatas + \'\n\' + writeData
                    }
                    wx.writeBLECharacteristicValue({
                      deviceId: that.deviceId,
                      serviceId: that.serviceId,
                      characteristicId: that.characteristicId,
                      value: dataBuffer,
                      success: function (res) {
                        console.log(\'发送的数据:\' + that.writeDatas)
                        console.log(\'message发送成功\')
                        wx.showModal({
                          title: \'数据发送成功\',
                          content: that.writeDatas
                        })
                        wx.readBLECharacteristicValue({
                          deviceId: that.deviceId,
                          serviceId: that.serviceId,
                          characteristicId: that.characteristicId,
                          success: function (res) {
                            console.log(\'读取数据成功\')
                          }
                        })
                      },
                      fail: function (res) {
                        // fail
                        console.log(\'message发送失败\' + that.characteristicIdw)
                        wx.showToast({
                          title: \'数据发送失败,请稍后重试\',
                          icon: \'none\'
                        })
                      },
                      complete: function (res) {
                        // fail
                        console.log(\'message发送完成\')
                      }
                    })
                  },
                  fail: function () {
                    console.log(\'开启notify失败\' + that.characteristicId)
                  }
                })
                // that.writeMessage(that.deviceId, that.serviceId, that.characteristicIdw, that.characteristicIdr, that.characteristicIdn)
              }
            }
          },
          fail: function () {
            console.log(\'获取characteristic失败\')
          }
        })
  1. 读取串口发送的数据 (重要)
    wx.getBLEDeviceCharacteristics –> success:wx.notifyBLECharacteristicValueChange –> success:wx.readBLECharacteristicValue –> wx.onBLECharacteristicValueChange

五.微信小程序蓝牙未启动,离开小程序开启蓝牙后再启动小程序

蓝牙页面启动流程

  1. 在onLoad中wx.openBluetoothAdapter
  2. 在onShow中判断当前蓝牙适配器的状态wx.onBluetoothAdapterStateChange –> 若更改成功,则wx.openBluetoothAdapter

六.微信小程序开发注意

  1. Android设备在readBLECharacteristicValu后可能会出现显示message传输成功但是串口调试助手收不到数据的情况
    解决方法:在writeBLECharacteristicValu后添加readBLECharacteristicValue
  2. 串口读写设备的时候注意转换数据格式,传输的数据格式为ArrayBuffer,需要转换才可以显示,直接console返回的res.value为空
    用到的转换格式代码
let data = that.sendData.split(\',\')
        let dataBuffer = new ArrayBuffer(data.length)
        let dataView = new DataView(dataBuffer)
        for (let j = 0; j < data.length; j++) {
          dataView.setUint8(j, \'0x\' + data[j])
        }

var writeData = \'0x\' + dataView.getUint8(i).toString(16)
ab2hex: function (buffer) {
        var hexArr = Array.prototype.map.call(
          new Uint8Array(buffer), function (bit) {
            return (\'00\' + bit.toString(16)).slice(-2)
          }
        )
        return hexArr.join(\'\')
      }
  1. 根据serviceId获取characteristicId时需要采用for循环获取,不使用for循环会无法开启notify,使用for循环会开启两遍,两次开启UUID相同,但是第一次显示开启成功,第二次显示开启失败
  2. 实际读取串口发送数据的位置为wx.onBLECharacteristicValueChang,wx.readBLECharacteristicValue返回的res中只有接受信息是否成功的信息
  3. 问题:若手机蓝牙未启动,初始化页面无法成功开启蓝牙适配器,重新打开蓝牙后,页面无法重新开启蓝牙适配器
    解决:因为只在onLoad中定义了开始蓝牙适配器,没有在onShow中定义,通过《六》中来解决
    注意:必须在onShow中先进行判断,再选择是否调用wx.openBluetoothAdapter,否则在第一次启动页面的时候调用两次wx.openBluetoothAdapter,wx.showModal会显示两次(初始化页面的时候onLoad后会调用onShow)
版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: