高端网站建设费用,室内设计好的大学排名,手机端网站设计模板,昆山规划建设局网站BLE
低功耗蓝牙#xff08;Bluetooth Low Energy#xff0c;或称Bluetooth LE、BLE#xff0c;旧商标Bluetooth Smart#xff09;#xff0c;用于医疗保健、运动健身、安防、工业控制、家庭娱乐等领域。在如今的物联网时代下大放异彩#xff0c;扮演者重要一环#xff…BLE
低功耗蓝牙Bluetooth Low Energy或称Bluetooth LE、BLE旧商标Bluetooth Smart用于医疗保健、运动健身、安防、工业控制、家庭娱乐等领域。在如今的物联网时代下大放异彩扮演者重要一环是无线通信的主流技术之一常见的无线通信技术有NFC、GPRS、Zigbee、WiFi等2021 年 7 月蓝牙技术联盟Bluetooth SIG 发布了蓝牙 5.3 版本也是截止目前的最新版本。 蓝牙BT最早诞生于1999年第一代蓝牙是单工传输的、通信易受干扰难以区分主从设备、传输速率才几百kbps一路发展直到 蓝牙4.0 版本才有了低功耗蓝牙BLE的诞生。
经典蓝牙 经典蓝牙泛指支持蓝牙协议4.0以下的蓝牙经典蓝牙一般用于连续流式传输音频和数据量比较大的传输例如音乐、语音、打印机等。低功耗蓝牙 低功耗蓝牙ble指支持蓝牙协议4.0或更高的版本它不向后兼容4.0之前的经典蓝牙协议主打低功耗使用一个纽扣电池最起码都能工作好几个月低延迟几毫秒级别的响应应用于实时性要求比较高但是低速率低功耗的场景如鼠标键盘、智能家居、智能穿戴这类不需要大数据量交互的场景中非常适合物联网应用。
前序
这是一次真实的 低功耗蓝牙 收发数据 的全过程讲解。
本文使用 uni-app Vue3 的方式进行开发以手机app的方式运行微信小程序同样可行。
uni-app 提供了 蓝牙 和 低功耗蓝牙 的 api 和微信小程序提供的 api 是一样的所以本文的讲解也适用于微信小程序。
本文只实现 蓝牙收发数据 功能至于样式我懒得调~
蓝牙相关功能我会逐步讲解。如果你基础好又急的话可以直接跳到 『完整代码』的章节查看那里没废话。 花了几块钱巨款买回来的蓝牙学习套装~
环境说明
开发工具HBuilder X 3.4.7.20220422uni-app Vue3以安卓App的方式运行iOS和小程序同理
思路
蓝牙收发数据的逻辑和我们常用的 AJAX 进行的网络请求是有一丢丢不同的。
其中较大的区别是蓝牙接收数据不是那么的稳定相比起网络请求蓝牙更容易出现丢包的情况。
在开发中AJAX 发起的请求不管成功还是失败浏览器基本都会给你一个答复。但 uni-app 提供的 api 来看蓝牙接收数据会显得更加**“异步”**。
大致思路
使用蓝牙进行数据传输的大概思路如下
初始化打开蓝牙模块搜寻检测附近存在的设备连接找到目标设备进行监听开启监听功能接收其他设备传过来的数据发送指令不管发送数据还是读取数据都可以理解为向外发送指令
从步骤的实现目标的角度来说大概思路如下
搜索 蓝牙设备获取 设备ID 连接 设备获取 蓝牙设备 的所有 服务获取服务 所有的 特征值根据 特征值 进行 发送指令 操作
实现
上面整理出使用蓝牙传输数据的5大动作但每个动作其实都是由 uni-app 提供的一个或者多个 api 组合而成。
初始化阶段
使用蓝牙之前需要初始化蓝牙模块这是最最最开始就要做的
使用 uni.openBluetoothAdapter 这个 api 就可以初始化蓝牙模块。其他蓝牙相关 API 必须在 uni.openBluetoothAdapter 调用之后使用。否则 API 会返回错误 errCode10000 。
错误代码可以查阅 《错误码文档》
代码示例
templateviewbutton clickinitBlue初始化蓝牙/button/view
/templatescript setup// 【1】初始化蓝牙
function initBlue() {uni.openBluetoothAdapter({success(res) {console.log(初始化蓝牙成功)console.log(res)},fail(err) {console.log(初始化蓝牙失败)console.error(err)}})
}
/script如果你手机开启了蓝牙点击页面上的按钮后控制台就会输出如下内容
初始化蓝牙成功
{errMsg:openBluetoothAdapter:ok}如果手机没开启蓝牙就会返回如下内容
初始化蓝牙失败
{errMsg:openBluetoothAdapter:fail not available,code:10001}根据文档提示10001代表当前蓝牙适配器不可用。 如果你的控制台能打印出 {errMsg:openBluetoothAdapter:ok} 证明第一步已经成功了。
接下来可以开始搜索附近蓝牙设备。
搜寻附近设备
这一步需要2个 api 配合完成。所以可以分解成以下2步
开启搜寻功能uni.startBluetoothDevicesDiscovery监听搜寻到新设备uni.onBluetoothDeviceFound
开发蓝牙相关功能时操作逻辑更像是推送所以“开启搜索”和“监听新设备”是分开操作的。
uni.startBluetoothDevicesDiscovery 可以让设备开始搜索附近蓝牙设备但这个方法比较耗费系统资源建议在连接到设备之后就使用 uni.stopBluetoothDevicesDiscovery 停止继续搜索。
uni.startBluetoothDevicesDiscovery 方法里可以传入一个对象该对象接收几个参数但初学的话我们只关注 success 和 fail。如果你的项目中硬件佬有提供 service 的 uuid 给你的话你也可以在 services 里传入。其他参数可以查看官方文档的介绍。
在使用 uni.startBluetoothDevicesDiscovery 开始搜索后可以使用 uni.onBluetoothDeviceFound 进行监听这个方法里面接收一个回调函数。
代码示例
templateviewscroll-viewscroll-yclassboxview classitem v-foritem in blueDeviceListviewtextid: {{ item.deviceId }}/text /viewviewtextname: {{ item.name }}/text /view/view/scroll-viewbutton clickinitBlue初始化蓝牙/buttonbutton clickdiscovery搜索附近蓝牙设备/button/view
/templatescript setup
import { ref } from vue// 搜索到的蓝牙设备列表
const blueDeviceList ref([])// 【1】初始化蓝牙
function initBlue() {uni.openBluetoothAdapter({success(res) {console.log(初始化蓝牙成功)console.log(res)},fail(err) {console.log(初始化蓝牙失败)console.error(err)}})
}// 【2】开始搜寻附近设备
function discovery() {uni.startBluetoothDevicesDiscovery({success(res) {console.log(开始搜索)// 开启监听回调uni.onBluetoothDeviceFound(found)},fail(err) {console.log(搜索失败)console.error(err)}})
}// 【3】找到新设备就触发该方法
function found(res) {console.log(res)blueDeviceList.value.push(res.devices[0])
}
/scriptstyle
.box {width: 100%;height: 400rpx;box-sizing: border-box;margin-bottom: 20rpx;border: 2px solid dodgerblue;
}
.item {box-sizing: border-box;padding: 10rpx;border-bottom: 1px solid #ccc;
}
button {margin-bottom: 20rpx;
}
/style上面代码的逻辑是如果开启 “寻找附近设备” 功能成功接着就开启 “监听寻找到新设备的事件” 。
搜索到的设备会返回以下数据
{devices: [{deviceId: B4:10:7B:C4:83:14,name: 蓝牙设备名,RSSI: -58,localName: ,advertisServiceUUIDs: [0000FFF0-0000-1000-8000-00805F9B34FB],advertisData: {}}]
}每监听到一个新的设备我都会将其添加到 蓝牙设备列表(blueDeviceList) 里最后讲这个列表的数据渲染到页面上。 连接目标设备
连接目标设备只需要1个 api 就能完成。但根据文档提示我们连接后还需要关闭 “搜索附近设备” 的功能这个很好理解既然找到了再继续找就是浪费资源。
流程如下
获取设备ID根据 uni.onBluetoothDeviceFound 回调拿到设备ID连接设备使用设备ID进行连接 uni.createBLEConnection停止搜索uni.stopBluetoothDevicesDiscovery
我给每条搜索到的蓝牙结果添加一个 click 事件会向目标设备发送连接请求。
我的设备名称是 leihou 所以我点击了这条。
代码示例
templateviewscroll-viewscroll-yclassboxview classitem v-foritem in blueDeviceList clickconnect(item)viewtextid: {{ item.deviceId }}/text /viewviewtextname: {{ item.name }}/text /view/view/scroll-viewbutton clickinitBlue初始化蓝牙/buttonbutton clickdiscovery搜索附近蓝牙设备/button/view
/templatescript setup
import { ref } from vue// 搜索到的蓝牙设备列表
const blueDeviceList ref([])// 【1】初始化蓝牙
function initBlue() {uni.openBluetoothAdapter({success(res) {console.log(初始化蓝牙成功)console.log(res)},fail(err) {console.log(初始化蓝牙失败)console.error(err)}})
}// 【2】开始搜寻附近设备
function discovery() {uni.startBluetoothDevicesDiscovery({success(res) {console.log(开始搜索)// 开启监听回调uni.onBluetoothDeviceFound(found)},fail(err) {console.log(搜索失败)console.error(err)}})
}// 【3】找到新设备就触发该方法
function found(res) {console.log(res)blueDeviceList.value.push(res.devices[0])
}// 蓝牙设备的id
const deviceId ref()// 【4】连接设备
function connect(data) {console.log(data)deviceId.value data.deviceIduni.createBLEConnection({deviceId: deviceId.value,success(res) {console.log(连接成功)console.log(res)// 停止搜索stopDiscovery()},fail(err) {console.log(连接失败)console.error(err)}})
}// 【5】停止搜索
function stopDiscovery() {uni.stopBluetoothDevicesDiscovery({success(res) {console.log(停止成功)console.log(res)},fail(err) {console.log(停止失败)console.error(err)}})
}
/scriptstyle
.box {width: 100%;height: 400rpx;box-sizing: border-box;margin-bottom: 20rpx;border: 2px solid dodgerblue;
}
.item {box-sizing: border-box;padding: 10rpx;border-bottom: 1px solid #ccc;
}
button {margin-bottom: 20rpx;
}
/style连接成功后在控制台会输出
连接成功
{errMsg:createBLEConnection:ok}在连接成功后就立刻调用 uni.stopBluetoothDevicesDiscovery 方法停止继续搜索附近其他设备停止成功后会输出
停止成功
{errMsg:stopBluetoothDevicesDiscovery:ok}连接成功后设备也亮起了绿灯。
监听
在连接完设备后就要先开启监听数据的功能。这样才能接收到发送读写指令后设备给你回调的信息。
要开启监听首先需要知道蓝牙设备提供了那些服务然后通过服务获取特征值特征值会告诉你哪个可读哪个可写。最后根据特征值进行消息监听。
步骤如下
获取蓝牙设备服务uni.getBLEDeviceServices获取特征值uni.getBLEDeviceCharacteristics开启消息监听uni.notifyBLECharacteristicValueChange接收消息监听传来的数据uni.onBLECharacteristicValueChange
正常情况下硬件佬会提前把蓝牙设备的指定服务还有特征值告诉你。
比如我这个设备的蓝牙服务是0000FFE0-0000-1000-8000-00805F9B34FB
特征值是0000FFE1-0000-1000-8000-00805F9B34FB
第一步获取蓝牙服务
templateview!-- 省略上一步的代码 --button clickgetServices获取蓝牙服务/button/view
/templatescript setup
import { ref } from vue// 省略上一步的代码……// 【6】获取服务
function getServices() {uni.getBLEDeviceServices({deviceId: deviceId.value, // 设备ID在上一步【4】里获取success(res) {console.log(res)},fail(err) {console.error(err)}})
}
/script此时点击按钮将会获取到已连接设备的所有服务。
我的设备有以下几个服务。你在工作中拿到的 服务uuid 和我的是不一样的数量也不一定相同。
可以发现我拿到的结果里有 0000FFE0-0000-1000-8000-00805F9B34FB 这条服务。
{services: [{uuid: 00001800-0000-1000-8000-00805F9B34FB,isPrimary: true}, {uuid: 00001801-0000-1000-8000-00805F9B34FB,isPrimary: true}, {uuid: 0000180A-0000-1000-8000-00805F9B34FB,isPrimary: true}, {uuid: 0000FFF0-0000-1000-8000-00805F9B34FB,isPrimary: true}, {uuid: 0000FFE0-0000-1000-8000-00805F9B34FB,isPrimary: true}],errMsg: getBLEDeviceServices:ok
}第二步获取指定服务的特征值
获取特征值需要传 设备ID 和 服务ID。
在上两步我拿到了 设备ID 为 B4:10:7B:C4:83:14服务ID 为 0000FFE0-0000-1000-8000-00805F9B34FB。
templateview!-- 省略前面几步代码 --button clickgetCharacteristics获取特征值/button/view
/templatescript setup
import { ref } from vue// 省略前面几步代码// 【7】获取特征值
function getCharacteristics() {uni.getBLEDeviceCharacteristics({deviceId: deviceId.value, // 设备ID在【4】里获取到serviceId: 0000FFE0-0000-1000-8000-00805F9B34FB, // 服务UUID在【6】里能获取到success(res) {console.log(res)},fail(err) {console.error(err)}})
}
/script最后成功输出
{characteristics: [{uuid: 0000FFE1-0000-1000-8000-00805F9B34FB,properties: {read: true,write: true,notify: true,indicate: false}}],errMsg: getBLEDeviceCharacteristics:ok
}characteristics 字段里保存了该服务的所有特征值我的设备这个服务只有1个特征值并且读、写、消息推送都为 true。
你的设备可能不止一条特征值需要监听那条特征值这需要你和硬件佬协商的通常也是硬件佬直接和你说要监听哪条。
第三、四步开启消息监听 并 接收消息监听传来的数据
根据已经拿到的 设备ID、服务ID、特征值就可以开启对应的监听功能。
使用 uni.notifyBLECharacteristicValueChange 开启消息监听
并在 uni.onBLECharacteristicValueChange 方法触发监听到的消息。
templateview!-- 省略前面几步代码 --button clicknotify开启消息监听/button/view
/templatescript setup
import { ref } from vue// 省略前面几步代码// 【8】开启消息监听
function notify() {uni.notifyBLECharacteristicValueChange({deviceId: deviceId.value, // 设备ID在【4】里获取到serviceId: 0000FFE0-0000-1000-8000-00805F9B34FB, // 服务UUID在【6】里能获取到characteristicId: 0000FFE1-0000-1000-8000-00805F9B34FB, // 特征值在【7】里能获取到success(res) {console.log(res)// 接受消息的方法listenValueChange()},fail(err) {console.error(err)}})
}// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {const hexArr Array.prototype.map.call(new Uint8Array(buffer),function (bit) {return (00 bit.toString(16)).slice(-2)})return hexArr.join()
}// 将16进制的内容转成我们看得懂的字符串内容
function hexCharCodeToStr(hexCharCodeStr) {var trimedStr hexCharCodeStr.trim();var rawStr trimedStr.substr(0, 2).toLowerCase() 0x ? trimedStr.substr(2) : trimedStr;var len rawStr.length;if (len % 2 ! 0) {alert(存在非法字符!);return ;}var curCharCode;var resultStr [];for (var i 0; i len; i i 2) {curCharCode parseInt(rawStr.substr(i, 2), 16);resultStr.push(String.fromCharCode(curCharCode));}return resultStr.join();
}// 【9】监听消息变化
function listenValueChange() {uni.onBLECharacteristicValueChange(res {// 结果console.log(res)// 结果里有个value值该值为 ArrayBuffer 类型所以在控制台无法用肉眼观察到必须将该值转换为16进制let resHex ab2hex(res.value)console.log(resHex)// 最后将16进制转换为ascii码就能看到对应的结果let result hexCharCodeToStr(resHex)console.log(result)})
}
/scriptlistenValueChange 方法是用来接收设备传过来的消息。
上面的例子中res 的结果是
{deviceId: B4:10:7B:C4:83:14,serviceId: 0000FFE0-0000-1000-8000-00805F9B34FB,characteristicId: 0000FFE1-0000-1000-8000-00805F9B34FB,value: {}
}设备传过来的内容就放在 value 字段里但因为该字段的类型是 ArrayBuffer所以无法在控制台用肉眼直接观察。于是就通过 ab2hex 方法将该值转成 16进制 最后再用 hexCharCodeToStr 方法将 16进制 转成 ASCII码。
我从设备里发送一段字符串过来leihou App端收到的数据转成 16进制 后的结果6c6569686f75
再从 16进制 转成 ASCII码 后的结果leihou
发送指令
终于到最后一步了。
从 uni-app 和 微信小程序 提供的蓝牙api 来看发送指令只要有2个方法
uni.writeBLECharacteristicValue向低功耗蓝牙设备特征值中写入二进制数据。uni.readBLECharacteristicValue读取低功耗蓝牙设备的特征值的二进制数据值。
这里需要理清一个概念本节的内容为 “发送指令”也就是说从你的app或小程序向其他蓝牙设备发送指令而这个指令分2种情况一种是你要发送一些数据给蓝牙设备另一种情况是你叫蓝牙设备给你发点信息。
uni.writeBLECharacteristicValue
这两种情况我们需要分开讨论先讲讲 uni.writeBLECharacteristicValue 。
uni.writeBLECharacteristicValue 从文档可以看出这个 api 是可以发送一些数据给蓝牙设备但发送的值要转成 ArrayBuffer 。
代码示例
templateview!-- 省略前面几步代码 --button clicksend发送数据/button/view
/templatescript setup
import { ref } from vue// 省略前面几步代码// 【10】发送数据
function send() {// 向蓝牙设备发送一个0x00的16进制数据let msg helloconst buffer new ArrayBuffer(msg.length)const dataView new DataView(buffer)// dataView.setUint8(0, 0)for (var i 0; i msg.length; i) {dataView.setUint8(i, msg.charAt(i).charCodeAt())}uni.writeBLECharacteristicValue({deviceId: deviceId.value, // 设备ID在【4】里获取到serviceId: 0000FFE0-0000-1000-8000-00805F9B34FB, // 服务UUID在【6】里能获取到characteristicId: 0000FFE1-0000-1000-8000-00805F9B34FB, // 特征值在【7】里能获取到value: buffer,success(res) {console.log(res)},fail(err) {console.error(err)}})
}
/script此时如果 uni.writeBLECharacteristicValue 走 success 证明你已经把数据向外成功发送了但不代表设备一定就收到了。
通常设备收到你发送过去的信息会返回一条消息给你而这个回调消息会在 uni.onBLECharacteristicValueChange 触发也就是 第【9】步 那里。但这是蓝牙设备那边控制的你作为前端佬人家“已读不回”你也拿人家没办法。 uni.readBLECharacteristicValue
在 “监听” 部分我们使用了 uni.getBLEDeviceCharacteristics 获取设备的特征值我的设备提供的特征值支持 read 所以可以使用 uni.readBLECharacteristicValue 向蓝牙设备发送一条 “读取” 指令。然后在 uni.onBLECharacteristicValueChange 里可以接收设备发送过来的数据。
代码示例
templateview!-- 省略前面几步代码 --button clickread读取数据/button/view
/templatescript setup
import { ref } from vue// 省略前面几步代码// 【11】读取数据
function read() {uni.readBLECharacteristicValue({deviceId: deviceId.value,serviceId: serviceId.value,characteristicId: characteristicId.value,success(res) {console.log(读取指令发送成功)console.log(res)},fail(err) {console.log(读取指令发送失败)console.error(err)}})
}
/script使用 “读取” 的方式向设备发送指令是不需要另外传值的。
此时我的设备返回 00 这个数据是硬件那边设置的。
在日常工作中uni.readBLECharacteristicValue 的作用主要是读取数据但使用场景不算很多。
我在工作中遇到的场景是蓝牙设备提供了几个接口而且传过来的数据比较大比如传图片给app这边。我就会先用 uni.writeBLECharacteristicValue 告诉设备我现在需要取什么接口的数据然后用 uni.readBLECharacteristicValue 发送读取数据的请求如果数据量比较大就要重复使用 uni.readBLECharacteristicValue 进行读取。比如上面的例子我读第一次的时候返回 00 读第二次就返回 01 ……
最后再提醒一下uni.readBLECharacteristicValue 只负责发送读取的请求并且里面的 success 和 fail 只是返回你本次发送请求的动作是否成功至于对面的蓝牙设备有没有收到这个指令你是不清楚的。
最后需要通过 uni.getBLEDeviceCharacteristics 监听设备传过来的数据。
完整代码
templateviewscroll-viewscroll-yclassboxview classitem v-foritem in blueDeviceList clickconnect(item)viewtextid: {{ item.deviceId }}/text /viewviewtextname: {{ item.name }}/text /view/view/scroll-viewbutton clickinitBlue1 初始化蓝牙/buttonbutton clickdiscovery2 搜索附近蓝牙设备/buttonbutton clickgetServices3 获取蓝牙服务/buttonbutton clickgetCharacteristics4 获取特征值/buttonbutton clicknotify5 开启消息监听/buttonbutton clicksend6 发送数据/buttonbutton clickread7 读取数据/buttonview classmsg_xview classmsg_txt监听到的内容{{ message }}/viewview classmsg_hex监听到的内容十六进制{{ messageHex }}/view /view /view
/templatescript setup
import { ref } from vue// 搜索到的蓝牙设备列表
const blueDeviceList ref([])// 【1】初始化蓝牙
function initBlue() {uni.openBluetoothAdapter({success(res) {console.log(初始化蓝牙成功)console.log(res)},fail(err) {console.log(初始化蓝牙失败)console.error(err)}})
}// 【2】开始搜寻附近设备
function discovery() {uni.startBluetoothDevicesDiscovery({success(res) {console.log(开始搜索)// 开启监听回调uni.onBluetoothDeviceFound(found)},fail(err) {console.log(搜索失败)console.error(err)}})
}// 【3】找到新设备就触发该方法
function found(res) {console.log(res)blueDeviceList.value.push(res.devices[0])
}// 蓝牙设备的id
const deviceId ref()// 【4】连接设备
function connect(data) {console.log(data)deviceId.value data.deviceId // 将获取到的设备ID存起来uni.createBLEConnection({deviceId: deviceId.value,success(res) {console.log(连接成功)console.log(res)// 停止搜索stopDiscovery()uni.showToast({title: 连接成功})},fail(err) {console.log(连接失败)console.error(err)uni.showToast({title: 连接成功,icon: error})}})
}// 【5】停止搜索
function stopDiscovery() {uni.stopBluetoothDevicesDiscovery({success(res) {console.log(停止成功)console.log(res)},fail(err) {console.log(停止失败)console.error(err)}})
}// 【6】获取服务
function getServices() {// 如果是自动链接的话uni.getBLEDeviceServices方法建议使用setTimeout延迟1秒后再执行uni.getBLEDeviceServices({deviceId: deviceId.value,success(res) {console.log(res) // 可以在res里判断有没有硬件佬给你的服务uni.showToast({title: 获取服务成功})},fail(err) {console.error(err)uni.showToast({title: 获取服务失败,icon: error})}})
}// 硬件提供的服务id开发中需要问硬件佬获取该id
const serviceId ref(0000FFE0-0000-1000-8000-00805F9B34FB)// 【7】获取特征值
function getCharacteristics() {// 如果是自动链接的话uni.getBLEDeviceCharacteristics方法建议使用setTimeout延迟1秒后再执行uni.getBLEDeviceCharacteristics({deviceId: deviceId.value,serviceId: serviceId.value,success(res) {console.log(res) // 可以在此判断特征值是否支持读写等操作特征值其实也需要提前向硬件佬索取的uni.showToast({title: 获取特征值成功})},fail(err) {console.error(err)uni.showToast({title: 获取特征值失败,icon: error})}})
}const characteristicId ref(0000FFE1-0000-1000-8000-00805F9B34FB)// 【8】开启消息监听
function notify() {uni.notifyBLECharacteristicValueChange({deviceId: deviceId.value, // 设备idserviceId: serviceId.value, // 监听指定的服务characteristicId: characteristicId.value, // 监听对应的特征值success(res) {console.log(res)listenValueChange()uni.showToast({title: 已开启监听})},fail(err) {console.error(err)uni.showToast({title: 监听失败,icon: error})}})
}// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {const hexArr Array.prototype.map.call(new Uint8Array(buffer),function (bit) {return (00 bit.toString(16)).slice(-2)})return hexArr.join()
}// 将16进制的内容转成我们看得懂的字符串内容
function hexCharCodeToStr(hexCharCodeStr) {var trimedStr hexCharCodeStr.trim();var rawStr trimedStr.substr(0, 2).toLowerCase() 0x ? trimedStr.substr(2) : trimedStr;var len rawStr.length;if (len % 2 ! 0) {alert(存在非法字符!);return ;}var curCharCode;var resultStr [];for (var i 0; i len; i i 2) {curCharCode parseInt(rawStr.substr(i, 2), 16);resultStr.push(String.fromCharCode(curCharCode));}return resultStr.join();
}// 监听到的内容
const message ref()
const messageHex ref() // 十六进制// 【9】监听消息变化
function listenValueChange() {uni.onBLECharacteristicValueChange(res {console.log(res)let resHex ab2hex(res.value)console.log(resHex)messageHex.value resHexlet result hexCharCodeToStr(resHex)console.log(String(result))message.value String(result)})
}// 【10】发送数据
function send() {// 向蓝牙设备发送一个0x00的16进制数据let msg helloconst buffer new ArrayBuffer(msg.length)const dataView new DataView(buffer)// dataView.setUint8(0, 0)for (var i 0; i msg.length; i) {dataView.setUint8(i, msg.charAt(i).charCodeAt())}uni.writeBLECharacteristicValue({deviceId: deviceId.value,serviceId: serviceId.value,characteristicId: characteristicId.value,value: buffer,success(res) {console.log(writeBLECharacteristicValue success, res.errMsg)uni.showToast({title: write指令发送成功})},fail(err) {console.error(err)uni.showToast({title: write指令发送失败,icon: error})}})
}// 【11】读取数据
function read() {uni.readBLECharacteristicValue({deviceId: deviceId.value,serviceId: serviceId.value,characteristicId: characteristicId.value,success(res) {console.log(res)uni.showToast({title: read指令发送成功})},fail(err) {console.error(err)uni.showToast({title: read指令发送失败,icon: error})}})
}
/scriptstyle
.box {width: 98%;height: 400rpx;box-sizing: border-box;margin: 0 auto 20rpx;border: 2px solid dodgerblue;
}
.item {box-sizing: border-box;padding: 10rpx;border-bottom: 1px solid #ccc;
}
button {margin-bottom: 20rpx;
}.msg_x {border: 2px solid seagreen;width: 98%;margin: 10rpx auto;box-sizing: border-box;padding: 20rpx;
}.msg_x .msg_txt {margin-bottom: 20rpx;
}
/style