From 218c0aa66673068bd4df1c73d349d86a8e58f81c Mon Sep 17 00:00:00 2001 From: xyy <544939200@qq.com> Date: Wed, 3 Jun 2026 14:04:49 +0800 Subject: [PATCH] --- Models/AppConfig.cs | 4 +- ViewModels/D7896ViewModel.cs | 137 ++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 53 deletions(-) diff --git a/Models/AppConfig.cs b/Models/AppConfig.cs index fb42406..b8b09cc 100644 --- a/Models/AppConfig.cs +++ b/Models/AppConfig.cs @@ -71,7 +71,7 @@ public class TestParameters //public double FitStartTime { get; set; } = 0.01; // 默认0.35秒,避开早期扰动 //public double FitEndTime { get; set; } = 0.1; - public double FitStartTime { get; set; } = 0.20; // 默认0.35秒,避开早期扰动 + public double FitStartTime { get; set; } = 0.25; // 默认0.35秒,避开早期扰动 public double FitEndTime { get; set; } = 0.60; @@ -92,6 +92,6 @@ public class CalibrationCoefficients public ushort TemperatureCoefficient { get; set; } public ushort ResistanceCoefficient { get; set; } - public double ThermalConductivityCorrection { get; set; } = 33.8; + public double ThermalConductivityCorrection { get; set; } = 36.8; public double ThermalDiffusivityCorrection { get; set; } = 19.9; } \ No newline at end of file diff --git a/ViewModels/D7896ViewModel.cs b/ViewModels/D7896ViewModel.cs index 1b17661..ac131ae 100644 --- a/ViewModels/D7896ViewModel.cs +++ b/ViewModels/D7896ViewModel.cs @@ -91,7 +91,7 @@ public partial class D7896ViewModel : ObservableObject private const double EulerGamma = 0.5772156649; // 欧拉常数 //private const double WireRadius = 0.00003; // 铂丝半径 (0.03 mm) [ObservableProperty] private double _sampleDensity = 1000.0; // 新增,密度默认值1000 kg/m³(水) - int samples = 800; // 1秒 * 1000点/秒 + int samples = 1000; // 1秒 * 1000点/秒 double heatingDuration = 1; // 加热时间 0.8 秒(需与您的加热脉冲宽度一致) double totalDuration = 2; // 总采样时间(加热 + 冷却) public D7896ViewModel() @@ -195,6 +195,10 @@ public partial class D7896ViewModel : ObservableObject try { + + + + await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP await _th1963Ustd.ConfigureForHighSpeedDcvAsync(); @@ -268,14 +272,25 @@ public partial class D7896ViewModel : ObservableObject await Task.Delay(100); await _th1953Ustd.FetchBatchAsync(); // 丢弃结果 - for (int i = 1; i <= _config.TestParameters.MeasurementCount; i++) + + + + + int requiredCount = _config.TestParameters.MeasurementCount; // 需要多少有效数据 + int validCount = 0; + int attemptCount = 0; + int maxAttempts = requiredCount * 2; // 最多尝试次数,防止死循环 + + // 存储每次成功测量的结果(用于后续异常判断) + List validLambdaList = new List(); + List validAlphaList = new List(); + List validCpList = new List(); + + while (validCount < requiredCount && attemptCount < maxAttempts && !_stopRequested) { - if (_stopRequested) break; - - CurrentMeasurementIndex = i; - StatusMessage = $"正在执行第 {i} 次测量..."; - - + attemptCount++; + CurrentMeasurementIndex = attemptCount; // 显示当前尝试次数(不是有效次数) + StatusMessage = $"正在执行第 {attemptCount} 次测量(有效:{validCount}/{requiredCount})..."; // --- 步骤1:基线采集(加热前)--- await _th1963Ustd.PrepareBatchAsync(50); @@ -312,15 +327,6 @@ public partial class D7896ViewModel : ObservableObject Logger.Log("基线采集未返回数据,将使用加热段早期点"); } - - - - - - - - - // --- 步骤2:正式加热采集 --- await _th1963Ustd.PrepareBatchAsync(samples); await _th1953Ustd.PrepareBatchAsync(samples); @@ -339,10 +345,9 @@ public partial class D7896ViewModel : ObservableObject double[] ustd = await _th1963Ustd.FetchBatchAsync(); double[] upt = await _th1953Ustd.FetchBatchAsync(); - if (dynamicR0 == 2.45) // 仍为默认值,说明基线无效 + if (dynamicR0 == 2.45) // 基线无效 { double sumR0 = 0; int cnt = 0; - // 改用第 2~5 点(索引 2,3,4,5) for (int j = 2; j < Math.Min(6, ustd.Length); j++) { if (ustd[j] > 0.01 && upt[j] > 0.01) @@ -358,9 +363,7 @@ public partial class D7896ViewModel : ObservableObject } } - - - + // 记录原始电压(调试用) for (int j = 0; j < 20 && j < ustd.Length; j++) { Logger.Log($"第{j}点: U_std={ustd[j]:F6} V, U_pt={upt[j]:F6} V"); @@ -368,53 +371,85 @@ public partial class D7896ViewModel : ObservableObject StandardResistorVoltage = ustd.Average(); PlatinumVoltage = upt.Average(); - Logger.Log($"测量 {i}: U_std 平均值={ustd.Average():F6} V, U_pt 平均值={upt.Average():F6} V"); + Logger.Log($"测量 {attemptCount}: U_std 平均值={ustd.Average():F6} V, U_pt 平均值={upt.Average():F6} V"); double[] timeArray = new double[ustd.Length]; for (int idx = 0; idx < timeArray.Length; idx++) timeArray[idx] = idx * totalDuration / samples; - // 计算本次测量的 λ 和 α (传入刚才测得的冷态 dynamicR0) var (lambda, alpha, deltaT, coolingPoints) = ComputeThermalProperties(upt, ustd, timeArray, dynamicR0, CurrentTestTemperature); + // 计算比热容 Cp + double vhc = lambda / alpha; // kJ/(m³·K) + double cp = vhc / SampleDensity; // J/(kg·K) - //var lambdaCorr = _config.TestParameters.CalibrationCoefficients.ThermalConductivityCorrection; - //var alphaCorr = _config.TestParameters.CalibrationCoefficients.ThermalDiffusivityCorrection; + Logger.Log($"测量 {attemptCount} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s, Cp={cp:F2} J/(kg·K)"); - //lambda *= lambdaCorr; - //alpha *= alphaCorr; + // ---- 异常值检测 ---- + bool isOutlier = false; + double deviationThreshold = 0.20; // 20% 偏差阈值 - Logger.Log($"测量 {i} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s"); - - GenerateTemperatureCurveFromData(timeArray, deltaT, coolingPoints); - - var result = new MeasurementResult + if (validCount >= 2) // 至少有两个有效数据后才开始剔除 { - Index = i, - ThermalConductivity = lambda, - ThermalDiffusivity = alpha - }; - result.CalculateVhcAndCp(SampleDensity); - Application.Current.Dispatcher.Invoke(() => Measurements.Add(result)); - StatusMessage = $"第 {i} 次测量完成,λ={lambda:F4} W/m·K"; + double avgLambda = validLambdaList.Average(); + double avgAlpha = validAlphaList.Average(); + double avgCp = validCpList.Average(); - Logger.Log($"========== 第 {i} 次测量详细数据 =========="); - Logger.Log($"热导率 λ: {lambda:F6} W/(m·K)"); - Logger.Log($"热扩散率 α: {alpha:E6} m²/s"); - Logger.Log($"体积热容 VHC: {result.VolumetricHeatCapacity:F2} kJ/(m³·K)"); - Logger.Log($"比热容 Cp: {result.SpecificHeatCapacity:F2} J/(kg·K)"); - Logger.Log($"初始电阻 R0: {dynamicR0:F6} Ω"); - Logger.Log("==========================================="); + if (Math.Abs(lambda - avgLambda) / avgLambda > deviationThreshold || + Math.Abs(alpha - avgAlpha) / avgAlpha > deviationThreshold || + Math.Abs(cp - avgCp) / avgCp > deviationThreshold) + { + isOutlier = true; + Logger.Log($"第 {attemptCount} 次测量结果异常(偏差过大),予以舍弃。λ={lambda:F4}, α={alpha:E4}, Cp={cp:F2}"); + } + } - if (i < _config.TestParameters.MeasurementCount && !_stopRequested) + if (!isOutlier) + { + // 正常结果,添加到列表 + validLambdaList.Add(lambda); + validAlphaList.Add(alpha); + validCpList.Add(cp); + validCount++; + + GenerateTemperatureCurveFromData(timeArray, deltaT, coolingPoints); + + var result = new MeasurementResult + { + Index = validCount, // 使用有效次数编号 + ThermalConductivity = lambda, + ThermalDiffusivity = alpha + }; + result.CalculateVhcAndCp(SampleDensity); + Application.Current.Dispatcher.Invoke(() => Measurements.Add(result)); + StatusMessage = $"第 {validCount} 次测量完成,λ={lambda:F4} W/m·K"; + + Logger.Log($"========== 第 {validCount} 次测量详细数据 =========="); + Logger.Log($"热导率 λ: {lambda:F6} W/(m·K)"); + Logger.Log($"热扩散率 α: {alpha:E6} m²/s"); + Logger.Log($"体积热容 VHC: {result.VolumetricHeatCapacity:F2} kJ/(m³·K)"); + Logger.Log($"比热容 Cp: {cp:F2} J/(kg·K)"); + Logger.Log($"初始电阻 R0: {dynamicR0:F6} Ω"); + Logger.Log("==========================================="); + } + + // 测量间隔(即使舍弃也等待,让样品恢复) + if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts) { try { await Task.Delay(_config.TestParameters.IntervalSeconds * 500, _testCts.Token); } catch (OperationCanceledException) { break; } } } - - CalculateAverages(); - StatusMessage = _stopRequested ? "测试已停止。" : "测试完成。"; + if (validCount >= requiredCount) + { + CalculateAverages(); + StatusMessage = "测试完成"; + } + else + { + StatusMessage = $"测试中止。"; + MessageBox.Show($"测试中止,未收集到足够有效数据({validCount}/{requiredCount})。请检查样品或仪器状态。", "提示"); + } } catch (Exception ex) {