IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 15_微信小程序-BLE低功耗蓝牙开发-读写特征值 -> 正文阅读

[移动开发]15_微信小程序-BLE低功耗蓝牙开发-读写特征值

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

currWriteChar: {    // 当前选择的写入特征值
	flag: false, // 表示是否可用
	serId: "", // 服务ID
	charId: "" // 特征值ID
},
currReadChar: { // 当前选择的读/通知特征值
	flag: false, // 表示是否可用
	serId: "", // 服务ID
	charId: "" // 特征值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是一个ArrayBuffer
		var 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

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:41:20  更:2022-02-28 15:42:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 15:39:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码