From 2cd1b997a96c1d70148107b3962df7c4d21132cb Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Mon, 5 Jan 2026 09:09:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WindowsFormsApp6/MainForm.cs | 672 +++++++++++++++++++++++++---------- 1 file changed, 475 insertions(+), 197 deletions(-) diff --git a/WindowsFormsApp6/MainForm.cs b/WindowsFormsApp6/MainForm.cs index b3a011f..202ded1 100644 --- a/WindowsFormsApp6/MainForm.cs +++ b/WindowsFormsApp6/MainForm.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Data; using System.Drawing; using System.Windows.Forms; @@ -26,6 +27,22 @@ namespace WindowsFormsApp6 private IModbusMaster _modbusMaster; private System.Windows.Forms.Timer _readTimer; + // Form1历史数据缓存(用于累积显示) + private List form1TimeValues = new List(); + + // Form2历史数据缓存(用于累积显示) + private List form2SampleDataList = new List(); + + // Form2单个试样数据结构 + private class Form2SampleData + { + public double InitialWeight { get; set; } + public double AfterWeight { get; set; } + public int SoakTime { get; set; } + public int HangTime { get; set; } + public int RunSpeed { get; set; } + } + public MainForm() { InitializeComponent(); @@ -297,15 +314,15 @@ namespace WindowsFormsApp6 /// /// 读取Form1数据(液体吸收时间) - /// PLC地址:D200 - 时间(s),每次测试读取1个试样(2个字节,1个寄存器) + /// PLC地址:D200 - 时间(s),每次测试读取1个试样(2个字节) /// 信号量:M103 - /// 每次测试添加一个试样,试样数量动态增长 + /// 每次测试动态添加一列显示,每5个试样计算一次平均值 /// private void ReadForm1Data(byte slaveId) { try { - // 每次只读取1个寄存器(1个试样的数据) + // 读取1个寄存器(2个字节)- D200 ushort[] registers = _modbusMaster.ReadHoldingRegisters(slaveId, 200, 1); // 使用反射获取Form1的私有字段 @@ -315,147 +332,148 @@ namespace WindowsFormsApp6 var currentSampleCountField = form1Instance.GetType() .GetField("currentSampleCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - if (sampleDataTableField != null && currentSampleCountField != null) + if (sampleDataTableField == null || currentSampleCountField == null) { - DataTable dataTable = sampleDataTableField.GetValue(form1Instance) as DataTable; - int currentSampleCount = (int)currentSampleCountField.GetValue(form1Instance); - - if (dataTable != null) + System.Diagnostics.Debug.WriteLine("无法获取Form1的私有字段"); + return; + } + + DataTable dataTable = sampleDataTableField.GetValue(form1Instance) as DataTable; + int currentSampleCount = (int)currentSampleCountField.GetValue(form1Instance); + + if (dataTable == null) + { + System.Diagnostics.Debug.WriteLine("DataTable为空"); + return; + } + + // 转换寄存器值为实际时间(秒) + double timeValue = registers[0] / 10.0; + + // 检查NaN + if (double.IsNaN(timeValue) || double.IsInfinity(timeValue)) + { + System.Diagnostics.Debug.WriteLine("读取的时间值无效,跳过本次读取"); + return; + } + + // 添加到历史数据 + form1TimeValues.Add(timeValue); + + // 新试样的索引 + int newSampleIndex = form1TimeValues.Count; + + // 如果需要扩展列数 + if (newSampleIndex > currentSampleCount) + { + // 添加新列到DataTable + if (!dataTable.Columns.Contains($"试样{newSampleIndex}")) { - // 移除旧的平均值行 - var avgRows = dataTable.Select("序号 = '平均时间(s)'"); - foreach (var row in avgRows) - { - dataTable.Rows.Remove(row); - } + dataTable.Columns.Add($"试样{newSampleIndex}", typeof(double)); + } + + // 更新currentSampleCount + currentSampleCount = newSampleIndex; + currentSampleCountField.SetValue(form1Instance, currentSampleCount); + + // 重新初始化DataGridView以显示新列 + this.Invoke(new Action(() => + { + var initMethod = form1Instance.GetType() + .GetMethod("InitializeDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + initMethod?.Invoke(form1Instance, null); + })); + + // 重新获取DataTable(可能已重新绑定) + dataTable = sampleDataTableField.GetValue(form1Instance) as DataTable; + } - // 获取所有现有的时间行 - var timeRows = dataTable.AsEnumerable() - .Where(r => r.Field("序号") == "时间(s)") - .ToList(); + // 清空所有数据,重新构建 + dataTable.Clear(); - // 计算当前已有的试样数量 - int existingSampleCount = timeRows.Count; - int newSampleIndex = existingSampleCount + 1; - - // 如果新试样索引超过当前列数,需要动态添加列 - if (newSampleIndex > currentSampleCount) - { - // 动态扩展DataTable列 - if (!dataTable.Columns.Contains($"试样{newSampleIndex}")) - { - dataTable.Columns.Add($"试样{newSampleIndex}", typeof(double)); - } - - // 更新currentSampleCount - currentSampleCountField.SetValue(form1Instance, newSampleIndex); - currentSampleCount = newSampleIndex; - - // 重新初始化DataGridView以显示新列 - this.Invoke(new Action(() => - { - var initMethod = form1Instance.GetType() - .GetMethod("InitializeDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - initMethod?.Invoke(form1Instance, null); - })); - } - - // 创建新数据行(添加新试样) - DataRow dataRow = dataTable.NewRow(); - dataRow["序号"] = "时间(s)"; - - // 将新读取的时间值转换并填充到对应的试样列 - double timeValue = registers[0] / 10.0; // 转换为秒 - dataRow[$"试样{newSampleIndex}"] = timeValue; - - // 其他列设置为空 - for (int i = 1; i < newSampleIndex; i++) - { - if (dataTable.Columns.Contains($"试样{i}")) - { - dataRow[$"试样{i}"] = DBNull.Value; - } - } - - // 添加新数据行 - dataTable.Rows.Add(dataRow); - - // 重新获取所有时间行(包括刚添加的) - timeRows = dataTable.AsEnumerable() - .Where(r => r.Field("序号") == "时间(s)") - .ToList(); - - // 计算平均值:每5个试样计算一次平均值 - int totalSamples = timeRows.Count; - int groupCount = (int)Math.Ceiling(totalSamples / 5.0); - - for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) - { - int startSample = groupIndex * 5 + 1; - int endSample = Math.Min(startSample + 4, totalSamples); - - // 计算该组的平均值 - double groupSum = 0; - int validCount = 0; - - for (int i = startSample; i <= endSample; i++) - { - var row = timeRows[i - 1]; // 索引从0开始 - - // 找到该行中有值的列 - for (int col = 1; col <= currentSampleCount; col++) - { - if (dataTable.Columns.Contains($"试样{col}") && - row[$"试样{col}"] != DBNull.Value) - { - double value = Convert.ToDouble(row[$"试样{col}"]); - if (value > 0) - { - groupSum += value; - validCount++; - break; // 每行只取一个有效值 - } - } - } - } - - if (validCount > 0) - { - double groupAvg = groupSum / validCount; - - // 创建平均值行 - DataRow avgRow = dataTable.NewRow(); - avgRow["序号"] = "平均时间(s)"; - - // 将平均值显示在该组的第一个试样列 - avgRow[$"试样{startSample}"] = groupAvg; - - // 其他列设置为空 - for (int i = 1; i <= currentSampleCount; i++) - { - if (i != startSample && dataTable.Columns.Contains($"试样{i}")) - { - avgRow[$"试样{i}"] = DBNull.Value; - } - } - - dataTable.Rows.Add(avgRow); - } - } - - // 刷新显示 - dataTable.AcceptChanges(); - this.Invoke(new Action(() => - { - // 触发Form1的界面刷新 - var refreshMethod = form1Instance.GetType() - .GetMethod("RefreshDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - refreshMethod?.Invoke(form1Instance, null); - })); - - System.Diagnostics.Debug.WriteLine($"Form1数据读取成功:试样 #{newSampleIndex}"); + // 创建时间行 + DataRow timeRow = dataTable.NewRow(); + timeRow["序号"] = "时间(s)"; + + // 填充所有历史数据 + for (int i = 0; i < form1TimeValues.Count; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + timeRow[$"试样{i + 1}"] = form1TimeValues[i]; } } + + // 其余列设为空 + for (int i = form1TimeValues.Count + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + timeRow[$"试样{i}"] = DBNull.Value; + } + } + + dataTable.Rows.Add(timeRow); + + // 计算并添加平均值行:每5个试样一组 + int totalSamples = form1TimeValues.Count; + int groupCount = (int)Math.Ceiling((double)totalSamples / 5.0); + + for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) + { + int startSample = groupIndex * 5 + 1; + int endSample = Math.Min(startSample + 4, totalSamples); + + // 计算该组的平均值 + double groupSum = 0; + int validCount = 0; + + for (int i = startSample; i <= endSample; i++) + { + groupSum += form1TimeValues[i - 1]; + validCount++; + } + + if (validCount > 0) + { + double groupAvg = groupSum / validCount; + + // 检查NaN + if (double.IsNaN(groupAvg) || double.IsInfinity(groupAvg)) + { + groupAvg = 0; + } + + // 创建平均值行 + DataRow avgRow = dataTable.NewRow(); + avgRow["序号"] = "平均时间(s)"; + + // 将平均值显示在该组的第一个试样列 + avgRow[$"试样{startSample}"] = groupAvg; + + // 其他列设置为空 + for (int i = 1; i <= currentSampleCount; i++) + { + if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = DBNull.Value; + } + } + + dataTable.Rows.Add(avgRow); + } + } + + // 刷新显示 + dataTable.AcceptChanges(); + this.Invoke(new Action(() => + { + var refreshMethod = form1Instance.GetType() + .GetMethod("RefreshDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + refreshMethod?.Invoke(form1Instance, null); + })); + + System.Diagnostics.Debug.WriteLine($"Form1数据读取成功:试样{newSampleIndex},时间={timeValue:F2}秒,累计{totalSamples}个试样"); } catch (Exception ex) { @@ -467,14 +485,33 @@ namespace WindowsFormsApp6 /// 读取Form2数据(液体吸收量) /// PLC地址:D420 - 初始重量, D422 - 浸润后重量, D402 - 浸润时间, D406 - 悬挂时间, D310 - 运行速度 /// 信号量:M252 - /// - /// - /// 读取Form2数据 - 每次读取一个试样的数据并累加 + /// 每次测试动态添加一列显示,每5个试样计算平均值、最大值、标准偏差 /// private void ReadForm2Data(byte slaveId) { try { + // 读取当前试样的数据(每次读取2个字节) + // 读取初始重量(D420,2字节) + ushort[] initialWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 420, 2); + double initialWeight = ConvertRegistersToDouble(initialWeightReg); + + // 读取浸润后重量(D422,2字节) + ushort[] afterWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 422, 2); + double afterWeight = ConvertRegistersToDouble(afterWeightReg); + + // 读取浸润时间(D402,2字节) + ushort[] soakTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 402, 2); + int soakTime = ConvertRegistersToInt(soakTimeReg); + + // 读取悬挂时间(D406,2字节) + ushort[] hangTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 406, 2); + int hangTime = ConvertRegistersToInt(hangTimeReg); + + // 读取运行速度(D310,2字节) + ushort[] runSpeedReg = _modbusMaster.ReadHoldingRegisters(slaveId, 310, 2); + int runSpeed = ConvertRegistersToInt(runSpeedReg); + // 使用反射获取Form2的私有字段 var sampleDataTableField = form2Instance.GetType() .GetField("sampleDataTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); @@ -497,69 +534,263 @@ namespace WindowsFormsApp6 return; } - // 读取当前试样的数据(每次读取2个字节) - // 读取初始重量(D420,2字节) - ushort[] initialWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 420, 2); - double initialWeight = ConvertRegistersToDouble(initialWeightReg); - - // 读取浸润后重量(D422,2字节) - ushort[] afterWeightReg = _modbusMaster.ReadHoldingRegisters(slaveId, 422, 2); - double afterWeight = ConvertRegistersToDouble(afterWeightReg); - - // 读取浸润时间(D402,2字节) - ushort[] soakTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 402, 2); - int soakTime = ConvertRegistersToInt(soakTimeReg); - - // 读取悬挂时间(D406,2字节) - ushort[] hangTimeReg = _modbusMaster.ReadHoldingRegisters(slaveId, 406, 2); - int hangTime = ConvertRegistersToInt(hangTimeReg); - - // 读取运行速度(D310,2字节) - ushort[] runSpeedReg = _modbusMaster.ReadHoldingRegisters(slaveId, 310, 2); - int runSpeed = ConvertRegistersToInt(runSpeedReg); - - // 确定当前试样索引(基于现有数据) - int sampleIndex = GetNextSampleIndex(dataTable, currentSampleCount); - - if (sampleIndex >= currentSampleCount) + // 添加到历史数据 + form2SampleDataList.Add(new Form2SampleData { - // 需要扩展试样数量 - currentSampleCount = sampleIndex + 1; + InitialWeight = initialWeight, + AfterWeight = afterWeight, + SoakTime = soakTime, + HangTime = hangTime, + RunSpeed = runSpeed + }); + + // 新试样的索引 + int newSampleIndex = form2SampleDataList.Count; + + // 如果需要扩展列数 + if (newSampleIndex > currentSampleCount) + { + // 添加新列到DataTable + if (!dataTable.Columns.Contains($"试样{newSampleIndex}")) + { + dataTable.Columns.Add($"试样{newSampleIndex}", typeof(object)); + } + + // 更新currentSampleCount + currentSampleCount = newSampleIndex; currentSampleCountField.SetValue(form2Instance, currentSampleCount); - // 重新初始化DataTable和DataGridView + // 重新初始化DataGridView以显示新列 this.Invoke(new Action(() => { - var setSampleCountMethod = form2Instance.GetType() - .GetMethod("SetSampleCount", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); - setSampleCountMethod?.Invoke(form2Instance, new object[] { currentSampleCount }); + var initMethod = form2Instance.GetType() + .GetMethod("InitializeDataGridView", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + initMethod?.Invoke(form2Instance, null); })); - // 重新获取更新后的DataTable + // 重新获取DataTable(可能已重新绑定) dataTable = sampleDataTableField.GetValue(form2Instance) as DataTable; } - // 收集所有试样的数据(包括新读取的) - double[] initialWeights = new double[currentSampleCount]; - double[] afterWeights = new double[currentSampleCount]; - string[] soakTimes = new string[currentSampleCount]; - string[] hangTimes = new string[currentSampleCount]; - string[] runSpeeds = new string[currentSampleCount]; + // 清空所有数据,重新构建 + dataTable.Clear(); - // 从现有数据中提取已有试样的数据 - ExtractExistingData(dataTable, initialWeights, afterWeights, soakTimes, hangTimes, runSpeeds, sampleIndex); + int totalSamples = form2SampleDataList.Count; - // 添加新读取的试样数据 - initialWeights[sampleIndex] = initialWeight; - afterWeights[sampleIndex] = afterWeight; - soakTimes[sampleIndex] = $"{soakTime}s"; - hangTimes[sampleIndex] = $"{hangTime}s"; - runSpeeds[sampleIndex] = $"{runSpeed}mm/min"; + // 1. 初始重量行 + DataRow initialRow = dataTable.NewRow(); + initialRow["序号"] = "初始重量(g)"; + for (int i = 0; i < totalSamples; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + initialRow[$"试样{i + 1}"] = form2SampleDataList[i].InitialWeight; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + initialRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(initialRow); - // 更新显示(使用Form2的UpdateDisplay逻辑) - UpdateForm2Display(dataTable, initialWeights, afterWeights, soakTimes, hangTimes, runSpeeds, currentSampleCount); + // 2. 浸润后重量行 + DataRow afterRow = dataTable.NewRow(); + afterRow["序号"] = "浸润后重量(g)"; + for (int i = 0; i < totalSamples; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + afterRow[$"试样{i + 1}"] = form2SampleDataList[i].AfterWeight; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + afterRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(afterRow); - // 刷新界面 + // 3. 液体吸收量行 (%) + DataRow absorptionRow = dataTable.NewRow(); + absorptionRow["序号"] = "液体吸收量(%)"; + double[] absorptions = new double[totalSamples]; + for (int i = 0; i < totalSamples; i++) + { + if (form2SampleDataList[i].InitialWeight > 0) + { + absorptions[i] = ((form2SampleDataList[i].AfterWeight - form2SampleDataList[i].InitialWeight) + / form2SampleDataList[i].InitialWeight) * 100; + + // 检查NaN + if (double.IsNaN(absorptions[i]) || double.IsInfinity(absorptions[i])) + { + absorptions[i] = 0; + } + } + else + { + absorptions[i] = 0; + } + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + absorptionRow[$"试样{i + 1}"] = absorptions[i]; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + absorptionRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(absorptionRow); + + // 4. 浸润时间行 + DataRow soakTimeRow = dataTable.NewRow(); + soakTimeRow["序号"] = "浸润时间"; + for (int i = 0; i < totalSamples; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + soakTimeRow[$"试样{i + 1}"] = $"{form2SampleDataList[i].SoakTime}s"; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + soakTimeRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(soakTimeRow); + + // 5. 悬挂时间行 + DataRow hangTimeRow = dataTable.NewRow(); + hangTimeRow["序号"] = "悬挂时间"; + for (int i = 0; i < totalSamples; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + hangTimeRow[$"试样{i + 1}"] = $"{form2SampleDataList[i].HangTime}s"; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + hangTimeRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(hangTimeRow); + + // 6. 运行速度行 + DataRow runSpeedRow = dataTable.NewRow(); + runSpeedRow["序号"] = "运行速度"; + for (int i = 0; i < totalSamples; i++) + { + if (dataTable.Columns.Contains($"试样{i + 1}")) + { + runSpeedRow[$"试样{i + 1}"] = $"{form2SampleDataList[i].RunSpeed}mm/min"; + } + } + for (int i = totalSamples + 1; i <= currentSampleCount; i++) + { + if (dataTable.Columns.Contains($"试样{i}")) + { + runSpeedRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(runSpeedRow); + + // 计算并添加统计行:每5个试样一组 + int groupCount = (int)Math.Ceiling((double)totalSamples / 5.0); + + for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) + { + int startSample = groupIndex * 5 + 1; + int endSample = Math.Min(startSample + 4, totalSamples); + + // 获取该组的吸收量数据 + List groupAbsorptions = new List(); + for (int i = startSample - 1; i < endSample; i++) + { + groupAbsorptions.Add(absorptions[i]); + } + + if (groupAbsorptions.Count > 0) + { + // 7. 液体吸收量平均值行 + DataRow avgRow = dataTable.NewRow(); + avgRow["序号"] = "液体吸收量平均值(%)"; + double avgAbsorption = groupAbsorptions.Average(); + + // 检查NaN + if (double.IsNaN(avgAbsorption) || double.IsInfinity(avgAbsorption)) + { + avgAbsorption = 0; + } + + avgRow[$"试样{startSample}"] = avgAbsorption; + for (int i = 1; i <= currentSampleCount; i++) + { + if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + { + avgRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(avgRow); + + // 8. 液体吸收量最大值行 + DataRow maxRow = dataTable.NewRow(); + maxRow["序号"] = "液体吸收量最大值(%)"; + double maxAbsorption = groupAbsorptions.Max(); + + // 检查NaN + if (double.IsNaN(maxAbsorption) || double.IsInfinity(maxAbsorption)) + { + maxAbsorption = 0; + } + + maxRow[$"试样{startSample}"] = maxAbsorption; + for (int i = 1; i <= currentSampleCount; i++) + { + if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + { + maxRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(maxRow); + + // 9. 标准偏差行 + DataRow stdDevRow = dataTable.NewRow(); + stdDevRow["序号"] = "标准偏差"; + double stdDev = groupAbsorptions.Count > 1 ? CalculateStandardDeviation(groupAbsorptions.ToArray()) : 0; + + // 检查NaN + if (double.IsNaN(stdDev) || double.IsInfinity(stdDev)) + { + stdDev = 0; + } + + stdDevRow[$"试样{startSample}"] = stdDev; + for (int i = 1; i <= currentSampleCount; i++) + { + if (i != startSample && dataTable.Columns.Contains($"试样{i}")) + { + stdDevRow[$"试样{i}"] = DBNull.Value; + } + } + dataTable.Rows.Add(stdDevRow); + } + } + + // 刷新显示 + dataTable.AcceptChanges(); this.Invoke(new Action(() => { var refreshMethod = form2Instance.GetType() @@ -567,7 +798,7 @@ namespace WindowsFormsApp6 refreshMethod?.Invoke(form2Instance, null); })); - System.Diagnostics.Debug.WriteLine($"Form2数据读取成功 - 试样{sampleIndex + 1}"); + System.Diagnostics.Debug.WriteLine($"Form2数据读取成功:试样{newSampleIndex},初始重量={initialWeight:F2}g,浸润后重量={afterWeight:F2}g,累计{totalSamples}个试样"); } catch (Exception ex) { @@ -584,7 +815,15 @@ namespace WindowsFormsApp6 // 组合两个寄存器为32位整数(高位在前) uint value = ((uint)registers[0] << 16) | registers[1]; - return value / 100.0; + double result = value / 100.0; + + // 检查NaN + if (double.IsNaN(result) || double.IsInfinity(result)) + { + return 0.0; + } + + return result; } /// @@ -713,6 +952,16 @@ namespace WindowsFormsApp6 if (initialWeights[i] > 0) { absorptions[i] = ((afterWeights[i] - initialWeights[i]) / initialWeights[i]) * 100; + + // 检查NaN + if (double.IsNaN(absorptions[i]) || double.IsInfinity(absorptions[i])) + { + absorptions[i] = 0; + } + } + else + { + absorptions[i] = 0; } absorptionRow[$"试样{i + 1}"] = absorptions[i]; } @@ -745,14 +994,23 @@ namespace WindowsFormsApp6 } dataTable.Rows.Add(runSpeedRow); - // 计算有效试样数量(初始重量>0的试样) - var validAbsorptions = absorptions.Where((a, idx) => initialWeights[idx] > 0).ToArray(); + // 计算有效试样数量(初始重量>0的试样,且吸收量不是NaN) + var validAbsorptions = absorptions + .Where((a, idx) => initialWeights[idx] > 0 && !double.IsNaN(a) && !double.IsInfinity(a)) + .ToArray(); int validCount = validAbsorptions.Length; // 7. 液体吸收量平均值行 DataRow avgRow = dataTable.NewRow(); avgRow["序号"] = "液体吸收量平均值(%)"; double avgAbsorption = validCount > 0 ? validAbsorptions.Average() : 0; + + // 检查NaN + if (double.IsNaN(avgAbsorption) || double.IsInfinity(avgAbsorption)) + { + avgAbsorption = 0; + } + avgRow["试样1"] = avgAbsorption; for (int i = 2; i <= count; i++) { @@ -764,6 +1022,13 @@ namespace WindowsFormsApp6 DataRow maxRow = dataTable.NewRow(); maxRow["序号"] = "液体吸收量最大值(%)"; double maxAbsorption = validCount > 0 ? validAbsorptions.Max() : 0; + + // 检查NaN + if (double.IsNaN(maxAbsorption) || double.IsInfinity(maxAbsorption)) + { + maxAbsorption = 0; + } + maxRow["试样1"] = maxAbsorption; for (int i = 2; i <= count; i++) { @@ -1001,9 +1266,22 @@ namespace WindowsFormsApp6 { if (values == null || values.Length <= 1) return 0; - double avg = values.Average(); - double sumOfSquares = values.Sum(val => Math.Pow(val - avg, 2)); - return Math.Sqrt(sumOfSquares / (values.Length - 1)); + // 过滤掉NaN和Infinity值 + var validValues = values.Where(v => !double.IsNaN(v) && !double.IsInfinity(v)).ToArray(); + + if (validValues.Length <= 1) return 0; + + double avg = validValues.Average(); + double sumOfSquares = validValues.Sum(val => Math.Pow(val - avg, 2)); + double result = Math.Sqrt(sumOfSquares / (validValues.Length - 1)); + + // 检查结果是否为NaN + if (double.IsNaN(result) || double.IsInfinity(result)) + { + return 0; + } + + return result; } ///