From 14d6fa7ccb12c240c1db5d491e8df23ae7b165a6 Mon Sep 17 00:00:00 2001 From: fengerli <528575642@qq.com> Date: Fri, 21 Nov 2025 18:47:20 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8C=BA=E5=88=86?= =?UTF-8?q?=E5=9B=BE=E7=89=87=EF=BC=8C=E5=8A=A8=E7=94=BB=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/6155/deviceDetail.vue | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pages/6155/deviceDetail.vue b/pages/6155/deviceDetail.vue index f9a4375..58bfff9 100644 --- a/pages/6155/deviceDetail.vue +++ b/pages/6155/deviceDetail.vue @@ -77,7 +77,7 @@ 泛光模式 - - + + @@ -422,15 +422,11 @@ } switch (this.formData.mode) { case 0: - - txt = "强光模式"; - break; case 1: txt = "弱光模式"; break; - case 2: txt = "爆闪模式"; break; @@ -773,7 +769,7 @@ } - //FA 09 0C 84 FB 09 00 [01~08] + 3200字节 +FF 数据格式 + //FA 09 0C 84 FE 09 00 [01~08] + 3200字节 +FF 数据格式 var buffer = new ArrayBuffer(bufferSize); var dataView = new DataView(buffer); if (childPacket == 1) { @@ -781,7 +777,7 @@ dataView.setUint8(1, 0x09); // 帧头 dataView.setUint8(2, 0x0C); // 帧头 dataView.setUint8(3, 0x84); // 帧头 - dataView.setUint8(4, 0xFD); // 帧头 + dataView.setUint8(4, 0xFE); // 帧头 dataView.setUint8(5, 0x09); dataView.setUint8(6, 0x00); // 帧头 dataView.setUint8(7, currentPacket); //包序号 @@ -1581,7 +1577,7 @@ dataView.setUint8(bufferSize - 1, 0xFF); - let inteval = 100; + let inteval = 200; //parseInt(this.inteval ? this.inteval : 80); //console.log("inteval=", inteval) ble.sendData(f.deviceId, buffer, f.writeServiceId, f From 97b6825420f88774db9190c2ff00b9351032a9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=AE=E5=BE=AE=E4=B8=80=E7=AC=91?= <709648985@qq.com> Date: Sat, 22 Nov 2025 18:28:43 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D6155=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=AD=97=E4=BD=93?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E9=97=AE=E9=A2=98,=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E5=8F=96=E5=80=BC=E5=8A=A0=E8=BD=BD=E9=A2=84=E7=83=AD=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/TextToHex/TextToHexV1.vue | 63 +++++++++++- pages/6155/deviceDetail.vue | 147 ++++++++++++++------------- 2 files changed, 137 insertions(+), 73 deletions(-) diff --git a/components/TextToHex/TextToHexV1.vue b/components/TextToHex/TextToHexV1.vue index 210407a..36bfc99 100644 --- a/components/TextToHex/TextToHexV1.vue +++ b/components/TextToHex/TextToHexV1.vue @@ -34,7 +34,9 @@ currentCanvasWidth: 0, currentCanvasHeight: 0, // Canvas上下文(复用) - ctx: null + ctx: null, + // 标记是否已经预热过画布 + canvasWarmed: false }; }, computed: { @@ -62,10 +64,67 @@ this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight); }, + /** + * 预热画布,确保画布和字体完全准备好(解决APP重新打开后第一次获取数据不完整的问题) + */ + async warmupCanvas() { + if (this.canvasWarmed) { + return; + } + + try { + // 设置画布尺寸 + this.currentCanvasWidth = 16; + this.currentCanvasHeight = 16; + + // 清空画布 + this.clearCanvas(); + + // 绘制一个测试字符来预热字体和画布 + this.ctx.setFillStyle(this.color); + this.ctx.setFontSize(this.fontSize); + this.ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`; + this.ctx.setTextBaseline('middle'); + this.ctx.fillText('测', 0, 8); + + // 等待画布绘制完成 + await new Promise((resolve) => { + this.ctx.draw(false, () => { + // 获取一次测试数据,确保canvasGetImageData API已准备好 + setTimeout(() => { + uni.canvasGetImageData({ + canvasId: 'reusableCanvas', + x: 0, + y: 0, + width: 16, + height: 16, + success: () => { + this.canvasWarmed = true; + resolve(); + }, + fail: () => { + this.canvasWarmed = true; + resolve(); + } + }); + }, 100); + }); + }); + + // 额外等待确保字体完全加载 + await new Promise(resolve => setTimeout(resolve, 200)); + } catch (ex) { + console.log("画布预热异常:", ex); + this.canvasWarmed = true; // 即使失败也标记为已预热,避免重复尝试 + } + }, + /** * 复用单个Canvas处理所有文本行 */ async drawAndGetPixels() { + // 第一次调用时先预热画布(解决APP重新打开后第一次获取数据不完整的问题) + await this.warmupCanvas(); let convertCharToMatrix=function(imageData) { // console.log("imgData=",imageData) @@ -119,7 +178,7 @@ // 3. 设置文字样式 ctx.setFillStyle(this.color); - ctx.setTextBaseline('middle'); + ctx.setTextBaseline('middle'); // ctx.setTextAlign('center') ctx.setFontSize(this.fontSize); ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`; diff --git a/pages/6155/deviceDetail.vue b/pages/6155/deviceDetail.vue index 58bfff9..d31c03c 100644 --- a/pages/6155/deviceDetail.vue +++ b/pages/6155/deviceDetail.vue @@ -1528,78 +1528,58 @@ var promise = new Promise((resolve, reject) => { try { + // 设备协议:FA 06/07/08 01 00 + 256字节数据 + FF + // 每个文本行只需要一个261字节的包 + const bufferSize = 261; + const dataSize = 256; // 数据部分固定256字节 - let packetSize = rgbdata.length; //每包均分的数量 - let mode = rgbdata.length % packetSize; //最后一包的数量 - let cnt = - 1; // parseInt(rgbdata.length / packetSize) + (mode > 0 ? 1 :0); //总包数量 - let curr = 1; //当前包序号 + let buffer = new ArrayBuffer(bufferSize); + let dataView = new DataView(buffer); - let sendNext = () => { - - if (curr > cnt) { - resolve(); - return; - } - - let bufferSize = 261; - - console.log("bufferSize=", bufferSize) - - let buffer = new ArrayBuffer(bufferSize); - let dataView = new DataView(buffer); - let startIndex = (curr - 1) * packetSize; - - let endIndex = Math.min(startIndex + packetSize, rgbdata - .length); - if (startIndex > endIndex) { - - return; - } - - let packetData = rgbdata.slice(startIndex, - endIndex); //取一片数据发送 - console.log("packetData.length=", packetData.length); - let start = 0; - if (curr == 1) { - dataView.setUint8(0, 0xFA); - dataView.setUint8(1, type); - dataView.setUint8(2, 0x01); - dataView.setUint8(3, 0x00); - - - start = 4; - } - - for (let i = 0; i < packetData.length; i++) { - dataView.setUint8(start + i, packetData[i]); - } - - dataView.setUint8(bufferSize - 1, 0xFF); - - let inteval = 200; - //parseInt(this.inteval ? this.inteval : 80); - //console.log("inteval=", inteval) - ble.sendData(f.deviceId, buffer, f.writeServiceId, f - .wirteCharactId, 30).then(() => { - - curr++; - setTimeout(sendNext, inteval); - }).catch(err => { - - if (err.code == '10007') { - setTimeout(sendNext, inteval); - } else { - reject(err); - } - }); + // 写入头部:FA 06/07/08 01 00 + dataView.setUint8(0, 0xFA); + dataView.setUint8(1, type); + dataView.setUint8(2, 0x01); + dataView.setUint8(3, 0x00); + // 写入数据(最多256字节),确保数据是数字格式 + let actualDataSize = Math.min(rgbdata.length, dataSize); + for (let i = 0; i < actualDataSize; i++) { + // 确保数据是数字格式,如果是字符串则转换 + let byteValue = typeof rgbdata[i] === 'string' ? these.toByteValue(rgbdata[i]) : rgbdata[i]; + dataView.setUint8(4 + i, byteValue); } - sendNext(); - } catch (ex) { - console.log("ex=", ex); + // 用0填充剩余数据部分(如果数据不足256字节) + for (let i = 4 + actualDataSize; i < bufferSize - 1; i++) { + dataView.setUint8(i, 0x00); + } + // 写入尾部:FF + dataView.setUint8(bufferSize - 1, 0xFF); + + console.log(`发送文本数据包: type=0x${type.toString(16)}, 数据长度=${actualDataSize}, 总长度=${bufferSize}`); + + // 发送数据包 + ble.sendData(f.deviceId, buffer, f.writeServiceId, f + .wirteCharactId, 100).then(() => { + resolve(); + }).catch(err => { + if (err.code == '10007') { + // 重试 + setTimeout(() => { + ble.sendData(f.deviceId, buffer, f.writeServiceId, f + .wirteCharactId, 100).then(() => { + resolve(); + }).catch(reject); + }, 100); + } else { + reject(err); + } + }); + + } catch (ex) { + console.log("构建数据包异常:", ex); reject(ex); } }); @@ -1612,9 +1592,10 @@ var result = null; try { console.log("this.$refs.textToHex=", this.$refs.textToHex); + // 获取像素数据(组件内部会自动预热画布) result = await this.$refs.textToHex.drawAndGetPixels(); } catch (ex) { - console.log("ex=", ex); + console.log("获取画布数据异常:", ex); } if (!result) { hideLoading(this); @@ -1622,7 +1603,10 @@ } console.log("result=", result); result = result.map(level1 => { - return level1.flat(Infinity); + return level1.flat(Infinity).map(item => { + // 确保数据转换为数字格式,避免字符串格式导致的问题 + return typeof item === 'string' ? these.toByteValue(item) : item; + }); }); console.log("result=", result); @@ -1643,6 +1627,9 @@ let h3dic = [0x06, 0x07, 0x08]; let pros = []; let flag = true; + // 在开始发送前添加延迟,确保数据完全准备好(解决第一次发送第一个字缺失的问题) + await new Promise(resolve => setTimeout(resolve, 500)); + for (var i = 0; i < result.length; i++) { let str = this.formData.textLines[i]; @@ -1651,14 +1638,32 @@ let width = str.length * 16; var rgb = result[i]; + + // 确保数据是数组且已转换 + if (!Array.isArray(rgb)) { + console.error(`第${i+1}行数据格式错误:`, rgb); + flag = false; + break; + } + + // 第一次发送前额外延迟,确保设备完全准备好 + if (i === 0) { + console.log("准备发送第一个文本行,等待设备准备好..."); + await new Promise(resolve => setTimeout(resolve, 500)); + } try { - // console.log("1111"); + console.log(`开始发送第${i+1}个文本行 (type=0x${h3dic[i].toString(16)})`); await sendTxtPackge(rgb, h3dic[i], str); - // console.log("222222"); + console.log(`第${i+1}个文本行发送完成`); + + // 每个文本行发送完成后,添加延迟确保设备处理完成 + if (i < result.length - 1) { + await new Promise(resolve => setTimeout(resolve, 300)); + } } catch (ex) { flag = false; - console.log("33333"); + console.error(`发送第${i+1}个文本行出现异常:`, ex); break; } }