diff --git a/WindowsFormsApp6/MainForm.cs b/WindowsFormsApp6/MainForm.cs index 23f659b..5abe910 100644 --- a/WindowsFormsApp6/MainForm.cs +++ b/WindowsFormsApp6/MainForm.cs @@ -446,15 +446,28 @@ namespace WindowsFormsApp6 // 创建平均值行 DataRow avgRow = dataTable.NewRow(); - avgRow["序号"] = "平均时间(s)"; + avgRow["序号"] = $"平均时间(s) 试样{startSample}-{endSample}"; - // 将平均值显示在该组的第一个试样列 - avgRow[$"试样{startSample}"] = groupAvg; + // 将平均值显示在该组的所有试样列(合并显示效果) + for (int i = startSample; i <= endSample; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = groupAvg; + } + } // 其他列设置为空 - for (int i = 1; i <= currentSampleCount; i++) + for (int i = 1; i < startSample; i++) { - if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + if (dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = DBNull.Value; + } + } + for (int i = endSample + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) { avgRow[$"试样{i}"] = DBNull.Value; } @@ -483,7 +496,7 @@ namespace WindowsFormsApp6 /// /// 读取Form2数据(液体吸收量) - /// PLC地址:D420 - 初始重量, D422 - 浸润后重量, D402 - 浸润时间, D406 - 悬挂时间, D310 - 运行速度 + /// PLC地址:D420 - 初始重量, D422 - 浸润后重量, D402 - 浸润时间, D406 - 悬挂时间, D410 - 运行速度 /// 信号量:M252 /// 每次测试动态添加一列显示,每5个试样计算平均值、最大值、标准偏差 /// @@ -491,26 +504,25 @@ namespace WindowsFormsApp6 { try { - // 读取当前试样的数据(每次读取1个寄存器 = 2个字节) - // 读取初始重量(D420,1个寄存器) - ushort[] initialWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 420, 1); - double initialWeight = initialWeightReg[0]; + // 读取初始重量(D420,2个寄存器,浮点数,单位:g,精度0.01g) + ushort[] initialWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 420, 2); + double initialWeight = ConvertRegistersToDouble(initialWeightReg); - // 读取浸润后重量(D422,1个寄存器) - ushort[] afterWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 422, 1); - double afterWeight = afterWeightReg[0]; + // 读取浸润后重量(D422,2个寄存器,浮点数,单位:g,精度0.01g) + ushort[] afterWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 422, 2); + double afterWeight = ConvertRegistersToDouble(afterWeightReg); - // 读取浸润时间(D402,1个寄存器) + // 读取浸润时间(D402,1个寄存器,整数,单位:秒) ushort[] soakTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 402, 1); - int soakTime = soakTimeReg[0]; + int soakTime = ConvertSingleRegisterToInt(soakTimeReg[0]); - // 读取悬挂时间(D406,1个寄存器) + // 读取悬挂时间(D406,1个寄存器,整数,单位:秒) ushort[] hangTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 406, 1); - int hangTime = hangTimeReg[0]; + int hangTime = ConvertSingleRegisterToInt(hangTimeReg[0]); - // 读取运行速度(D310,1个寄存器) - ushort[] runSpeedReg = _modbusMaster.ReadHoldingRegisters(slaveId, 310, 1); - int runSpeed = runSpeedReg[0]; + // 读取运行速度(D410,1个寄存器,整数,单位:mm/min) + ushort[] runSpeedReg = _modbusMaster.ReadHoldingRegisters(slaveId, 410, 1); + int runSpeed = ConvertSingleRegisterToInt(runSpeedReg[0]); // 使用反射获取Form2的私有字段 var sampleDataTableField = form2Instance.GetType() @@ -726,7 +738,7 @@ namespace WindowsFormsApp6 { // 7. 液体吸收量平均值行 DataRow avgRow = dataTable.NewRow(); - avgRow["序号"] = "液体吸收量平均值(%)"; + avgRow["序号"] = $"液体吸收量平均值(%) 试样{startSample}-{endSample}"; double avgAbsorption = groupAbsorptions.Average(); // 检查NaN @@ -735,10 +747,25 @@ namespace WindowsFormsApp6 avgAbsorption = 0; } - avgRow[$"试样{startSample}"] = avgAbsorption; - for (int i = 1; i <= currentSampleCount; i++) + // 将平均值显示在该组的所有试样列(合并显示效果) + for (int i = startSample; i <= endSample; i++) { - if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + if (dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = avgAbsorption; + } + } + // 其他列设置为空 + for (int i = 1; i < startSample; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = DBNull.Value; + } + } + for (int i = endSample + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) { avgRow[$"试样{i}"] = DBNull.Value; } @@ -747,7 +774,7 @@ namespace WindowsFormsApp6 // 8. 液体吸收量最大值行 DataRow maxRow = dataTable.NewRow(); - maxRow["序号"] = "液体吸收量最大值(%)"; + maxRow["序号"] = $"液体吸收量最大值(%) 试样{startSample}-{endSample}"; double maxAbsorption = groupAbsorptions.Max(); // 检查NaN @@ -756,10 +783,25 @@ namespace WindowsFormsApp6 maxAbsorption = 0; } - maxRow[$"试样{startSample}"] = maxAbsorption; - for (int i = 1; i <= currentSampleCount; i++) + // 将最大值显示在该组的所有试样列(合并显示效果) + for (int i = startSample; i <= endSample; i++) { - if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + if (dataTable.Columns.Contains($"试样{i}")) + { + maxRow[$"试样{i}"] = maxAbsorption; + } + } + // 其他列设置为空 + for (int i = 1; i < startSample; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + maxRow[$"试样{i}"] = DBNull.Value; + } + } + for (int i = endSample + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) { maxRow[$"试样{i}"] = DBNull.Value; } @@ -768,7 +810,7 @@ namespace WindowsFormsApp6 // 9. 标准偏差行 DataRow stdDevRow = dataTable.NewRow(); - stdDevRow["序号"] = "标准偏差"; + stdDevRow["序号"] = $"标准偏差 试样{startSample}-{endSample}"; double stdDev = groupAbsorptions.Count > 1 ? CalculateStandardDeviation(groupAbsorptions.ToArray()) : 0; // 检查NaN @@ -777,10 +819,25 @@ namespace WindowsFormsApp6 stdDev = 0; } - stdDevRow[$"试样{startSample}"] = stdDev; - for (int i = 1; i <= currentSampleCount; i++) + // 将标准偏差显示在该组的所有试样列(合并显示效果) + for (int i = startSample; i <= endSample; i++) { - if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + if (dataTable.Columns.Contains($"试样{i}")) + { + stdDevRow[$"试样{i}"] = stdDev; + } + } + // 其他列设置为空 + for (int i = 1; i < startSample; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + stdDevRow[$"试样{i}"] = DBNull.Value; + } + } + for (int i = endSample + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) { stdDevRow[$"试样{i}"] = DBNull.Value; } @@ -807,7 +864,7 @@ namespace WindowsFormsApp6 } /// - /// 将寄存器数据转换为double(假设寄存器值为实际值*100) + /// 将寄存器数据转换为double(用于重量数据,假设寄存器值为实际值*100) /// private double ConvertRegistersToDouble(ushort[] registers) { @@ -827,7 +884,7 @@ namespace WindowsFormsApp6 } /// - /// 将寄存器数据转换为int + /// 将寄存器数据转换为int(用于时间、速度等整数数据) /// private int ConvertRegistersToInt(ushort[] registers) { @@ -837,6 +894,14 @@ namespace WindowsFormsApp6 return (registers[0] << 16) | registers[1]; } + /// + /// 将单个寄存器数据转换为int(用于时间等单寄存器整数数据) + /// + private int ConvertSingleRegisterToInt(ushort register) + { + return register; + } + /// /// 获取下一个试样索引 /// @@ -1052,7 +1117,7 @@ namespace WindowsFormsApp6 /// /// 读取Form3数据(液体芯吸速率) - /// PLC地址:D200 - 吸水时间(s),D454 - 吸芯高度(mm),每次测试读取1个试样(各2个字节) + /// PLC地址:D200 - 吸水时间(s),D454 - 吸芯高度(mm),每次测试读取1个试样(各1个寄存器用于时间,2个寄存器用于高度) /// /// 数据结构说明: /// - 每组试样包含3次测试数据(试样1_1, 试样1_2, 试样1_3) @@ -1067,11 +1132,11 @@ namespace WindowsFormsApp6 { try { - // 读取吸水时间(D200,1个寄存器 = 2个字节) + // 读取吸水时间(D200,1个寄存器,整数,单位:秒) ushort[] timeRegisters = _modbusMaster.ReadHoldingRegisters(slaveId, 200, 1); - // 读取吸芯高度(D454,1个寄存器 = 2个字节) - ushort[] heightRegisters = _modbusMaster.ReadHoldingRegisters(slaveId, 454, 1); + // 读取吸芯高度(D454,2个寄存器,浮点数,单位:mm,精度0.01mm) + ushort[] heightRegisters = _modbusMaster.ReadHoldingRegisters(slaveId, 454, 2); // 使用反射获取Form3的私有字段 var sampleDataTableField = form3Instance.GetType() @@ -1099,13 +1164,15 @@ namespace WindowsFormsApp6 return; } - // 将寄存器值转换为实际数据(直接使用寄存器值) - double wickingTime = timeRegisters[0]; // 吸水时间(秒) - double wickingHeight = heightRegisters[0]; // 吸芯高度(mm) + // 将寄存器值转换为实际数据 + // 吸水时间:单个寄存器,整数,单位:秒 + int wickingTime = ConvertSingleRegisterToInt(timeRegisters[0]); + + // 吸芯高度:2个寄存器,浮点数,单位:mm,精度0.01mm + double wickingHeight = ConvertRegistersToDouble(heightRegisters); // 检查数据有效性 - if (double.IsNaN(wickingTime) || double.IsInfinity(wickingTime) || - double.IsNaN(wickingHeight) || double.IsInfinity(wickingHeight)) + if (wickingTime <= 0 || double.IsNaN(wickingHeight) || double.IsInfinity(wickingHeight)) { System.Diagnostics.Debug.WriteLine("读取的数据无效,跳过本次读取"); return;