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

目录

使用接口

微信小程序官方开发文档

接口 说明
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) {

  },
})
相关推荐
不悔哥19 小时前
开源OV-Watch:怎么做一个智能手表
单片机·开源·嵌入式
XiHongShi201619 小时前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
前端小万19 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
优信电子20 小时前
AIT1001 非接触式红外测温模块 STM32 驱动开发实战:从引脚到代码全解析
stm32·嵌入式·温度传感器·红外测温·非接触式测温·ait1001
深圳老胡21 小时前
STM32F407 控制 L6470 步进电机驱动 —— 控制过程简介
笔记·stm32·单片机·嵌入式硬件·代码规范
wuyk55521 小时前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
MoonMoonLee21 小时前
小程序配置
小程序
女神下凡1 天前
嵌入式设计的各种存储芯片的硬件/软件设计规范,非常全面。
arm开发·单片机·嵌入式硬件
梅梅9661 天前
一款mipi转lvds的lcd调试(LT8912B)
单片机·计算机外设·电脑·显示器·pd芯片
开发笔记-阿牛1 天前
蓝牙音乐灯拆解,又一次拆到蓝牙音乐灯芯片CK6865L
人工智能·单片机·嵌入式硬件·音视频·音频