当前位置: 首页 > news >正文

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

目录

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

使用接口

微信小程序官方开发文档

接口说明
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 = falseconst 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 = deviceIdthis._serviceId = serviceIdthis._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 = falseconsole.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) {},
})

相关文章:

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

目录 使用接口界面效果界面设计界面逻辑设计 使用接口 微信小程序官方开发文档 接口说明wx.openBluetoothAdapter初始化蓝牙模块wx.closeBluetoothAdapter关闭蓝牙模块(调用该方法将断开所有已建立的连接并释放系统资源)wx.startBluetoothDevicesDiscovery开始搜寻附近的蓝牙…...

【react hook】react hook组件中,在forEach中使用async/awati进行异步操作,为什么后面代码没有等待直接同步运行了呢?

这是因为 forEach 方法不会等待 async/await 异步操作的完成。forEach 方法是一种同步的方法&#xff0c;它会在每个迭代内部同步执行一个回调函数。当遇到 await 时&#xff0c;会立即暂停执行&#xff0c;但是 forEach 方法不会等待回调函数中的 await 异步操作完成&#xff…...

高斯过程回归 | GPR高斯过程回归

高斯过程回归(Gaussian Process Regression, GPR)是一种强大的非参数回归方法,它通过假设数据是从一个高斯过程中生成的来预测新的数据点。 高斯过程是一种定义在连续输入空间上的随机过程,其中任何有限集合的观测值都呈多变量高斯分布。 实现GPR的Python代码import numpy …...

[autojs]逍遥模拟器和vscode对接

第一步&#xff1a;启动autojs服务 第二步&#xff1a;去cmd查看ip地址&#xff0c;输入ipconfig 第三步&#xff1a;打开逍遥模拟器中的sutojs-左上角- 连接电脑&#xff0c;然后输入WLAN或者其他ip也行&#xff0c;根据自己电脑实际情况确认 此时vscode显示连接成功。我们写…...

Docker 安装与优化

一、安装Docker 1、关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 02、安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2#解释 yum-utils #提供了yum-config-manager工具 device mapper #是linux内核中支持逻辑卷…...

Wix使用velo添加Google ads tag并在form表单提交时向谷歌发送事件

往head里加代码时&#xff0c;不能看谷歌的代码&#xff0c;要看wix的代码&#xff0c;不然必定踩坑 https://support.wix.com/en/article/tracking-google-ads-conversions-using-wix-custom-code 这里的代码才对&#xff0c;因为wix搞了个velo&#xff0c;这个velo很傻x&am…...

Centos配置邮件发送

在CentOS Linux上配置邮件发送 在这个指南中&#xff0c;我们将讨论如何配置CentOS Linux系统以通过外部邮件服务器发送电子邮件&#xff0c;使用自己的邮件账户进行发送。 第一步&#xff1a;开启SMTP授权码 首先&#xff0c;我们以QQ邮箱为例&#xff0c;需要开启SMTP授权…...

Ubuntu系统使用apt-get管理软件工具

记录一下使用Ubuntu系统的apt-get管理软件工具 先查看一下系统的版本&#xff0c;可以看到这里使用的是Ubuntu20.04版本&#xff0c;版本代号focal rootmyw:~# uname -a Linux myw 5.4.0-70-generic #78-Ubuntu SMP Fri Mar 19 13:29:52 UTC 2021 x86_64 x86_64 x86_64 GNU/L…...

带你走进Cflow (三)·控制符号类型分析

目录 ​编辑 1、控制符号类型 1.1 语法类 1.2 符号别名 1.3 GCC 初始化 1、控制符号类型 有人也许注意到了输出中奇怪的现象&#xff1a;函数_exit 丢失了&#xff0c;虽然它在源文件中被printdir 调用了两次。这是因为默认情况下 cflow 忽略所有的一下划线开头的符号…...

FPGA UDP RGMII 千兆以太网(3)ODDR

1 xilinx原语 在 7 系列 FPGA 中实现 RGMII 接口需要借助 5 种原语,分别是:IDDR、ODDR、IDELAYE2、ODELAYE2(A7 中没有)、IDELAYCTRL。其中,IDDR和ODDR分别是输入和输出的双边沿寄存器,位于IOB中。IDELAYE2和ODELAYE2,分别用于控制 IO 口输入和输出延时。同时,IDELAYE2 …...

OSG交互:选中场景模型并高亮显示

1、目的 可以在osg视图中选中指定模型实体,并高亮显示。共分为两种,一种鼠标点选,一种框选。 2、鼠标点选 2.1 功能说明 生成两组对象,一组cow对象可以被选中,另一组robot不能被选中;点击cow对象被选中高亮,点击robot被选中不高亮;点击空白处,弹出“select nothing!…...

农业大棚智能化改造升级与远程视频监管方案,助力智慧农业建设发展

一、需求分析 随着现代化技术的发展&#xff0c;农业大棚的智慧化也成为当前备受关注的智慧农业发展手段。利用先进的信息化手段来对农业大棚进行管理&#xff0c;采集和掌握作物的生长状况、作业监督、生态环境等信息数据&#xff0c;实现精准操作、精细管理&#xff0c;远程…...

P6入门:项目初始化2-项目详情之日期Date

前言 使用项目详细信息查看和编辑有关所选项目的详细信息&#xff0c;在项目创建完成后&#xff0c;初始化项目是一项非常重要的工作&#xff0c;涉及需要设置的内容包括项目名&#xff0c;ID,责任人&#xff0c;日历&#xff0c;预算&#xff0c;资金&#xff0c;分类码等等&…...

【ubuntu20.04】win10安装ubuntu20.04双系统

win10安装ubuntu20.04双系统&#xff1a; 【ubuntu20.04】win10安装ubuntu20.04双系统:https://www.bilibili.com/video/BV11k4y1k7Li/?spm_id_from333.999.0.0&vd_source66a67b8a0b3c4e03915bf8b3a6ff9a74 ubuntu与windows双系统时间同步&#xff1a; windows认为&…...

使用ffmpeg 压缩视频

我有一批1080p的视频,在网上播放占用空间太大,需要进行压缩以后再上传,下面是记录一下ffmpeg命令的使用情况 原视频大小:288mb --压缩加修改分辨率 640p ffmpeg -y -i C4995.mp4 -vcodec libx264 -crf 18 -s vga C4995\C4995_2.MP4 -y: 强制覆盖 -i :输入文件 -vcodec lib…...

C# , .netWebApi, WPF 用特性实现类似Java 的Ioc 自动装配@Autowired

写C# 一直很羡慕Java的@Autowired 自动装配. 因为C# 必须手动在Ioc里注册 之前用接口实现了自动注册IOC, 总是觉得美中不足, 毕竟没有真正实现用注解/特性实现自动注入, 这次我们来实现一个用特性注入Ioc的扩展方法. namespace MyCode.BLL.Service.Ioc {/// <summary>/…...

3DMAX汽车绑定动画模拟插件MadCar疯狂汽车使用教程

3DMAX汽车绑定动画模拟插件MadCar疯狂的汽车&#xff0c;用于通过模拟控制来快速装配轮式车辆及其动画。这个新版本允许装配任何数量的车轮的车辆&#xff0c;以及包括摩托车在内的任何相互布置。还支持任意数量的拖车。 每个车轮和悬架都有简化的行为设置以及微调&#xff0c…...

比较PID控制和神经网络控制在机器人臂上的应用

机器人臂是自动化领域中常见的机器人形式&#xff0c;其精确控制对于实现复杂任务具有重要意义。在机器人臂的控制中&#xff0c;PID控制和神经网络控制是两种常用的控制方法。本文将比较PID控制和神经网络控制在机器人臂控制方面的应用&#xff0c;包括控制原理、优缺点以及在…...

ubuntu16.04 交叉编译 mbedtls

在为客户交叉编译项目时需要依赖 mbedtls&#xff0c; 客户的机器是 arm64 的 ubuntu 16.04&#xff0c; 交叉编译过程中遇到几个问题。 首先&#xff0c; mbedtls 需要依赖 python, 在 cmake 的过程中&#xff0c; 如果不是使用系统默认的 cmake 可能会导致&#xff0c;mbedt…...

基于遗传算法优化的直流电机PID控制器设计

PID控制器是工业控制中常用的一种控制算法&#xff0c;通过不断调节比例、积分和微分部分来实现对系统的稳定控制。然而&#xff0c;在一些复杂系统中&#xff0c;传统的PID参数调节方法可能存在局限性。本文将介绍一种基于遗传算法优化的直流电机PID控制器设计方法&#xff0c…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...