• 微信小程序连接蓝牙


    准备工作:

    1:需要一个蓝牙板子和串口软件(卖蓝牙板子的商家会提供),手机上需要蓝牙调试助手(为了测试蓝牙是否正常连接)
    2:蓝牙板通过usb插入到电脑端
    3:安装好串口调试工具并打开连接上蓝牙
    4:打开手机蓝牙调试助手,连接上后进行读写操作,确认已正常连接通信
    准备工作完结!
    
    • 1
    • 2
    • 3
    • 4
    • 5

    直接上代码

    第一步:初始化蓝牙设备, onShow里面调用或者onLoad里面调用都可,看你的需求场景

    initBlue () {
        wx.openBluetoothAdapter({
          success: (res) => {
            wx.showToast({
              title: '正在搜索蓝牙设备...',
              icon: 'loading'
            })
            this.findBlue()
          },
          fail: (error) => {
            wx.showToast({
              title: '请开启蓝牙',
              icon: 'fails',
              duration: 1000
            })
            this.setData({ isTrigger: false })
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    第二步:搜索蓝牙设备

    findBlue(){
        wx.startBluetoothDevicesDiscovery({
          allowDuplicatesKey: true,
          interval: 0,
          powerLevel: 'high',
          success: (res) => {
            this.getBlue()//3.0
          },
          complete: () => {
            this.setData({ isTrigger: false })
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    第三步:拿到需要的蓝牙设备进行列表渲染

    getBlue () {
        wx.onBluetoothDeviceFound((devices) => {
          if (devices.devices[0].name.includes('demo')) {
            console.log(devices.devices[0].name, 'devices.devices[0].name')
            // 添加有名字的蓝牙设备,并去重处理
            this.setData({ bluetoolList: [...this.data.bluetoolList, devices.devices[0]].filter((obj, index, self) =>
              index === self.findIndex((t) => (
                  t.name === obj.name
              ))) })
            wx.stopBluetoothDevicesDiscovery() // 停止搜索
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    第四步:点击某个蓝牙设备进行连接

    connetBluetooth(evt) {
        wx.showToast({
          title: '正在连接...',
          icon: 'loading'
        })
        console.log(evt.currentTarget.dataset, '=========')
        const { row } = evt.currentTarget.dataset
        this.setData({ currentDeviceid: row.deviceId })
        wx.setStorageSync('deviceId', row.deviceId)
        wx.createBLEConnection({
          deviceId: row.deviceId,
          timeout: 5000,
          success: (res) => {
            console.log('connet success: ', res)
            wx.stopBluetoothDevicesDiscovery()
            this.getServiceUUid() // 连接的收就获取服务ID 用于后面获取特征值id(特征值id可以用来进行读、写、监听蓝牙操作)
          },
          fail: (error) => {
            console.log('createBLEConnection error: ', error)
            if (error.errCode === -1) { // 表示已经连接, 直接跳转到对应页面即可
              wx.navigateTo({ url: '/pages/xxx/xxx' })
            } else {
              wx.showToast({
                title: '连接失败',
                icon: 'error',
                timeout: 500,
                complete: () => {
                }
              })
            }
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    第五步:获取服务id,不同蓝牙设备,不同机型,获取的服务值不一样,根据你自己的蓝牙板子和机型来获取,一定要获取准确,错了就读写不了蓝牙设备

    getServiceUUid() {
        console.log('=====================getServiceUUid=======================')
        let _this = this
        wx.getBLEDeviceServices({
          // 这里的 deviceid 需要已经通过 createBLEConnection 与对应设备建立链接
          deviceId: _this.data.currentDeviceid,
          success: async (res) => {
            console.log('res.services: ', res.services)
            if (wx.getStorageSync('platform') === 'ios') {
              // read
              await _this.setData({ readServiceId: res.services[0].uuid })
              await wx.setStorageSync('readServiceId', res.services[0].uuid)
    
              // write true
              await _this.setData({ writeServiceId: res.services[1].uuid })
              await wx.setStorageSync('writeServiceId', res.services[1].uuid)
    
              // notify
              await _this.setData({ notifyServiceId: res.services[1].uuid })
              await wx.setStorageSync('notifyServiceId', res.services[1].uuid)
    
              await _this.getReadCharacteIdIos()
              await _this.getWriteCharacteIdIos()
    
            } else {
              // read true
              // _this.setData({ readServiceId: res.services[0].uuid })
              await _this.setData({ readServiceId: res.services[2].uuid })
              await wx.setStorageSync('readServiceId', res.services[2].uuid)
      
              // 第一个 write: true;第二个 notify: true
              await _this.setData({ writeServiceId: res.services[1].uuid })
              await wx.setStorageSync('writeServiceId', res.services[1].uuid)
    
              await _this.setData({ notifyServiceId: res.services[1].uuid })
              await wx.setStorageSync('notifyServiceId', res.services[1].uuid)
      
              // read true
              // await _this.setData({ readServiceId: res.services[2].uuid })
              // await wx.setStorageSync('readServiceId', res.services[2].uuid)
              
              // indicate 安卓端监听不到蓝牙发送过来的回调
              // await _this.setData({ notifyServiceId: res.services[3].uuid })
              // await wx.setStorageSync('notifyServiceId', res.services[3].uuid)
      
              await _this.getReadCharacteId()
              // await _this.getNotifyCharacteId()
              await _this.getWriteCharacteId()
            }
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    第六步:获取特征值id,并保证在了本地(也可以挂在全局,方便另一个页面获取),跳转到对应页面,这里你可以封装一下,我这里做demo就没封装,五个方法,分别获取IOS端和安卓端的对应读写和监听的特征值,一定要根据蓝牙的板子获取对应正确的特征值(为true的才能进行后面的连接和读写操作),慢慢调试

     // readServiceId
      getReadCharacteId() {
        let _this = this
        wx.getBLEDeviceCharacteristics({
          deviceId: _this.data.currentDeviceid,
          serviceId: _this.data.readServiceId,
          success: (res) => {
            console.log('res.haracteristics read: ', res.characteristics)
            for (let i = 0; i < res.characteristics.length; i++) {
              let characteristic = res.characteristics[i]
              // 检查特征值是否具有 read 属性为 false
              if (characteristic.properties.read) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                _this.setData({ characteReadId: characteristic.uuid })
                wx.setStorageSync('characteReadId', characteristic.uuid)
                // break // 找到符合条件的特征值后,结束循环
              }
            }
          },
          fail: (error) => {
            console.log('get read CharacteId error: ', error)
          }
        })
      },
      // use bluetool deviceId and uuid get characteId (特征值) writeServiceId
      getWriteCharacteId () {
        let _this = this
        wx.getBLEDeviceCharacteristics({
          deviceId: _this.data.currentDeviceid,
          serviceId: _this.data.writeServiceId,
          success: (res) => {
            // 遍历特征值列表
            console.log('res.characteristics write : ', res.characteristics)
            for (let i = 0; i < res.characteristics.length; i++) {
              let characteristic = res.characteristics[i]
              // 检查特征值是否具有 read 属性为 false
              if (characteristic.properties.write) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                _this.setData({
                  characteWriteId: characteristic.uuid
                })
                wx.setStorageSync('characteWriteId', characteristic.uuid)
                // break // 找到符合条件的特征值后,结束循环
              }
              if (characteristic.properties.notify) {
                _this.setData({ characteNotifyId: characteristic.uuid })
                wx.setStorageSync('characteNotifyId', characteristic.uuid)
              }
            }
            console.log('currentDeviceid: ', _this.data.currentDeviceid)
            console.log('----------------------read--------------------')
            console.log('readServiceId: ', _this.data.readServiceId)
            console.log('characteReadId: ', _this.data.characteReadId)
            console.log('----------------------write--------------------')
            console.log('writeServiceId: ', _this.data.writeServiceId)
            console.log('characteWriteId: ', _this.data.characteWriteId)
            wx.navigateTo({
              url: '/pages/action/action'
            })
            wx.hideToast()
          },
          fail: function (error) {
            console.log("error reason: ", error)
          }
        })
      },
      // notifyServiceId
      getNotifyCharacteId() {
        let _this = this
        wx.getBLEDeviceCharacteristics({
          deviceId: _this.data.currentDeviceid,
          serviceId: _this.data.notifyServiceId,
          success: (res) => {
            console.log('res.characteristics notify: ', res.characteristics)
            for (let i = 0; i < res.characteristics.length; i++) {
              let characteristic = res.characteristics[i]
              // 检查特征值是否具有 read 属性为 false
              if (characteristic.properties.indicate) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                _this.setData({ characteNotifyId: characteristic.uuid })
                wx.setStorageSync('characteNotifyId', characteristic.uuid)
                break // 找到符合条件的特征值后,结束循环
              }
            }
          },
          fail: (error) => {
            console.log('get notify CharacteId error: ', error)
          }
        })
      },
    
      // ios read characteId
      getReadCharacteIdIos() {
        wx.getBLEDeviceCharacteristics({
          deviceId: this.data.currentDeviceid,
          serviceId: this.data.readServiceId,
          success: (res) => {
            // 遍历特征值列表
            console.log('res.characteristics read : ', res.characteristics)
            for (let i = 0; i < res.characteristics.length; i++) {
              let characteristic = res.characteristics[i]
              // 检查特征值是否具有 read 属性为 false
              if (characteristic.properties.read) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                this.setData({
                  characteReadId: characteristic.uuid
                })
                wx.setStorageSync('characteReadId', characteristic.uuid)
                break // 找到符合条件的特征值后,结束循环
              }
            }
          }
        })
      },
      // ios write characteId
      getWriteCharacteIdIos() {
        wx.getBLEDeviceCharacteristics({
          deviceId: this.data.currentDeviceid,
          serviceId: this.data.writeServiceId,
          success: (res) => {
            // 遍历特征值列表
            console.log('res.characteristics write : ', res.characteristics)
            for (let i = 0; i < res.characteristics.length; i++) {
              let characteristic = res.characteristics[i]
              // 检查特征值是否具有 read 属性为 false
              if (characteristic.properties.write) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                this.setData({
                  characteWriteId: characteristic.uuid
                })
                wx.setStorageSync('characteWriteId', characteristic.uuid)
                // break // 找到符合条件的特征值后,结束循环
              }
              if (characteristic.properties.notify) {
                // 当找到 read 属性为 false 的特征值时,设置 writeId 为该特征值的 UUID
                this.setData({
                  characteNotifyId: characteristic.uuid
                })
                wx.setStorageSync('characteNotifyId', characteristic.uuid)
              }
              wx.navigateTo({
                url: '/pages/xxx/xxx'
              })
              wx.hideToast()
            }
          }
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148

    第七步:这时候已经跳转到对应页面了,在页面onLoad里开启监听,后面蓝牙发送设备到小程序可以实时监听到值

    async onLoad(options) {
        // 监听蓝牙发送到小程序的数据
        await wx.onBLECharacteristicValueChange((res) => {
          console.log('characteristicis: ', res.value)
          console.log('转换后的值: ', this.ab2hex(res.value))
          this.setData({ fromBlueToolsData: this.ab2hex(res.value) })
          // this.setData({ fromBlueToolsData: res.value })
        })
    
        await wx.readBLECharacteristicValue({
          deviceId: wx.getStorageSync('deviceId'),
          serviceId: wx.getStorageSync('readServiceId'),
          characteristicId: wx.getStorageSync('characteReadId'),
          success: (res) => {
            console.log('read data is: ', res)
          },
          fail: (error) => {
            console.log('read error, error message is: ', error)
          }
        })
    
        await wx.notifyBLECharacteristicValueChange({
          state: true,
          type: 'notification', // 根据你蓝牙的特征值来选择类型
          deviceId: wx.getStorageSync('deviceId'),
          serviceId: wx.getStorageSync('notifyServiceId'),
          characteristicId: wx.getStorageSync('characteNotifyId'),
          success: (res) => {
            console.log('notify success, success message is: ', res)
          },
          fail: (error) => {
            console.log('notify error, error message is: ', error)
            this.setData({ fromBlueToolsData: '' })
          }
        })
      },
    
      // 16 进制到 10进制
      ab2hex(buffer) {
        let hexArr = Array.prototype.map.call(
          new Uint8Array(buffer),
          function(bit) {
            return ('00' + bit.toString(16)).slice(-2)
          }
        )
        return hexArr.join('');
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    第八步:测试读写,看蓝牙串口与小程序是否有通信

    // 写入数据
    writeTap() {
        console.log('-----------------start write action----------------------------')
        console.log('inputValue: ', this.data.inputValue)
        let data = this.data.inputValue
        if (data.length === 0) {
          wx.showModal({ title: '提示', content: '请输入要发送的数据' })
          return
      }
        wx.writeBLECharacteristicValue({
          deviceId: wx.getStorageSync('deviceId'),
          serviceId: wx.getStorageSync('writeServiceId'),
          characteristicId: wx.getStorageSync('characteWriteId'),
          value: this.string2buffer(data), // 数据转换发送
          success (res) {
            console.log('writeBLECharacteristicValue success', res)
            this.setData({ inputValue: '' })
          },
          fail: (error) => {
            console.log('write error, error message is: ', error)
          }
        })
      },
      string2buffer(hexString) {
        hexString = hexString.replace(/^0x/, '');
        const bytes = new Uint8Array(hexString.length / 2);
        for (let i = 0; i < hexString.length; i += 2) {
            bytes[i / 2] = parseInt(hexString.substring(i, i + 2), 16);
        }
        console.log('写入的buffer:', bytes.buffer)
        return bytes.buffer;
      },
      // input输入值
      onWriteInput(evt) {
        const { value } = evt.detail
        this.setData({ inputValue: value })
      },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    最终测试后在ios与安卓上能够与蓝牙串口进行正常通信,完结!

  • 相关阅读:
    [极致用户体验] 你的 Link Button 能让用户选择新页面打开吗?
    SpFFmpeg音视频开发1:Linux开发环境下常用Shell脚本语法
    听书网站模板源码 懒人书院网站源码 苹果cms手机听书网站模版源码 支持手机端
    Maven生命周期
    C4D基础认识
    springboot学习一:idea社区版本创建springboot项目的三种方式(第三种日后更新,以第二种方法主)
    dolphinscheduler 2.0.6 任务之间的参数传递及Java脚本引擎
    jsp+ajax+json练习(表单数据检测)
    谷歌 I/O 2024大会全面硬钢OpenAI;腾讯宣布旗下的混元文生图大模型;阿里巴巴技术下的AI自动视频剪辑工具
    Flutter学习笔记——初识Flutter
  • 原文地址:https://blog.csdn.net/qq_43258522/article/details/137957024