使用微信小程序控制蓝牙小车(微信小程序端)

目录

使用接口

微信小程序官方开发文档

接口 说明
wx.openBluetoothAdapter 初始化蓝牙模块
wx.closeBluetoothAdapter 关闭蓝牙模块(调用该方法将断开所有已建立的连接并释放系统资源)
wx.startBluetoothDevicesDiscovery 开始搜寻附近的蓝牙外围设备
wx.stopBluetoothDevicesDiscovery 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时,建议调用该接口停止蓝牙搜索
wx.onBluetoothDeviceFound 监听搜索到新设备的事件
wx.createBLEConnection 连接蓝牙低功耗设备
wx.closeBLEConnection 断开与蓝牙低功耗设备的连接
wx.getBLEDeviceServices 获取蓝牙低功耗设备所有服务
wx.getBLEDeviceCharacteristics 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
wx.readBLECharacteristicValue 读取蓝牙低功耗设备特征值的二进制数据
wx.writeBLECharacteristicValue 向蓝牙低功耗设备特征值中写入二进制数据
wx.showToast 显示消息提示框

界面效果


图片素材库地址

项目目录列表

界面设计

  1. app.json中添加一个新页面"pages/home/home"
javascript 复制代码
{
  "pages":[
    "pages/home/home",
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle":"black"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}
  1. 设计界面home.wxml
xml 复制代码
<!--pages/home/home.wxml-->
<button type="primary" class = "connectBLE" bindtap = "openBluetoothAdapter">连接蓝牙</button>
<button class = "disconnectBLE" bindtap = "closeBluetoothAdapter">断开蓝牙</button>  

<button class="custom-button" style="bottom: -395px" bindtap = "btnClickDown">
  <image class="button-image" src="/image/doubledown.png"></image>
</button>

<button class="custom-button" style="bottom: -15px" bindtap = "btnClickUp">
  <image class="button-image" src="/image/doubleup.png"></image>
</button>

<view>
  <button class="custom-button" style="bottom: -60px; left: -35%" bindtap = "btnClickLeft">
    <image class="button-image-1" src="/image/doubleleft.png"></image>
  </button>
</view>

<view>
  <button class="custom-button" style="bottom: 40px; left: 35%" bindtap = "btnClickRight">
    <image class="button-image-1" src="/image/doubleright.png"></image>
  </button>
</view>

<view>
  <button class="custom-button" style="bottom: 134px; left: 0%" bindtap = "btnClickStop">
    <image class="button-image-2" src="/image/remove.png"></image>
  </button>
</view>
  1. 画面渲染home.wxss
css 复制代码
/* pages/home/home.wxss */
.connectBLE {
  width: 49% !important;
  float: left;
  font-size: 100;
}

.disconnectBLE {
  width: 49% !important;
  float: right;
  font-size: 100;
  color: red;
}

.custom-button {
  position: relative;
  width: 100px;
  height: 100px;
  border: none;
  padding: 0;
  overflow: hidden;
  background: transparent;   /*设置背景颜色一致*/
  border-color: transparent; /*设置边框颜色一致*/
}

.button-image {
  object-fit: contain;
  width: 75%;
  height: 110%;
}

.button-image-1 {
  object-fit: contain;
  width: 75%;
  height: 110%;
}

.button-image-2 {
  object-fit: contain;
  width: 60%;
  height: 100%;
}

界面逻辑设计

连接的目标蓝牙名称为ESP_SPP_SERVER

javascript 复制代码
// pages/home/home.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    connected: false,
    serviceId: "",
  },

  //蓝牙初始化
  openBluetoothAdapter() {
    if(this.data.connected)
    {
      return
    }
    wx.openBluetoothAdapter({
      success: (res) => {
        console.log('bluetooth initialization success', res)
        this.startBluetoothDevicesDiscovery()
      },
      fail: (err) => {
        wx.showToast({
          title: '蓝牙适配器初始化失败',
          icon: 'none'
        })
        return
      }
    })
  },
  //关闭蓝牙初始化
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter({
      success: (res) => {
        console.log('bluetooth deinitialization success', res)
      },
      fail: (err) => {
        wx.showToast({
          title: '蓝牙适配器解初始化失败',
          icon: 'none'
        })
        return
      }
    })
  },
  //开始搜寻附近的蓝牙外围设备
  startBluetoothDevicesDiscovery() {
    wx.startBluetoothDevicesDiscovery({
      success: (res) => {
        console.log('startBluetoothDevicesDiscovery success', res)
        this.onBluetoothDeviceFound()
      },
      fail: (err) => {
        wx.showToast({
          title: '蓝牙适配器解初始化失败',
          icon: 'none'
        })
        return
      }
    })
  },
  //监听搜索到新设备的事件
  onBluetoothDeviceFound() {
    let found_device = false
    const timer = setTimeout(() => {
      if (!found_device) {
        console.error('未找到设备');
        wx.showToast({
          title: '未找到设备',
          icon: 'none'
        })
      }
    }, 2000); // 设置定时器为10秒
  
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (device.name === 'ESP_SPP_SERVER') {
          console.log('find target device')
          found_device = true; // 找到目标设备,将标志变量设置为已找到
          clearTimeout(timer); // 取消定时器
          this.createBLEConnection(device.deviceId)
        }
      });
    });
  },
  //连接蓝牙低功耗设备
  createBLEConnection(deviceId) {
    wx.createBLEConnection({
      deviceId,
      success:() => {
        this.setData({
          connected: true,
        })
        console.log('connect device success')
        this.getBLEDeviceServices(deviceId)
        wx.stopBluetoothDevicesDiscovery()
      },
      fail:(err) => {
        wx.showToast({
          title: '建立蓝牙连接失败',
          icon: 'none'
        })
      }
    })
  },
  //获取蓝牙低功耗设备所有服务
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success:(res) => {
        for (let i = 0; i < res.services.length; i++) {
          if(res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      },
      fail:(res) => {
        console.log('getBLEDeviceServices fail', res.errMsg)
      }
    })
  },
  //获取蓝牙低功耗设备某个服务中所有特征
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if(item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          if(item.properties.write)
          {
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
          }
        }
      },
      fail:(res) => {
        console.log('get characteristicId fail', res.errMsg)
      }
    })
  },
  //关闭蓝牙服务
  closeBluetoothAdapter() {
    wx.closeBLEConnection({
      deviceId: this._deviceId,
      success: (res) => {
        console.log('disconnect success')
      },
      fail: (res) => {
        console.log('disconnect fail',res.errMsg)
      }
    })
    wx.closeBluetoothAdapter({
      success: (res) => {
        console.log('close success')
      },
      fail: (res) => {
        console.log('close fail',res.errMsg)
      }
    })
    this.data.connected = false
    console.log('close connection')
  },

  btnClickDown() {
    this.tipsBluetoothWarn()
    this.writeBluetoothValue('down')
    console.log('click down')
  },
  btnClickUp() {
    this.tipsBluetoothWarn()
    this.writeBluetoothValue('up')
    console.log('click up')
  },
  btnClickLeft() {
    this.tipsBluetoothWarn()
    this.writeBluetoothValue('left')
    console.log('click left')
  },
  btnClickRight() {
    this.tipsBluetoothWarn()
    this.writeBluetoothValue('right')
    console.log('click right')
  },
  btnClickStop() {
    this.tipsBluetoothWarn()
    this.writeBluetoothValue('stop')
    console.log('click stop')
  },
  tipsBluetoothWarn()
  {
    if(!this.data.connected)
    {
      wx.showToast({
        title: '蓝牙未连接',
        icon: 'none'
      })
    }
  },
  writeBluetoothValue(value) {
    if(!this.data.connected)
    {
      return
    }
    const buffer = new ArrayBuffer(value.length)
    const dataView = new DataView(buffer)
    for (let i = 0; i < value.length; i++) {
      dataView.setUint8(i, value.charCodeAt(i))
    }
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: buffer,
      success (res) {
        console.log('writeBLECharacteristicValue success', res.errMsg)
      },
      fail (res) {
        console.log('writeBLECharacteristicValue fail', res.errMsg, res.errCode)
      }
    })
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },
})
相关推荐
2501_915106324 小时前
iOS 抓不到包怎么办?从 HTTPS 代理排查到 TCP 数据流捕获的全链路解决方案
android·tcp/ip·ios·小程序·https·uni-app·iphone
游戏开发爱好者84 小时前
APP上架苹果应用商店经验教训与注意事项
android·ios·小程序·https·uni-app·iphone·webview
ACP广源盛139246256735 小时前
GSV2712@ACP#2 进 1 出 HDMI 2.0/Type-C DisplayPort 1.4 混合切换器 + 嵌入式 MCU
单片机·嵌入式硬件·计算机外设·音视频
沉在嵌入式的鱼5 小时前
STM32--GY906体温检测传感器
stm32·单片机·嵌入式硬件·gy906·体温检测
2401_853448235 小时前
Spieed micarray开发介绍
stm32·sk9822·sipeed mic
hyswl6666 小时前
数字货物搬家小程序
python·小程序
哄娃睡觉6 小时前
STM32 VBAT外围电路接法详解--备用电源(纽扣电池)
stm32
小李做物联网6 小时前
26.3基于stm32单片机毕业设计物联网软硬件智能遮阳棚设计
stm32·单片机·嵌入式硬件·物联网
D***y2016 小时前
SocketTool、串口调试助手、MQTT中间件基础
单片机·嵌入式硬件·中间件
易水寒陈6 小时前
使用1个定时器作为多个串口的超时计数器
stm32·单片机