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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值