微信小程序-蓝牙工具的开发

该蓝牙特性,发送数据不需加密,但每次发送操作命令,都需走登陆操作,在登陆操作成功后,notify方法里回调,执行相关命令操作。

js代码如下:

const base = getApp().constants;
var that
var temp = []
// 蓝牙通信需要使用的id
// 蓝牙设备 service(服务)Id
var blue_serviceId = ""
// 设备某个服务中的 characteristic(特征值)Id,不同特征值代表不同功能
var characteristicId = ""
Page({
  data: {

    //控制蓝牙状态
    isbluetoothready: false,
    // 蓝牙连接状态
    deviceconnected: false,
    //控制按钮的名称前是否带 loading 图标
    searchingstatus: false,
    //蓝牙notify返回值
    receivedata: '',
    nameString: 'blueNameTest-YHY',
    // 判断是不是开关灯操作
    isOperationLamp: false,
    //判断是开灯还是关灯
    isOpenLamp: true

  },
  onLoad: function () {
    that = this;
  },
  switchBlueTooth: function () {
    var that = this
    that.setData({
      isbluetoothready: !that.data.isbluetoothready,
    })

    if (that.data.isbluetoothready) {
      wx.openBluetoothAdapter({
        success: function (res) {
          console.log("初始化蓝牙适配器成功")
          //蓝牙适配器状态发生变化会回调该方法(监听蓝牙适配器状态变化事件)
          wx.onBluetoothAdapterStateChange(function (res) {
            console.log("蓝牙适配器状态变化", res)
            that.setData({
              isbluetoothready: res.available,
              searchingstatus: res.discovering
            })
          })
          //寻找到新设备的回调(监听寻找到新设备的事件)
          wx.onBluetoothDeviceFound(function (devices) {
            console.log(devices.devices[0])
            console.log('发现新蓝牙设备')
            temp.push(devices.devices[0])
            console.log('设备id' + devices.devices[0].deviceId)
            console.log('设备name' + devices.devices[0].name)
            that.setData({
              devices: temp
            })

          })
          //notify启动成功后,会回调这个方法(监听低功耗蓝牙设备的特征值变化。必须先启用notify接口才能接收到设备推送的notification。)
          wx.onBLECharacteristicValueChange(function (characteristic) {
            // 写入成功回调
            that.whiteSucess()
            console.log('characteristic value comed:')
            console.log(characteristic)
            //解析蓝牙返回数据
            let buffer = characteristic.value
            let dataView = new DataView(buffer)
            console.log("接收字节长度:" + dataView.byteLength)
            var str = ""
            for (var i = 0; i < dataView.byteLength; i++) {
              // str += String.fromCharCode(dataView.getUint8(i))
              str += dataView.getUint8(i).toString(16) + ','
              // console.log(dataView.getUint8(i))
              // console.log(str)
            }
            console.log(parseInt(str, 16))
            str = getNowFormatDate() + "收到数据:" + str;
            console.log(str)
            that.setData({
              receivedata: that.data.receivedata + "\n" + str,
            })

          })
        },
        fail: function (res) {
          console.log("初始化蓝牙适配器失败")
          wx.showModal({
            title: '提示',
            content: '请检查手机蓝牙是否打开',
            success: function (res) {
              that.setData({
                isbluetoothready: false,
                searchingstatus: false
              })
            }
          })
        }
      })
    } else {
      // 清空设备列表数组
      temp = []
      // 断开与低功耗蓝牙设备的连接
      wx.closeBLEConnection({
        deviceId: that.data.blue_deviceId,
        complete: function (res) {
          console.log(res)
          that.setData({
            deviceconnected: false,
            blue_deviceId: ""
          })
        }
      })
      // 关闭蓝牙模块,使其进入未初始化状态。
      wx.closeBluetoothAdapter({
        success: function (res) {
          console.log(res)
          that.setData({
            isbluetoothready: false,
            deviceconnected: false,
            devices: [],
            searchingstatus: false,
            receivedata: ''
          })
        },
        fail: function (res) {
          wx.showModal({
            title: '提示',
            content: '请检查手机蓝牙是否打开',
            success: function (res) {
              that.setData({
                isbluetoothready: false
              })
            }
          })
        }
      })
    }
  },
  //开始搜索附近蓝牙设备
  searchbluetooth: function () {
    temp = []
    var that = this
    if (!that.data.searchingstatus) {
      var that = this
      wx.startBluetoothDevicesDiscovery({
        // 云马lite主服务 UUID 为FF12
        services: ['1000'],
        success: function (res) {
          console.log("开始搜索附近蓝牙设备")
          console.log(res)
          that.setData({
            searchingstatus: !that.data.searchingstatus
          })
        }
      })
    } else {
      wx.stopBluetoothDevicesDiscovery({
        success: function (res) {
          console.log("停止蓝牙搜索")
          console.log(res)
        }
      })
    }
  },
  //设备连接
  connectTO: function (e) {
    var that = this
    if (that.data.deviceconnected) {
      //断开已有蓝牙连接
      wx.notifyBLECharacteristicValueChanged({
        state: false, // 停用notify 功能
        deviceId: that.data.blue_deviceId,
        serviceId: blue_serviceId,
        characteristicId: characteristicId,
        success: function (res) {
          console.log("停用notify 功能")
        }
      })
      wx.closeBLEConnection({
        deviceId: e.currentTarget.id,
        complete: function (res) {
          console.log("断开设备")
          console.log(res)
          that.setData({
            deviceconnected: false,
            blue_deviceId: "",
            receivedata: ""
          })
        }
      })
    } else {
      wx.showLoading({
        title: '连接蓝牙设备中...',
      })
      //用设备搜索时获取的id尝试连接,如果成功,则该id就为deviceId,
      console.log("deviceId=" + e.currentTarget.id)
      wx.createBLEConnection({

        deviceId: e.currentTarget.id,
        success: function (res) {
          wx.hideLoading()
          wx.showToast({
            title: '连接成功',
            icon: 'success',
            duration: 1000
          })
          console.log("连接设备成功,设备deviceId=" + e.currentTarget.id)
          console.log(res)
          that.setData({
            deviceconnected: true,
            //deviceId初始化
            blue_deviceId: e.currentTarget.id
          })

          // 获取serviceId
          wx.getBLEDeviceServices({
            // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 
            deviceId: that.data.blue_deviceId,
            success: function (res) {
              console.log("获取servicesId")
              console.log('device services列表:', res.services)
              //蓝牙的服务id列表,serviceId初始化
              // blue_serviceId = '00001000-0000-1000-8000-00805F9B34FB';
              blue_serviceId = res.services[1].uuid
              console.log('获取到servicesId:', res.services[1].uuid)
              // 获取characteristicId
              wx.getBLEDeviceCharacteristics({
                // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
                deviceId: that.data.blue_deviceId,
                // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
                serviceId: blue_serviceId,
                success: function (res) {
                  console.log('获取characteristicId成功')
                  console.log('device getBLEDeviceCharacteristics:', res.characteristics)
                  // characteristicId = '0000FF02-0000-1000-8000-00805F9B34FB';
                  //启用notify

                }, fail: function (res) {
                  console.log(res)
                  console.log("获取characteristicId失败")
                }
              })

            }, fail: function (res) {
              console.log(res)
              console.log("获取servicesId失败")
            }
          })


        },
        fail: function (res) {
          wx.hideLoading()
          wx.showToast({
            title: '连接设备失败',
            icon: 'success',
            duration: 1000
          })
          console.log("连接设备失败")
          console.log(res)
          that.setData({
            connected: false
          })
        }
      })
      wx.stopBluetoothDevicesDiscovery({
        success: function (res) {
          console.log("停止蓝牙搜索")
          console.log(res)
        }
      })
    }
  },
  openNotifyAction: function () {
    // 启用 notify 功能
    wx.notifyBLECharacteristicValueChanged({
      state: true,
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
      deviceId: that.data.blue_deviceId,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: blue_serviceId,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: '00001002-0000-1000-8000-00805F9B34FB',
      success: function (res) {
        console.log(res)
        console.log("启用notify成功")
      },
      fail: function (res) {
        console.log(res)
        console.log("启用notify失败")
      }
    })
  },
  closeNotifyAction: function () {
    wx.notifyBLECharacteristicValueChanged({
      state: false, // 停用notify 功能
      deviceId: that.data.blue_deviceId,
      serviceId: blue_serviceId,
      characteristicId: '0000FF02-0000-1000-8000-00805F9B34FB',
      success: function (res) {
        console.log("停用notify 功能")
      }
    })
  },
  //输入框
  inputAction: function (e) {
    console.log(e.detail.value)
    this.setData({
      nameString: e.detail.value
    })
  },
  //登陆蓝牙,云马lite蓝牙,不需要加密通信,全程命令只需要登陆命令成功,后发送业务命令
  getToken() {
    //手机往模块写入通道(特征值)0001001-0000-1000-8000-00805F9B34FB 
  //手机读取模块的通道(特征值) 00001002-0000-1000-8000-00805F9B34FB
    characteristicId = '00001001-0000-1000-8000-00805F9B34FB'
    //主服务Id
    // var serviceId = '00001000-0000-1000-8000-00805F9B34FB';
    //获取token命令0xAA0x79
    // var unlock = "AA0B790000000000000084";
    //16进制的通信帧  
    // var unlock = "0xAA,0x0b,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x84";
    //10进制的通信帧   
    // var unlock = '170, 11, 121, 0, 0, 0, 0, 0, 0, 0, 131';
    var value = 'AA,0B,79,00,00,00,00,00,00,00,84'
    that.writeChar(that.data.blue_deviceId, blue_serviceId, characteristicId, value);

    // 通信帧讲解
    // 帧头   帧长  命令  口令  数据  校验
    // 1B    1B    1B     4B      N字节 1B
    // 帧头占用1个字节,其内容固定为“0xAA”
    // 帧长为整一帧数据的字节长度,即N + 8。
    // 命令占用1个字节(具体值看列表)
    // 口令占用4个字节(默认为0x00,0x00,0x00,0x00)
    // 数据,长度N的取值范围为0~8(具体值看列表)
    // 校验码占用1个字节,其值为前面除帧头外N + 6个字节的校验和。
    //以登陆命令为例
    //帧头 0xAA
    //口令  0x00,0x00,0x00,0x00
    //命令 0x79(121)
    //数据 3个字节
    //帧长 为数据的长度(3)+8=11  为 0x0B
    //校验 为帧长(11)+命令(121)+口令(0)+数据(0)= 131 为 0x84
    // 帧头 帧长 命令  口令           数据           校验
    // 'AA, 0B, 79, 00, 00, 00, 00, 00, 00, 00, 84'
  },
  openLampAction: function (e) {
    if (that.data.isOperationLamp) {
      var characteristicId = '00001001-0000-1000-8000-00805F9B34FB'
      if (that.data.isOpenLamp) {
        // var unlock = '170, 9, 131, 0, 0, 0, 0, 1, 141';
        var value = 'AA,09,83,00,00,00,00,01,8D'
        console.log('开灯')
      } else {
        // var unlock = '170, 9, 131, 0, 0, 0, 0, 0, 141';
        var value = 'AA,09,83,00,00,00,00,00,8c'
        console.log('关灯')
      }
      that.writeChar(that.data.blue_deviceId, blue_serviceId, characteristicId, value);
      that.setData({
        isOperationLamp: false
      })
    } else {
      that.getToken()
      that.setData({
        isOperationLamp: true
      })
      console.log('灯' + e.currentTarget.dataset.typestring)
      if (e.currentTarget.dataset.typestring == 'open') {
        that.setData({
          isOpenLamp: true
        })
      } else {
        that.setData({
          isOpenLamp: false
        })
      }
    }

  },
  bicycleData: function(){
    var characteristicId = '00001002-0000-1000-8000-00805F9B34FB'
    // var unlock = '170, 8, 1, 0, 0, 0, 0, 0, 9';
    var value = 'AA,08,01,00,00,00,00,09'
    that.readChar(that.data.blue_deviceId, blue_serviceId, characteristicId);
  },
  //手机与蓝牙模块通信,写入操作
  writeChar: function (mac, svId, charId, value) {
    // 16进制字符串 转 ArrayBuffer 实例:'AA,0B,79,00,00,00,00,00,00,00,84'
    var hex = value
    var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
      // console.log(parseInt(h, 16))
      return parseInt(h, 16)
    }))
    var buffer = typedArray.buffer
    wx.writeBLECharacteristicValue({
      deviceId: mac, // 蓝牙设备 id,参考 device 对象
      serviceId: svId, // 蓝牙特征值对应 service 的 uuid
      characteristicId: charId, // 蓝牙特征值的 uuid
      value: buffer, // 蓝牙设备特征值对应的二进制值
      success: (res) => {
        console.log("写入成功");
        wx.showToast({
          content: '写入成功', // 文字内容
        });
      },
      fail: (e) => {
        console.log("写入失败");
        wx.showToast({
          content: '写入失败', // 文字内容
        });
      }
    });
  },
  // 写入成功,notify回调
  whiteSucess: function () {
    if (that.data.isOperationLamp) {
      //开关灯
      that.openLampAction()
    } else {

      console.log('无后续处理')
    }

  },
  //清空显示数据
  clearAction: function () {
    that.setData({
      receivedata: ''
    })
  },
  readChar: function (mac, svId, charId) {
    wx.readBLECharacteristicValue({
      // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  [**new**]
      deviceId: mac,
      // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
      serviceId: svId,
      // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
      characteristicId: charId,
      success: function (res) {

        console.log('获取,成功:', res.errCode)
      },
      fail: function (res) {
        console.log('获取,失败')
        console.log(res)

      }
    })
  }
})

//处理当前时间
function getNowFormatDate() {
  var date = new Date();
  var seperator1 = "-";
  var seperator2 = ":";
  var month = date.getMonth() + 1;
  var strDate = date.getDate();
  if (month >= 1 && month <= 9) {
    month = "0" + month;
  }
  if (strDate >= 0 && strDate <= 9) {
    strDate = "0" + strDate;
  }
  var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
    + " " + date.getHours() + seperator2 + date.getMinutes()
    + seperator2 + date.getSeconds();
  return currentdate;
}

wxml代码如下:



  
    
      蓝牙初始化:
      {{isbluetoothready?"ok":"尚未初始化"}}
    
    
      
    
  

  
  
    
  


  
  
     数据接收:
    
    
    
    
      

      启用Notify

      停用Notify

      登陆

      清空显示

      开灯
      关灯
      获取车体数据包

    
    

  


wxcss代码如下:

view {
  display: inline-block;
}

.container {
  padding: 0;
  margin: 0;
  align-items: flex-start;
}
.content {
  margin: auto;
  padding: auto;
  position: absolute;
  top: 5px;
  left: 10px;
}
button {
  background: red;
}

.list-item {
  margin-top: 20rpx;
  margin-bottom: 20rpx;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  border: 1px dashed #000;
}

.list-item text {
  margin-top: 10rpx;
}

.list-item button {
  margin-right: 10rpx;
}

.deviceconnected {
  background-color: sandybrown;
}

.recieve {
  width: 100%;
}

.recieve textarea {
  border: 1px dashed;
  width: 100%;
}

/* 顶部view */
.section_top {
  margin-top: 100rpx;
  display: inline-block;
  width: calc(100vw - 60rpx);
  margin-left: 30rpx;
  position: relative;
  border: 1px dashed;
}
.switch {
  position: relative;
  float: right;
  right: 0px;
}
/* 设备cell */
.section {
  margin-top: 30rpx;
  display: inline-block;
  width: calc(100vw - 60rpx);
  margin-left: 30rpx;
  position: relative;
}
/* 连接后的操作view */

.connectionView {
  font-size: 30rpx;
  width: 100vw;
  /* background-color: bisque; */
}

.textareaView {
  font-size: 26rpx;
  width: calc(100vw - 60rpx);
  /* height: auto; */
  margin-left: 30rpx;
  /* background-color: burlywood; */
  border: 1px dashed;
}

.controlView {
  /* margin-top: 30rpx; */
  width: calc(100vw - 60rpx);
  margin-left: 30rpx;
  height: 800rpx;
  border-bottom: 1px dashed; 
   /* background-color: brown;  */
}

.inputView {
  width: 100%;
  height: 66rpx;
  margin-bottom: 30rpx;
  margin-top: 30rpx; 
  border: 1px dashed;
}

.BtnView_left {
  margin-top: 30rpx;
  width: calc((100vw - 60rpx)*0.4);
  height: 66rpx;
  line-height: 66rpx;
  text-align: center;
  background-color: rgba(240, 91, 72, 1);
  color: white;
  float: left;
  border-radius: 15rpx;
}

.BtnView_right {
  margin-top: 30rpx;
  width: calc((100vw - 60rpx)*0.4);
  height: 66rpx;
  line-height: 66rpx;
  text-align: center;
  background-color: rgba(240, 91, 72, 1);
  color: white;
  float: right;
  border-radius: 15rpx;
}

.hover_BnView {
  background-color: rgba(240, 91, 72, 0.5);
}

你可能感兴趣的:(微信小程序-蓝牙工具的开发)