uni-app开发微信小程序使用BLE低功耗蓝牙正确步骤

文章目录

  • 前言
  • 连接逻辑
  • 建议

参考资料:https://www.hc01.com/downloads
在这里插入图片描述

前言

微信小程序通过蓝牙连接设备,所以需要使用到BLE连接。
思路:
小程序连接BLE的步骤+已经知道设备的BLE名称、服务id、特征值ID。需要根据蓝牙模块提供商的说明书去选择相应的服务、特征值。

注意:监听和写入不一定是同一个特征值。

连接逻辑

假设设备的蓝牙名称是MAX-8080
1、扫一扫二维码获取蓝牙名称;
2、连接BLE准备;
3、根据蓝牙名称链接BLE;
4、连接成功监听特征值;
5、收发数据。

代码:

<script>
export default {data() {return {connected:null,deviceId:null,scan_result:null,// 蓝牙适配器参数adapterState: {discovering: false,available: false},  // 搜索出来的蓝牙设备列表devicesLsits: [],/*** 定时器*/_discoveryTimer: null,_discoveryTimeout: 30000, // 搜索设备超时时间,单位msHC02CharacteristicNotifyUUID:"49535343-1E4D-4BD9-BA61-23C647249616",HC02ServiceUUID:'49535343-FE7D-4AE5-8FA9-9FAFD205E455',}},methods: {/*** 扫一扫调用接口,如果执行成功,app.scan_result会有值*/scan_weixi() {uni.scanCode({success: (res) => {// 取出扫码的设备名称 MAX-8080const result = res.result.split("?")[1];this.scan_result = result;this.closeBLEConnection();this.openBluetoothAdapter();},fail: (err) => {// 如果失败返回空}});},/*** 	断开蓝牙连接*/async closeBLEConnection(OBJECT) {try {const state = uni.getStorageSync('bluetoothAdapterState');if (state) {console.log("===断开连接操作===");uni.removeStorageSync('bluetoothAdapterState');await uni.closeBLEConnection({deviceId: this.deviceId,success(res) {console.log("===蓝牙已断开===", res)}})}} catch (e) {// error}// 关闭蓝牙特征值的监听wx.offBLECharacteristicValueChange();},/*** 初始化蓝牙设备*/openBluetoothAdapter() {const that = this;console.log("初始化log_scan_result", this.scan_result);uni.openBluetoothAdapter({success: e => {try {uni.setStorageSync('bluetoothAdapterState', true);} catch (e) {// error}console.log('初始化蓝牙成功:' + JSON.stringify(e));},fail: e => {try {uni.setStorageSync('bluetoothAdapterState', false);} catch (err) {// error}console.log(e)console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));},complete: () => {wx.offBluetoothAdapterStateChange();// 语法将结果res传入到handleBluetoothAdapterStateChange方法中wx.onBluetoothAdapterStateChange(this.handleBluetoothAdapterStateChange);/** 监听蓝牙连接 */// console.log('【监听蓝牙连接...】')wx.offBLEConnectionStateChange();wx.onBLEConnectionStateChange(this.handleBLEConnectionStateChange);/** 开始搜索附近设备 */this.onDevicesDiscovery()}});},/*** 蓝牙适配器状态改变(例如手动关闭蓝牙)*/async handleBluetoothAdapterStateChange(res) {console.log("BLE适配器发生变化", res, this.scan_result);// available 蓝牙适配器是否可用// discovering 蓝牙适配器是否处于搜索状态const {available} = resconst originState = wx.getStorageSync('bluetoothAdapterState')wx.setStorageSync('bluetoothAdapterState', available)if (!available) {this.offDevicesDiscovery()uni.showToast({title: '请打开手机蓝牙',icon: "error",duration: 2000});} else if (!originState) {this.onDevicesDiscovery();}},/** 开启搜索附近设备 */onDevicesDiscovery() {console.log('【开始搜索附近设备...】')if (wx.getStorageSync('bluetoothAdapterState')) {wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: true, // 重复上报发现设备powerLevel: 'height',interval: 1000,success: () => {// this._deviceIdsList = []// this.setData({// 	devicesList: []// })/** 发现设备 */wx.onBluetoothDeviceFound(this.handleFoundBluetoothDevices)/** 超时关闭搜索 */this._discoveryTimer = setTimeout(() => {this.offDevicesDiscovery();}, this._discoveryTimeout)},fail: err => {console.error(err)}})}},/*** 搜索附近设备回调*/handleFoundBluetoothDevices({devices}) {console.log("发现的设备列表devices", devices, this.scan_result);for (let item of devices) {if (this.scan_result == item.localName) {// 保存在全局变量中this.connectDevice = item;this.offDevicesDiscovery();console.log("找到设备", item, this.scan_result);if (!this.connected && this.connectDetermine(item.localName) && wx.getStorageSync('bluetoothAdapterState')) {console.log("==开始连接==", item.localName);this.createBLEConnection();} else {console.log("校验失败,不给予连接:", app.connected, wx.getStorageSync('bluetoothAdapterState'));}}}},/*** 连接低功耗蓝牙(连接开始)*/async createBLEConnection() {let that = this;let deviceId = this.deviceId;// 弹窗uni.showToast({title: '连接蓝牙中...',icon: 'loading',duration: 2000});await uni.createBLEConnection({deviceId,success: res => {console.log("createBLEConnection连接蓝牙成功", res);uni.hideLoading();uni.showToast({title: '连接成功',icon: 'success',duration: 1500});// this.getSystemInfo();this.setMTU();setTimeout(() => {// 订阅特征值this.getBLESC();}, 500)},fail: e => {let res = JSON.stringify(e);console.log('连接低功耗蓝牙失败,错误码:' + res);// 表示已经连接,不能再次连接的错误提示if (res.errCode == -1 && res.errno == 1509007) {app.connected = true;}}});},/*** 获取服务(Services)和特征值(Characteristics)* 必须的一步:IOS要调用特征值之后才能监听 notifyBLECharacteristicValueChange,否则会报错(找不到服务/特征值)*/getBLESC() {const that = this;console.log("====进入getBLESC====", this.deviceId, this.HC02ServiceUUID);uni.getBLEDeviceServices({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId: this.deviceId,success(res) {console.log('获取服务类别device services:', res.services)},fail(e) {console.log('getBLEDeviceServices失败', e);}})uni.getBLEDeviceCharacteristics({// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId: this.deviceId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId: this.HC02ServiceUUID,success(res) {console.log('获取特征值device getBLEDeviceCharacteristics:', res.characteristics)that.notifyBLECharacteristicValueChange();},fail(e) {console.log('getBLEDeviceCharacteristics失败', e);that.getBLESC();}})},/*** 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。*/async notifyBLECharacteristicValueChange() {await uni.notifyBLECharacteristicValueChange({state: true, // 启用 notify 功能// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId: this.deviceId,// 固定写死serviceId: this.HC02ServiceUUID,// 固定写死characteristicId: this.HC02CharacteristicNotifyUUID,success: (res) => {console.log('notifyBLECharacteristicValueChange执行 success:' + res.errMsg);onBLECharacteristicValueChange();},fail: (err) => {}});},onBLECharacteristicValueChange(){console.log("==========调用监听蓝牙======");uni.onBLECharacteristicValueChange(function(res) {console.log("==========在Send方法收到蓝牙信息======", res);})},}

建议

还是参考资料中的源码吧,我写的毕竟是定制需求,并非适合所有人。附链接:
微信小程序源码

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

链表之单链表

上一篇博客我们学习了线性表中的顺序表&#xff0c;这一篇博客让我们继续往下了解线性表的链表&#xff0c;链表分为好几种结构&#xff0c;活不多说&#xff0c;让我们开始学习吧&#xff01; 目录 1.链表 2.链表的结构 3.单链表的实现 1.链表 1.概念&#xff1a;它是一种物…

大创项目推荐 深度学习 python opencv 火焰检测识别 火灾检测

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

HTML - 请你谈一谈 iframe的优缺点

难度级别:中级及以上 提问概率:50% iframe是一个HTML标签,它可以在一个网页中嵌入另外一个网页,甚至是把其他的网站嵌入进来。在之前的很长时间里,内部管理系统都在使用iframe,做为菜单切换的主体模板区域框架。iframe包含一个src属性,…

php运行python脚本失败怎么解决

假设有文件&#xff1a;php_test.php python_test.py 在php文件中运行Python&#xff1a; exec("python python_test.py", $array, $ret); 如果运行Python出错并不能保存在数组array中&#xff0c;因此应该把标准错误重定向到文件中&#xff0c;以上代码改写如下&a…

【芯片验证】通关寄存器与ral_model —— 寄存器生成流程中加入backdoor后门配置

前言 【芯片验证】通关寄存器与ral_model —— backdoor后门访问实操测试-CSDN博客 上一篇文章中,我们通过在环境中配置后门路径的方式来实现了寄存器的后门访问,但是在实际应用中,无论寄存器RTL文件、例化还是寄存器模型大概率都是工具生成的,比如在本专栏中实现的gen_r…

Docker实战教程 第2章 Docker基础

3-1 Docker介绍 什么是Docker 虚拟化&#xff0c;容器 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&…

自动驾驶中各种坐标系辨析

坐标系辨析 0. 地球椭圆体1. 大地坐标系2. eci地心惯性坐标系3. 地心地固坐标系(ECEF坐标系&#xff0c;E系)4. 站心坐标系(ENU坐标系)5. UTM坐标系6. LTM坐标系7. IMU坐标系8. 代码部分8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标8.2 LLA坐标转…

线上线下陪玩,APP小程序H5。源码交付,支持二开!

线下陪玩的风险与管理方式 1、陪玩者的身心健康风险 线下陪玩的模式决定了陪玩者需要与不同的需求方见面&#xff0c;并满足他们的陪伴和娱乐需求。这种工作方式可能会给陪玩者带来身心上的压力和负担。因为陪玩者需要面对各种需求方的要求&#xff0c;有时还需要虚拟出一种完…

HTML - 你知道b与strong标签的区别吗

难度级别&#xff1a;初级及以上 提问概率&#xff1a;50% 不单单是初学者&#xff0c;即便是有好几年工作经验的前端开发工作者&#xff0c;也会有一大部分人把这两个标签搞混&#xff0c;甚至在工作中&#xff0c;很大一部人不会使用这两个标…

212 基于matlab的双稳态随机共振的算法

基于matlab的双稳态随机共振的算法&#xff0c;分析信噪比随系统参数a,b及乘性噪声和加性噪声的增益变化曲线&#xff0c;60个数据样本可供选择。程序已调通&#xff0c;可直接运行。 212 双稳态随机共振 信噪比增益变化曲线 - 小红书 (xiaohongshu.com)

浅谈分布式光伏电站的运维管理

摘要&#xff1a;随着近些年我国对节能降耗关注力度的持续加大&#xff0c;为满足人们不断增长的电能需求&#xff0c;光伏发电产业得到迅猛发展&#xff0c;其中分布式光伏发电的比重持续增长。在打赢脱贫攻坚战的大背景下&#xff0c;国家电网公司探索出一条“阳光扶贫”的扶…

Spring Cloud微服务入门(一)

微服务的演变过程 //controller 视图交互层 前端数据处理传给service //1.DAO RequestBody userDAO String id;String type; {"id":"lcs", "type":"lcs"} //2.GET请求 findUserById&#xff1f;id1&typelcsRequestParam String …

5.3.1 配置交换机 SSH 管理和端口安全

5.3.1 实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握&#xff1a; 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 交换机基本安全和 SSH管理实验拓扑 3、实验步骤 &a…

全面的Docker快速入门教程(详细)

前言&#xff1a; 都2024年了&#xff0c;你还在为了安装一个开发或者部署环境、软件而花费半天的时间吗&#xff1f;你还在解决开发环境能够正常访问&#xff0c;而发布测试环境无法正常访问的问题吗&#xff1f;你还在为持续集成和持续交付&#xff08;CI / CD&#xff09;工…

flink1.18源码本地调试环境

01 源码本地调试环境搭建 1. 从github拉取源码创建本地项⽬ https://github.com/apache/flink.git 可以拉取github上官⽅代码 https://github.com/apache/flink.git GitHub - apache/flink: Apache Flink 2. 配置编译环境 ctrlaltshifts &#xff08;或菜单&#xff09;打…

OpenHarmony Neptune开发板-MQTT连接华为IoT平台

本示例将演示如何在Neptune开发板上使用MQTT协议连接华为IoT平台,使用的是ATH20温湿度传感器模块与Neptune开发板 本示例实现AHT20温湿度数据上报华为IoT平台,IoT平台下发命令控制LED灯的开关 使用W800 SDK功能包中libemqtt来实现连接华为IoT平台 程序设计 初始化 一、MQT…

上位机图像处理和嵌入式模块部署(qmacvisual亮度检测)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;在机器视觉当中&#xff0c;对于光源的处理要非常小心。这里面不仅包括了选择什么样的光源&#xff0c;还取决于怎样使用…

WPF文本框TextEdit不以科学计数法显示

WPF文本框TextEdit不以科学计数法显示 一个float或者double类型的数值&#xff0c;如果小数点后0的个数≥4&#xff0c;在界面上就会自动以科学计数法显示&#xff0c; 比如&#xff1a;0.00003会显示成这样 但是很多时候我并不希望它这样显示&#xff0c;因为这样不方便编辑…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之一 简单视频放大抖动效果 一、简单介绍 二、简单视频放大抖动效果实现原理 三、简单视频放大…

C# WPF编程-命令

C# WPF编程-命令 概述WPF命令模型ICommand接口RoutedCommand类RoutedUICommand类命令库 概述 使用路由事件可以响应广泛的鼠标和键盘事件&#xff0c;这些事件是低级的元素。在实际应用程序中&#xff0c;功能被划分成一些高级的任务。这些任务可通过各种不同的动作和用户界面…