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

目录

  • 使用接口
  • 界面效果
  • 界面设计
  • 界面逻辑设计

使用接口

微信小程序官方开发文档

接口说明
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"
{
  "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
<!--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
/* 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

// 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) {

  },
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/127965.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【ATTCK】MITRE ATTCK 设计与哲学

MITRE ATT&CK™:设计与哲学 来源&#xff1a;MITRE ATT&CK™: Design and Philosophy 摘要 MITRE ATT&CK知识库描述了网络对手的行为&#xff0c;并为攻击和防御提供了一个通用的分类。它已成为跨许多网络安全领域的一个有用工具&#xff0c;用于传递威胁情报&…

纵行科技LPWAN2.0芯片产品ZT1826获“2023年度硬核芯”大奖

2023年10月30日&#xff0c;由深圳市芯师爷科技有限公司主办、慕尼黑华南电子展协办、深圳市半导体行业协会支持的“第五届硬核芯生态大会暨2023汽车芯片技术创新与应用论坛”在深圳国际会展中心1号馆圆满落幕。当晚&#xff0c;“2023年度硬核芯评选”获奖榜单同步揭晓并进行颁…

网络的相关概念介绍

客户端和服务器通常运行在不同的主机上&#xff0c;通过计算机网络的硬件和软件资源来通信。网络是个复杂的系统&#xff0c;这里我们从程序员的角度来介绍一下网络相关的概念。 对主机而言&#xff0c;网络只是一种I/O设备&#xff0c;是数据源和数据接收方。 一个插到I/O总线…

补偿 FIR 滤波器引入的延迟

补偿 FIR 滤波器引入的延迟 对信号进行滤波会引入延迟。这意味着相对于输入&#xff0c;输出信号在时间上有所偏移。此示例向您说明如何抵消这种影响。 有限冲激响应滤波器经常将所有频率分量延迟相同的时间量。这样&#xff0c;我们就很容易通过对信号进行时移处理来针对延迟…

降维·预测·救命:PCA、随机森林与乳腺癌

一、引言 乳腺癌作为女性健康领域的一大挑战&#xff0c;对全球范围内的女性健康产生了深远影响。据世界卫生组织&#xff08;WHO&#xff09;统计&#xff0c;乳腺癌已成为全球女性恶性肿瘤发病率的最高者&#xff0c;且呈现逐年上升的趋势。在中国&#xff0c;乳腺癌也是女性…

实用技巧:嵌入式人员使用http服务模拟工具模拟http服务器测试客户端get和post请求

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134305752 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

隧道施工工艺流程vr线上虚拟展示成为产品3D说明书

行业内都知道&#xff0c;汽车生产的大部分都需要冲压加工来完成&#xff0c;因此汽车冲压工艺是汽车制造过程中的重要环节&#xff0c;传统的展示方式往往局限于二维图纸和实地操作&#xff0c;难以充分展现工艺的细节和流程。然而&#xff0c;随着技术的进步&#xff0c;汽车…

HashMap存值、取值及哈希碰撞原理分析

HashMap中的put()和get()的实现原理&#xff1a; map.put(k,v)实现原理 首先将k,v封装到Node对象当中&#xff08;节点&#xff09;。 然后它的底层会调用K的hashCode()方法得出hash值。 通过哈希表函数/哈希算法&#xff0c;将hash值转换成数组的下标&#xff0c;下标位置上…

关于c++中数据sqrt() 精度问题

情景介绍 今天在做一个算法题目的时候&#xff0c;发现&#xff0c;当使用sqrt()方法进行开方的时候&#xff0c;一直存在提交不通过的情况。 问题分析 对数据不断分析后&#xff0c;发现对35进行开方后&#xff0c;仍然满足条件&#xff0c;这就存在问题。 sqrt(35) 5.9160…

jsp 的div表格示例

<%page contentType"text/html;charsetgbk" pageEncoding"UTF-8"%> <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><title>jsp div 表格示例 &…

十六、W5100S/W5500+RP2040树莓派Pico<HTTP Client上传数据到OneNET>

文章目录 1 前言2 简介2 .1 什么是HTTP&#xff1f;2.2 HTTP Client的优点2.3 HTTP Client工作原理2.4 HTTP Client应用场景 3 WIZnet以太网芯片4 HTTP Client网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链…

微软surface laptop禁用触摸屏(win10、设备管理器)

参考链接&#xff1a; 在屏幕中启用和禁用触摸屏Windows 设置如下

处理uniapp打包后有广告的问题

1、登录平台&#xff08;开发者中心&#xff09; 2、 3、 4、 5、

Mysql数据库管理---MySQL数据库连接、权限认证

1 mysql系统连接权限认证。 1 mysql数据库权限表在数据库启动时就载入内存&#xff0c;当用户通过身份验证后&#xff0c;就在内存中进行相应权限的存取。系统会用到mysql数据库中3个核心表&#xff1a;user&#xff0c;host&#xff0c;db。 主要包括&#xff1a; 用户列&a…

哈希表简介

哈希的概念 顺序结构以及平衡树中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在查找一个元素 时&#xff0c;必须要经过关键码的多次比较。顺序查找时间复杂度为O(N)&#xff0c;平衡树中为树的高度&#xff0c;即 O( l o g 2 N log_2 N log2​N)&…

[论文阅读] CLRerNet: Improving Confidence of Lane Detection with LaneIoU

Abstract 车道标记检测是自动驾驶和驾驶辅助系统的重要组成部分。采用基于行的车道表示的现代深度车道检测方法在车道检测基准测试中表现出色。通过初步的Oracle实验&#xff0c;我们首先拆分了车道表示组件&#xff0c;以确定我们方法的方向。我们的研究表明&#xff0c;现有…

农业银行余额截图生成器,工商建设邮政招商,画板+标签+取快照命令实现

其实这个软件具体的实现原理标题已经讲了&#xff0c;就是易语言的画板绘画实现的&#xff0c;然后加上标签透明属性固定余额模版图生成的&#xff0c;标签的话一定要弄透明的&#xff0c;因为模版上面有些元素的颜色比较杂乱&#xff0c;如果你背景设置白色的它显得就非常假&a…

H264 NALU分析

H264简介 H.264从1999年开始&#xff0c;到2003年形成草案&#xff0c;最后在2007年定稿有待核实。在ITU的标准⾥称为H.264&#xff0c;在MPEG的标准⾥是MPEG-4的⼀个组成部分–MPEG-4 Part 10&#xff0c;⼜叫AdvancedVideo Codec&#xff0c;因此常常称为MPEG-4 AVC或直接叫…

雷达波形之一——LFM线性调频波形

文章目录 前言一、线性调频信号的形式1、原理2、时域表达式3、频域表达式 二、MATLAB 仿真1、涅菲尔积分①、MATLAB 源码②、仿真结果 2、LFM①、MATLAB 源码②、仿真结果1) 典型 LFM 波形&#xff0c;实部2) 典型 LFM 波形&#xff0c;虚部3) LFM 波形的典型谱 前言 线性调频…

追寻Moonbeam身影,泰国区块链周正在火热进行中!

继Moonbeam参与HK Web3月之后&#xff0c;下一站便是由Cryptomind Group举办的泰国2023年区块链周。本次位于泰国的区块链周以“熊市中建设&#xff0c;牛市中崛起”为理念&#xff0c;旨在为对区块链技术感兴趣的个人和投资者提供机会接触行业中的团队和专家&#xff0c;并邀请…