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; } }