From 5947b15e92d7991afbd2cb38828a2e0567855ca1 Mon Sep 17 00:00:00 2001 From: zqm Date: Fri, 31 Oct 2025 13:30:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DTemperatureData.cs=E4=B8=AD?= =?UTF-8?q?=E6=B8=A9=E5=BA=A6=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E4=BD=BF=E5=85=B6=E7=AC=A6=E5=90=88SDK?= =?UTF-8?q?=E5=AE=9E=E9=99=85=E5=AE=9E=E7=8E=B0=EF=BC=9A1)=20=E5=B0=86?= =?UTF-8?q?=E5=A4=B4=E9=83=A8=E9=95=BF=E5=BA=A6=E4=BB=8E24=E5=AD=97?= =?UTF-8?q?=E8=8A=82=E4=BF=AE=E6=AD=A3=E4=B8=BA9=E5=AD=97=E8=8A=82?= =?UTF-8?q?=EF=BC=9B2)=20=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=E5=B8=83?= =?UTF-8?q?=E5=B1=80=E8=A7=A3=E6=9E=90=E6=96=B9=E5=BC=8F=EF=BC=8C=E4=BD=8E?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E5=9C=A8=E5=89=8D=E5=8D=8A=E9=83=A8=E5=88=86?= =?UTF-8?q?=EF=BC=8C=E9=AB=98=E5=AD=97=E8=8A=82=E5=9C=A8=E5=90=8E=E5=8D=8A?= =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=9B3)=20=E7=A1=AE=E4=BF=9D=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=9A=84=E6=B8=A9=E5=BA=A6=E8=AE=A1=E7=AE=97=E5=85=AC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Toprie/Toprie/TemperatureData.cs | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs index bdf55c3..9a54e74 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/TemperatureData.cs @@ -86,37 +86,30 @@ namespace JoyD.Windows.CS.Toprie /// 温度补偿值 private void ParseRawData(byte[] rawData, float compensationValue) { - // 按照SDK文档,温度数据格式为:24字节头部 + 温度数据 - // 温度数据为每个点2字节,摄氏温度=(H*256+L)/10 - // 温度数据是连续发送的,不需要分开处理奇偶数行 + // 根据SDK实际实现,温度数据格式为: + // 9字节头部 (+TEMP + 4字节长度) + 低字节数据 + 高字节数据 + // 温度计算公式:(低字节 + 高字节*256 - 2730)/10 // 首先检查数据长度是否足够包含头部信息 - if (rawData.Length < 24) + if (rawData.Length < 9) { - System.Diagnostics.Debug.WriteLine("警告: 原始数据长度小于24字节,无法包含有效的头部信息"); + System.Diagnostics.Debug.WriteLine("警告: 原始数据长度小于9字节,无法包含有效的头部信息"); throw new ArgumentException("原始数据长度不足以包含头部信息"); } - // 验证头部信息 - if (!ValidateHeader(rawData)) + // 验证头部标识字符是否为"+TEMP" + string headerMark = Encoding.ASCII.GetString(rawData, 0, 5).TrimEnd('\0'); + if (headerMark != "+TEMP") { - System.Diagnostics.Debug.WriteLine("警告: 温度数据头部信息验证失败,停止解析"); - throw new ArgumentException("温度数据头部信息无效"); + System.Diagnostics.Debug.WriteLine($"警告: 头部标识不匹配,期望'+TEMP',实际为'{headerMark}'"); + // 即使头部不匹配,我们也尝试继续处理,因为有些情况下数据可能没有标准头部 } - // 从头部解析温度数据长度 - int payloadLength = GetPayloadLengthFromHeader(rawData); - int actualDataLength = rawData.Length - 24; // 实际温度数据长度(总长度减去头部长度) + // 计算像素总数 - 根据SDK实现,数据长度应该是:头部(9字节) + 像素数*2 + int totalDataSize = rawData.Length - 9; // 减去9字节头部 + int pixelCount = totalDataSize / 2; // 每个像素点使用2字节(低字节和高字节分开存储) - // 验证数据长度一致性 - if (payloadLength > 0 && payloadLength != actualDataLength) - { - System.Diagnostics.Debug.WriteLine($"警告: 头部指定的数据长度({payloadLength})与实际数据长度({actualDataLength})不匹配"); - // 但我们仍然使用实际数据长度继续处理 - } - - // 根据数据长度自适应确定宽高 - int pixelCount = actualDataLength / 2; // 每个像素点2字节 + // 根据像素数确定宽高 - 使用标准分辨率 int[] widthHeight = GetWidthHeightByPixelCount(pixelCount); int adaptiveWidth = widthHeight[0]; int adaptiveHeight = widthHeight[1]; @@ -124,30 +117,30 @@ namespace JoyD.Windows.CS.Toprie // 输出自适应宽高信息 System.Diagnostics.Debug.WriteLine($"根据数据长度自适应宽高: {adaptiveWidth}x{adaptiveHeight} (像素数: {pixelCount})"); - // 如果自适应宽高与传入的宽高不同,更新宽高并重新初始化矩阵 - if (adaptiveWidth != Width || adaptiveHeight != Height) - { - Width = adaptiveWidth; - Height = adaptiveHeight; - TemperatureMatrix = new float[Height, Width]; - System.Diagnostics.Debug.WriteLine($"注意: 使用自适应宽高替换了原始宽高设置"); - } - - // 跳过24字节的头部信息 - int dataIndex = 24; + // 更新宽高并初始化矩阵 + Width = adaptiveWidth; + Height = adaptiveHeight; + TemperatureMatrix = new float[Height, Width]; // 计算最大可处理的像素数 int maxPixels = Math.Min(pixelCount, Width * Height); - // 遍历所有像素点,按顺序处理温度数据 - for (int row = 0; row < Height && dataIndex + 1 < rawData.Length; row++) + // 按照SDK实现的数据布局处理:低字节在前半部分,高字节在后半部分 + int lowByteOffset = 9; // 低字节数据起始位置(跳过9字节头部) + int highByteOffset = 9 + pixelCount; // 高字节数据起始位置(在低字节数据之后) + + // 遍历所有像素点,按照SDK的方式计算温度 + for (int i = 0; i < maxPixels; i++) { - for (int col = 0; col < Width && dataIndex + 1 < rawData.Length; col++) + // 计算行列索引 + int row = i / Width; + int col = i % Width; + + if (row < Height && col < Width) { - // 按照SDK实际实现计算温度值:摄氏温度=(L + H*256 - 2730)/10 - // 注意:SDK实现是低字节在前,高字节在后,且包含2730的开尔文到摄氏度转换 - int lowByte = rawData[dataIndex]; - int highByte = rawData[dataIndex + 1]; + // 按照SDK实现计算温度值:(低字节 + 高字节*256 - 2730)/10 + int lowByte = rawData[lowByteOffset + i]; + int highByte = rawData[highByteOffset + i]; float rawTemperature = (lowByte + highByte * 256 - 2730) / 10.0f; float compensatedTemperature = rawTemperature + compensationValue; @@ -156,8 +149,6 @@ namespace JoyD.Windows.CS.Toprie // 温补后的温度存入RealTemperatureMatrix(映射到512×384矩阵) MapToRealTemperatureMatrix(row, col, compensatedTemperature); - - dataIndex += 2; } } } @@ -347,10 +338,10 @@ namespace JoyD.Windows.CS.Toprie /// 如果头部信息有效返回true,否则返回false private bool ValidateHeader(byte[] rawData) { - // 根据SDK文档,头部信息的前几个字节包含标识字符和数据长度 + // 根据SDK实际实现,头部信息的前几个字节包含标识字符和数据长度 // 检查原始数据不为空且长度足够 - if (rawData == null || rawData.Length < 24) + if (rawData == null || rawData.Length < 9) return false; // 1. 验证头部标识字符是否为"+TEMP" @@ -362,7 +353,7 @@ namespace JoyD.Windows.CS.Toprie } // 2. 检查数据长度是否合理(至少包含头部+最小温度数据) - if (rawData.Length < 24 + 2) // 24字节头部 + 至少1个温度点(2字节) + if (rawData.Length < 9 + 2) // 9字节头部 + 至少1个温度点(2字节) return false; return true; @@ -375,8 +366,8 @@ namespace JoyD.Windows.CS.Toprie /// 温度数据长度(字节数) private int GetPayloadLengthFromHeader(byte[] rawData) { - // 根据SDK文档,payload_length在头部的第5-8字节 - // 注意:SDK文档指出采用低字节在前的存储方式 + // 根据SDK实际实现,payload_length在头部的第5-8字节 + // 注意:采用低字节在前的存储方式 if (rawData.Length >= 9) { return BitConverter.ToInt32(rawData, 5);