微信小程序连接蓝牙模块发送数据的详解以及封装版

连接蓝牙

  • 前言
  • 详解
    • 小程序链接蓝牙流程图
    • 需要的数据
    • api
      • openBluetoothAdapter:打开蓝牙适配器
      • getBluetoothAdapterState:查看蓝牙适配器状态
      • startBluetoothDevicesDiscovery:开始搜索蓝牙设备
      • getBluetoothDevices:获取所有已发现的所有蓝牙设备
      • createBLEConnection:连接蓝牙设备
      • stopBluetoothDevicesDiscovery:停止扫描设备
      • getBLEDeviceServices:获取连接设备的service服务
      • getBLEDeviceCharacteristics:获取连接设备具有读写功能服务的所有特征值
      • notifyBLECharacteristicValueChange:启动蓝牙设备特征值变化
      • onBLECharacteristicValueChange:监听蓝牙特征值变化
      • writeBLECharacteristicValue:向蓝牙写入数据
      • closeBluetoothAdapter:关闭蓝牙
    • 字符串与16进制的转换
      • 16进制转字符串
      • 字符串转16进制
  • 封装版
    • 步骤一
    • 步骤二
    • 步骤三
    • 步骤四
    • 步骤五

前言

  • 我是在给我们实验室小程序添加开锁功能的时候用到的蓝牙,做完之后我来总结一下。
  • 如果你是想要学习微信小程序的蓝牙api,你可以看详解部分
  • 如果你是单纯的想用一下的话,你就去看封装版部分,其中有详细的使用步骤
  • 还有一点要注意:小程序只支持蓝牙4.0的协议,不支持2.0的协议,我之前用的hc-06蓝牙模块它是给2.0的协议,小程序一直找不到,换成hc-08的蓝牙模块就能找到了

详解

小程序调用蓝牙需要一步一步使用很多api,我会给你们把每个api的作用给讲清楚,我学的时候看了b站的视频,质量并不是很高,但也可以看一下

小程序链接蓝牙流程图

微信小程序连接蓝牙模块发送数据的详解以及封装版_第1张图片

需要的数据

deviceId:"00:00:00:00:00:00",//蓝牙设备id,每个蓝牙都不一样,可以先用手机手动连一下,手机上会有id,要我们写
serviceUUIDSamll:'FFE0',//蓝牙可用服务id,用于查询我们要寻找的服务,我们买蓝牙模块时候文档里或者他的官网上会有,要我们写
serviceUUID:'',//蓝牙服务id全名,用作参数调用小程序api, serviceId程序会自动获取
notifyCharacteristicId:'',//该服务的notify特征值,自动获取
writeCharacteristicId:'',//该服务的write特征值,自动获取
msg:"这是你要给蓝牙发送的数据"//要给蓝牙发送的数据,这个我们要手动写

api

openBluetoothAdapter:打开蓝牙适配器

打开蓝牙适配器,成功表明手机蓝牙已打开。
这是判断手机是否打开蓝牙功能

 openBluetoothAdapter(){
     
   var that=this;
   wx.openBluetoothAdapter({
     
     success: function (res) {
     
       console.log("蓝牙已打开")
     },
     fail: function(res){
     
       console.log("蓝牙未打开")
     }
   })
 },

getBluetoothAdapterState:查看蓝牙适配器状态

查看蓝牙适配器状态,只要打开蓝牙一般都会成功返回

  getBluetoothAdapterState(){
     
    var that=this;
    wx.getBluetoothAdapterState({
     
      success: (result) => {
     
        console.log("蓝牙状态:\n"+result.errMsg)
      },
      fail: (res) => {
     
        console.log("蓝牙状态:\n"+res.errMsg)
      }
    })
  },

startBluetoothDevicesDiscovery:开始搜索蓝牙设备

小程序开始搜索蓝牙设备,如果你不关闭他,他会一直搜索,后面会有关闭的api

startBluetoothDevicesDiscovery(){
     
    var that=this;
    wx.startBluetoothDevicesDiscovery({
     
      success: (res) => {
     
        //打印调试日志
        console.log("搜索设备返回"+JSON.stringify(res))
      },
      fail: (res) => {
     
        console.log("搜索设备失败")
      }
    })
  },

getBluetoothDevices:获取所有已发现的所有蓝牙设备

获取所有已发现的所有蓝牙设备,之前都是一些准备工作,我们在这里判断是否搜索到我们想要的蓝牙,如果我们发现了我们的蓝牙,我们就可以连接蓝牙设备,然后停止扫描设备。

getBluetoothDevices :function(){
     
    var that=this;
    wx.getBluetoothDevices({
     
      success: (res) => {
     
        res.devices.forEach((device,i)=>{
     
          if(device.deviceId==that.data.deviceId){
     
            console.log("物联网设备已找到")
            return;
          }
        })
      }
    })
  },

createBLEConnection:连接蓝牙设备

连接我们的蓝牙设备,需要我们蓝牙的id,这个id我们在data中提前写上

createBLEConnection: function(){
     
    var that =this;
    wx.createBLEConnection({
     
      deviceId: that.data.deviceId,
      success: function(res){
     
        console.log('连接设备返回:'+res.errMsg);
      },
      fail:function(res){
     
        console.log("调用失败")
      }
    })
  },

stopBluetoothDevicesDiscovery:停止扫描设备

我们连接到蓝牙,就可以停止扫描蓝牙了

stopBluetoothDevicesDiscovery(){
     
    var that =this;
    wx.stopBluetoothDevicesDiscovery({
     
      success: (res) => {
     
        console.log("停止扫描设备")
      },
    })
  },

getBLEDeviceServices:获取连接设备的service服务

获取已连接蓝牙的所有服务,需要蓝牙的deviceId
一个蓝牙有许多服务,但是只有某些服务是我们需要用的,我们可以从蓝牙协议文档上查看我们所需要服务的id,通过id来获取该服务

getBLEDeviceServices(){
     
    var that =this;
    wx.getBLEDeviceServices({
     
      deviceId: that.data.deviceId,
      success:(res)=>{
     
        for(var i=0;i<res.services.length;i++){
     
          //把服务id放到数组中
          if(res.services[i].uuid.toUpperCase().indexOf(that.data.serviceUUIDSamll)!=-1){
     
            console.log("服务已找到")
            that.setData({
     
              serviceUUID:res.services[i].uuid
            })
          }
        }
      }
    })
  },

getBLEDeviceCharacteristics:获取连接设备具有读写功能服务的所有特征值

获取连接设备具有读写功能服务的所有特征值,需要deviceId和服务的id:serviceId
每个服务都有许多特征值,我们获取我们所需要的特征值

getBLEDeviceCharacteristics(){
     
    var that=this;
    wx.getBLEDeviceCharacteristics({
     
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceUUID,
      success: (res) => {
     
        //获取特征值
        console.log("-----------------------")
        for(var i=0;i<res.characteristics.length;i++){
     
          //把特征值id输出到控制台
          console.log("获取到的特征值id:"+res.characteristics[i].uuid)
          if(res.characteristics[i].properties.notify){
     
            console.log("开启notify的characteristicId:"+res.characteristics[i].uuid);
            this.setData({
     
              notifyCharacteristicId:res.characteristics[i].uuid
            })
          }
          //res.characteristics[i].properties.write
          if(res.characteristics[i].properties.write){
     
            console.log("开启write的characteristicId:"+res.characteristics[i].uuid);
            this.setData({
     
              writeCharacteristicId:res.characteristics[i].uuid
            })
          }
          if(res.characteristics[i].properties.read){
     
            console.log("开启read的characteristicId:"+res.characteristics[i].uuid);
          }
        }
        //把数据写道data中
        that.setData({
     
          characteristics:res.characteristics
        })
      },
      fail: (res) => {
     },
      complete: (res) => {
     },
    })
  }

notifyBLECharacteristicValueChange:启动蓝牙设备特征值变化

启动蓝牙设备特征值变化

notifyBLECharacteristicValueChange(){
     
  var that=this;
  wx.notifyBLECharacteristicValueChange({
     
    characteristicId: that.data.notifyCharacteristicId,
    deviceId: that.data.deviceId,
    serviceId: that.data.serviceUUID,
    state: true,
    success:(res)=>{
     
      console.log("notifyBLECharacteristicValueChange success:"+res.errMsg)
      that.setData({
     
        info:"成功"
      })
    },
    fail:(res)=>{
     
      console.log("notifyBLECharacteristicValueChange fail:"+res.errMsg)
      that.setData({
     
        info:"失败"
      })
    },
  })
},

onBLECharacteristicValueChange:监听蓝牙特征值变化

监听蓝牙特征值变化:见名知意,获取蓝牙特征值的改变
onBLECharacteristicValueChange(){
var that=this;
wx.onBLECharacteristicValueChange((res) => {
//console.log(“接收到的数据:”+that.ab2hex(res.value))
console.log(“接收到的数据:”+res.value)
})
},

writeBLECharacteristicValue:向蓝牙写入数据

向蓝牙写入数据,

 writeBLECharacteristicValue(){
     
    var that =this;
    // let buffer =new ArrayBuffer(1);
    
    // let dataView=new DataView(buffer)
    // dataView.setUint8(1,1)
    let buffer = that.stringToBytes(that.data.msg);
    console.log("开始发送指令")


    //写入数据
    wx.writeBLECharacteristicValue({
     
      characteristicId: that.data.writeCharacteristicId,
      deviceId: that.data.deviceId,
      serviceId: that.data.serviceUUID,
      value: buffer,
      success:function(res){
     
        console.log("返回信息:"+res.errMsg)
      }
    })
  },

closeBluetoothAdapter:关闭蓝牙

我们使用完蓝牙后要及时关闭,不然其他人就连不上了

closeBluetoothAdapter(){
     
    wx.closeBluetoothAdapter({
     
      success: (res) => {
     
        console.log("已关闭蓝牙");
      },
      fail:(res)=>{
     
        console.log("蓝牙未能关闭");
      }
    })
  },

字符串与16进制的转换

蓝牙需要16进制的数据,并且他传给小程序的也是16进制数据,小程序输入输出用的都是字符串,所以接收数据时我们要把16进制转成字符串,发送数据时,我们需要把字符串转成16进制

16进制转字符串

ab2hex(buffer){
     
    var hexArr =Array.prototype.map.call(
      new Uint16Array(buffer),
      function(bit){
     
        return ('00'+bit.toString(16).slice(-2))
      }
    )
    return hexArr.join('');
  },

字符串转16进制

stringToBytes(str) {
     
    var array = new Uint8Array(str.length);
    for (var i = 0, l = str.length; i < l; i++) {
     
      array[i] = str.charCodeAt(i);
    }
    console.log(array);
    return array.buffer;
  }

封装版

这是封装版,由于连续调一堆api会有回调地狱,我用promise来把api存起来

步骤一

在我们小程序项目根目录创建一个文件夹,里面是一个js文件
在这里插入图片描述
js文件中的代码是

  //1.打开蓝牙适配器
  export const openBluetoothAdapter=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.openBluetoothAdapter({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
          wx.showToast({
     
            title: '请打开蓝牙',
            icon: 'none'
          })
        }
      })
    })
  }
    //2.查看蓝牙适配器状态
  export const getBluetoothAdapterState=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.getBluetoothAdapterState({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '请打开蓝牙',
            icon: 'none'
          })
          reject(err);
        }
      })
    })
  }
    //3.搜索设备
  export const startBluetoothDevicesDiscovery=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.startBluetoothDevicesDiscovery({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '搜索设备失败',
            icon: 'none'
          })
          reject(err);
        }
      })
    })
  }
    //4.获取蓝牙设备信息
  export const getBluetoothDevices=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.getBluetoothDevices({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '未获取到设备信息',
            icon: 'none'
          })
          reject(err);
        }
      })
    })
  }
    //5.连接设备
  export const createBLEConnection=(deviceId)=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.createBLEConnection({
     
        deviceId:deviceId,
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '未连接到蓝牙,可能是设备没通电',
            icon: 'none'
          })
          reject(err);
        }
      })
    })
  }
    //6.停止扫描设备
  export const stopBluetoothDevicesDiscovery=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.stopBluetoothDevicesDiscovery({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
        }
      })
    })
  }
    //7.获取连接设备的service服务
  export const getBLEDeviceServices=(deviceId)=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.getBLEDeviceServices({
     
        deviceId:deviceId,
        success: (result) => {
     
          console.log("成功")
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '未能获取服务',
          })
          reject(err);
        }
      })
    })
  }
    //8.获取连接设备具有读写功能服务的所有特征值
  export const getBLEDeviceCharacteristics=(deviceId,serviceId)=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.getBLEDeviceCharacteristics({
     
        deviceId:deviceId,
        serviceId:serviceId,
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
        }
      })
    })
  }
      //9.启动蓝牙设备特征值变化
  export const notifyBLECharacteristicValueChange=(deviceId,serviceId,notifyCharacteristicId)=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.notifyBLECharacteristicValueChange({
     
        deviceId:deviceId,
        serviceId:serviceId,
        characteristicId:notifyCharacteristicId,
        state:true,
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
        }
      })
    })
  }
      //10.接受蓝牙发送的数据
  export const onBLECharacteristicValueChange=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.onBLECharacteristicValueChange({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
        }
      })
    })
  }
      //11.向蓝牙写入数据
  export const writeBLECharacteristicValue=(deviceId,serviceId,writeCharacteristicId,value)=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.writeBLECharacteristicValue({
     
        deviceId:deviceId,
        serviceId:serviceId,
        characteristicId:writeCharacteristicId,
        value:value,
        success: (result) => {
     
          wx.showToast({
     
            title: '已成功发送数据,蓝牙已打开',
          })
          resolve(result);
        },
        fail: (err)=>{
     
          reject(err);
        }
      })
    })
  }
      //12.关闭蓝牙
  export const closeBluetoothAdapter=()=>{
     
    return new Promise((resolve,reject)=>{
     
      wx.closeBluetoothAdapter({
     
        success: (result) => {
     
          resolve(result);
        },
        fail: (err)=>{
     
          wx.showToast({
     
            title: '数据发送成功,但未关闭蓝牙,请手动关闭',
            icon:'none'
          })
          reject(err);
        }
      })
    })
  }

步骤二

在我们需要连接蓝牙的页面的js文件中引入上面的js文件,写在文件最上面
注意:我引入时用的相对路径

import{
     openBluetoothAdapter,getBluetoothAdapterState,startBluetoothDevicesDiscovery,getBluetoothDevices,createBLEConnection,stopBluetoothDevicesDiscovery,getBLEDeviceServices,getBLEDeviceCharacteristics,notifyBLECharacteristicValueChange,onBLECharacteristicValueChange,writeBLECharacteristicValue,closeBluetoothAdapter} from "../../request/lanya.js";

步骤三

在我们需要连接蓝牙的页面的js文件的data里,加上必要的数据

//蓝牙相关信息
    deviceId:"00:00:00:00:00:00",//蓝牙设备id,每个蓝牙都不一样
    serviceUUIDSamll:'FFE0',//蓝牙可用服务id,用于查询我们要寻找的服务
    serviceId:'',//蓝牙服务id全名,用作参数调用小程序api
    notifyCharacteristicId:'',//该服务的notify特征值
    writeCharacteristicId:'',//该服务的write特征值
    msg:"1"//要给蓝牙发送的数据

步骤四

在我们需要连接蓝牙的页面的js文件中,添加上三个方法

  //向蓝牙发送数据
  async sendMsg(){
     
    var that=this;
    //1.打开蓝牙适配器
    var res=await openBluetoothAdapter();
    console.log("已蓝牙适配器")
    //2.查看蓝牙适配器状态
    res=await getBluetoothAdapterState();
    console.log("已查看蓝牙适配器状态")
    //3.搜索设备
    res =await startBluetoothDevicesDiscovery();
    console.log("已搜索设备")
    //4.获取蓝牙设备信息,停一秒再获取
    res =await getBluetoothDevices();
      console.log("已获取蓝牙设备信息") 
    //5.连接设备
    res =await createBLEConnection(that.data.deviceId);
    console.log("已连接设备")
    //6.停止扫描设备
    res =await stopBluetoothDevicesDiscovery();
    console.log("已停止扫描设备")
    //7.获取连接设备的service服务
    res =await getBLEDeviceServices(that.data.deviceId);
    for(let i=0;i<res.services.length;i++){
     
      //把服务id放到数组中
      if(res.services[i].uuid.toUpperCase().indexOf(that.data.serviceUUIDSamll)!=-1){
     
        console.log("服务已找到")
        that.setData({
     
          serviceId:res.services[i].uuid
        })
        break;
      }
    }
    console.log("已获取连接设备的service服务")
    //8.获取连接设备具有读写功能服务的所有特征值
    res =await getBLEDeviceCharacteristics(that.data.deviceId,that.data.serviceId);
    for(var i=0;i<res.characteristics.length;i++){
     
      //把特征值id输出到控制台
      console.log("获取到的特征值id:"+res.characteristics[i].uuid)
      if(res.characteristics[i].properties.notify){
     
        console.log("开启notify的characteristicId:"+res.characteristics[i].uuid);
        this.setData({
     
          notifyCharacteristicId:res.characteristics[i].uuid
        })
      }
      //res.characteristics[i].properties.write
      if(res.characteristics[i].properties.write){
     
        console.log("开启write的characteristicId:"+res.characteristics[i].uuid);
        this.setData({
     
          writeCharacteristicId:res.characteristics[i].uuid
        })
      }
    }
    console.log("已获取连接设备具有读写功能服务的所有特征值")
    //9.启动蓝牙设备特征值变化
    res =await notifyBLECharacteristicValueChange(that.data.deviceId,that.data.serviceId,that.data.notifyCharacteristicId);
    console.log("已启动蓝牙特征值变化")
    //10.向蓝牙写入数据
    let buffer = that.stringToBytes(that.data.msg);
    res =await writeBLECharacteristicValue(that.data.deviceId,that.data.serviceId,that.data.writeCharacteristicId,buffer);
    console.log("已发送数据");
    //11.关闭蓝牙
    res =await closeBluetoothAdapter();
  },
  //byte转字符串
  ab2hex(buffer){
     
    var hexArr =Array.prototype.map.call(
      new Uint16Array(buffer),
      function(bit){
     
        return ('00'+bit.toString(16).slice(-2))
      }
    )
    return hexArr.join('');
  },
  // 字符串转byte
  stringToBytes(str) {
     
    var array = new Uint8Array(str.length);
    for (var i = 0, l = str.length; i < l; i++) {
     
      array[i] = str.charCodeAt(i);
    }
    console.log(array);
    return array.buffer;
  }

步骤五

当你想要连接蓝牙并发送数据的时候,你只需要在data中填写好相关数据,然后直接调用sendMsg方法即可

你可能感兴趣的:(微信小程序,蓝牙,小程序)