读写特征值之前,用户需要先选择对应的特征值ID,用户选择了特征值ID以后,通过变量记录下来,方便下次使用。

currWriteChar: {    // 当前选择的写入特征值flag: false, // 表示是否可用serId: "", // 服务IDcharId: "" // 特征值ID
},
currReadChar: { // 当前选择的读/通知特征值flag: false, // 表示是否可用serId: "", // 服务IDcharId: "" // 特征值ID
},

为了方便查找到用户选择的是哪个服务下的哪个特征值ID,在特征值view的ID设置为当前对应的服务列表的index和特征值index的集合。

<view class="dialogContentCharsListItemView" id="{{sersIndex}},{{charsIndex}}" bindtap="charsListItemClick">

用户选择以后,直接通过解析出来的index去数组里面索引出来就好了。

charsListItemClick: function(e) {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "点击特征值", e.currentTarget.id);// 解析出当前点击的特征值item在数组中的位置,逗号前面的是service对应的index,逗号后面的是chars中的index位置var index = e.currentTarget.id.split(',');var serIndex = parseInt(index[0], 10);var charIndex = parseInt(index[1], 10);debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "点击的index", serIndex, charIndex);if (serIndex < this.data.devInfo.length && charIndex < this.data.devInfo[serIndex].serviceChars.length) {....根据index从devInfo中获取对应的服务ID和特征值ID并记录在currWriteChar或currReadChar数据中....}
},

选择好了特征值ID后,就可以开始对特征值进行读写了。

写入操作:

sendDataListButtonClick: function(e) {....设备是否连接、是否输入了发送数据的判断处理....var index = parseInt(e.currentTarget.id, 10);if (index < this.data.sendDataList.length) {if (this.data.sendDataList[index].inputText.length != 0){.....根据选择,按16进制或者字符方式解析出输入框的内容,存储到writeValue变量中.....ble.writeDevCharValue(this.userData.currDevId,this.userData.currWriteChar.serId,this.userData.currWriteChar.charId,writeValue,(res, errCode)=> {if (res) {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送成功", errCode);wx.showToast({title: '发送成功',icon: 'none',duration: 1500});} else {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "数据发送失败", errCode);wx.showToast({title: '发送失败',icon: 'none',duration: 1500});}});} else {wx.showToast({title: '请输入发送内容',icon: 'none',duration: 1500})}}
},

这里分为16进制发送和字符发送,这两种发送方式只是在解析输入数据的地方有差别。

还需要注意,根据BLE协议,一次只能发送最大20个字节的数据,当数据量大于20个字节后,就需要进行分包处理,所以在ble模块中新增的writeDevCharValue对需要发送的数据进行了自动的分包处理,防止在某些手机上发送失败。

ble模块的writeDevCharValue接口:

/**
* 写特征值
* @param {string} devId
* @param {string} serId
* @param {string} charId
* @param {ArrayBuffer} writeValue
* @param {function} cb 参数1成功标志:true为成功, 参数2错误码
*/
function writeDevCharValue(devId, serId, charId, writeValue, cb) {.....各种异常判断:蓝牙是否初始化,设备是否连接,writeValue长度是否为零等等.....debug.Debug(BLE_MODULE_NAME, debug.DEBUG_DEBUG,"发送数据", devId, serId, charId);// 如果数据长度超过20,需要做分包发送处理才行let sendArrayBuffer = new ArrayBuffer(20);let uint8ArrayBuffer = new Uint8Array(sendArrayBuffer);let srcArrayBuffer = new Uint8Array(writeValue);let currSendNum = 0;do {let revSendNum = srcArrayBuffer.length-currSendNum; // 剩余的发送字节数let currSendNumTmp = 0; // 本次需要发送的字节数if (revSendNum >= 20) {currSendNumTmp = 20;} else {currSendNumTmp = revSendNum;}for (let i=0; i<currSendNumTmp; i++) {uint8ArrayBuffer[i] = srcArrayBuffer[currSendNum];currSendNum++;}wx.writeBLECharacteristicValue({// 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取deviceId: devId,// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId: serId,// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取characteristicId: charId,// 这里的value是ArrayBuffer类型value: sendArrayBuffer,success: (res) => {// 这里要做到所有数据发送成功才返回成功回调if (currSendNum >= srcArrayBuffer.length) {if (typeof cb == "function") {cb(true, 0);}}},fail: (res) => {if (typeof cb == "function") {cb(false, res.errCode);}debug.Debug(BLE_MODULE_NAME, debug.DEBUG_DEBUG, "writeBLECharacteristicValue 失败", res.errCode, res.errMsg);return;}});} while(currSendNum < srcArrayBuffer.length);
}

BLE数据的读取,并不是直接获取的,而是通过wx.onBLECharacteristicValueChange注册的回调函数返回的,设备通过Notify发送给手机的信息也是通过该回调返回的。

所以我们在blectr.js页面加载的时候就开启该回调,并在界面释放的时候关闭该回调

/*** 生命周期函数--监听页面加载*/
onLoad: function (options) {.....其他操作.....// 设置特征值回调ble.onDevCharValueChange((res) => {// res.value是一个ArrayBuffervar buffer = new Uint8Array(res.value);var currText = "";.....根据用户选择,以16进制显示,还是以字符显示的处理.....// 最长接收显示指定个字符,再长最先接收到在的字符就会被删除var subText = "";if (this.data.recieveText.length + currText.length > BLECTR_RECIEVE_TEXT_MAX_LEN) {subText = this.data.recieveText.slice(this.data.recieveText.length + currText.length - BLECTR_RECIEVE_TEXT_MAX_LEN, this.data.recieveText.length);       this.data.recieveText = subText + currText;} else {this.data.recieveText += currText;}this.setData({['recieveText']: this.data.recieveText});});
},/*** 生命周期函数--监听页面卸载*/
onUnload: function () {.....其他操作.....// 关闭特征值监听ble.offDevCharValueChange(()=> {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "关闭特征值监听");});
},

当用户点击读取按钮的时候,调用一次读取方法就行了

// 读一次对应的特征值ID
recieveReadButtonClick: function(e) {let status = ble.getDevConStaus(this.userData.currDevId);if (status != ble.BLE_CON_SUCCESS) {wx.showToast({title: '设备未连接',icon: 'none',duration: 1500});return;}if (this.userData.currReadChar.flag) {var devID = this.userData.currDevId;var serID = this.userData.currReadChar.serId;var charID = this.userData.currReadChar.charId;debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值", devID, serID, charID);ble.readDevCharValue(devID,serID,charID,(res, errCode)=> {if (res) {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值成功", errCode);} else {debug.Debug(BLECTR_MODUAL_NAME, debug.DEBUG_DEBUG, "读取特征值失败", errCode);}});             } else {wx.showToast({title: '请先选择要读取的ID',icon: 'none',duration: 1500});}
},

最终的实际效果演示视频:

iBLETool读写特征值演示视频-小程序文档类资源-CSDN下载iBLETool读写特征值演示视频更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/Losthome/82439068

15_微信小程序-BLE低功耗蓝牙开发-读写特征值相关推荐

  1. 01_微信小程序-BLE低功耗蓝牙开发-注册和工具安装

    1. 访问微信公众号平台,注册小程序 注意:一个邮箱只能注册一个微信小程序 2. 下载安装开发工具 这里有个重要的东西AppID,注册申请的时候生成的.我们这里只做学习用,所以可以点击后面的测试号,会 ...

  2. 20_微信小程序-BLE低功耗蓝牙开发-发布小程序

    所有功能测试OK了,就剩下最后一步了,那就是把开发好的微信小程序发布出去. 1. 填写小程序信息,登录小程序管理平台,在设置->填写信息,里面填写小程序相关信息(后面我直接把小程序名称改为&qu ...

  3. 08_微信小程序-BLE低功耗蓝牙开发-设备搜索

    遇到的一些问题 BLE相关的好多函数都是异步的,但是BLE的操作又必须按照顺序流程来,否则就会出现问题,所以这里得嵌套大量的回调函数. 普通回调函数中this拿不到data数据的问题 原因:小程序在回 ...

  4. 微信小程序与低功耗蓝牙通信-接受硬件端发送来的数据(四)

    接受数据只要 wx.notifyBLECharacteristicValueChange监听器打开, wx.onBLECharacteristicValueChange是接受数据的函数. 数据接收到后 ...

  5. 微信小程序与低功耗蓝牙通信-往硬件端发送数据(三)

    准备工作: 软件:微信小程序 硬件: 蓝牙设备:hc-09 单片机:stm32 微信小程序往硬件端发送数据,对应的函数是wx.writeBLECharacteristicValue,他的参数是:(对应 ...

  6. 【微信小程序控制硬件15 】 开源一个微信小程序,支持蓝牙快速配网+WiFi双控制ESP32-C3应用示范;(附带Demo)

    文章目录 一.前言 二. Blufi乐鑫自研的蓝牙配网协议 ESP32 配网流程 流程图 三.相关代码 3.1 蓝牙快速配网 3.2 蓝牙本地控制 2.3 外设驱动 3.1 蓝牙搜索 3.2 蓝牙服务 ...

  7. 微信小程序直连蓝牙实现控制继电器及串口调试功能--全系统开源工程

    微信小程序直连蓝牙硬件设备,设备控制继电器,灯等设备,同时实现蓝牙串口调试助手等功能,设备能够输出微信小程序发出的蓝牙数据,可为工程师在手机上实现设备串口调试功能,当工程师去现场调试设备,没有带电脑, ...

  8. 微信小程序通过低功耗蓝牙设备进行定位及测距(二)

    定位及测距的原理 微信小程序搜索附近蓝牙设备,通过指定蓝牙名称获取信号轻度rssi,再通过信号强度转化为距离,进而实现定位和测距.(具体实现看代码) 信号响度转距离的公式 代码实现 var point ...

  9. ble 低功耗蓝牙开发学习 嵌入式交流学习

    ble 低功耗蓝牙开发学习 嵌入式交流学习 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 这篇文章教你学会低功耗蓝牙开发,从0到深入,适合自学的学生.初级工程师 前言 随着疫情爆发 ...

  10. Android 8.0 BLE 低功耗蓝牙开发记录

    Android 8.0 BLE 低功耗蓝牙开发记录(1-3)--------------(权限申请篇未完待续) 目的:开源博客,希望大家一起修改博客错误地方,共同完善并会鸣谢提供意见的朋友.为大家提供 ...

最新文章

  1. 你在用什么思想编码:事务脚本 OR 面向对象?
  2. redis php扩展 linux,linux下为php安装redis扩展phpredis
  3. kalixfce不能启动_kali升级2019.4后切换xfce桌面
  4. PL/SQL Developer连接Oracle 11g在Win8 64位系统下乱码
  5. 理解zookeeper选举机制
  6. github打开前端样式丢失_工具资源系列之 github 上各式各样的小徽章从何而来?...
  7. Android技能树 — 网络小结(6)之 OkHttp超超超超超超超详细解析
  8. essential c++源码_Goldenmask - 一键化保护你的 Python 源码
  9. MySQL03:DML语言
  10. centos 减少tty数量的方法
  11. EF BB BF的问题
  12. 基于SSM的实验室预约系统
  13. linux运行Windows模拟器,如何安装和使用Wine,以便在Linux上运行Windows应用程序?...
  14. 记一次js调试(attachEvent, onchange, onpropertychange)
  15. 1016day3:city查询系统json模块、餐厅点菜系统、点餐系统(class类)
  16. C语言求等腰梯形面积,几道C语言的题目!
  17. python爬虫入门实战之爬取美国体育网篮球比赛数据(selenium+xpath)
  18. 经典语录总结:识人篇
  19. geo读取表达矩阵 RNA-seq R语言部分(表达矩阵合并及id转换)
  20. 英汉《营销学》常用词汇-1

热门文章

  1. php filesize stat failed for,PHP filesize()适用于除一个文件之外的所有文件,给出stat失败错误...
  2. 移除List数组中的某一个元素
  3. 数据库设计5-逻辑结构设计
  4. 【前端性能优化】图片加载优化
  5. 简单的网页制作期末作业——html css javascript小礼品购物商城网站
  6. reduce具体使用以及使用reduce,toString,flat进行数组降维
  7. Package inputenc Error: Invalid UTF-8 byte “A1;Improper alphabetic constant. <to be read again>
  8. 专治不明觉厉:深度解密IBM黑科技量子计算机
  9. 常用的页面布局(两栏布局、三栏(圣杯、双飞翼)布局)
  10. 补码1位乘法和补码2位乘法(Booth算法)(三栏式)详解学习