This commit is contained in:
Binary file not shown.
34
Helpers/Logger.cs
Normal file
34
Helpers/Logger.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ASTM_D7896_Tester.Services
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static readonly object _lock = new object();
|
||||
private static string _logFilePath = "D7896_Test_Log.txt";
|
||||
|
||||
public static void Log(string message, bool toConsole = true, bool toFile = true)
|
||||
{
|
||||
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
string logLine = $"{timestamp} - {message}";
|
||||
|
||||
if (toConsole)
|
||||
Debug.WriteLine(logLine);
|
||||
|
||||
if (toFile)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
File.AppendAllText(_logFilePath, logLine + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void LogData(string label, double value, string unit = "")
|
||||
{
|
||||
Log($"{label}: {value:F6} {unit}".Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,8 @@ public partial class D7896ViewModel : ObservableObject
|
||||
|
||||
// 电压表服务
|
||||
private Th1963LanService _th1963Ustd; // 6位半测量标准电阻电压 U_std
|
||||
private FiveHalfDmmService _fiveHalfUpt; // 5位半测量铂丝电压 U_pt
|
||||
private Th1963LanService _th1953Ustd; // 6位半测量标准电阻电压 U_std
|
||||
//private FiveHalfDmmService _fiveHalfUpt; // 5位半测量铂丝电压 U_pt
|
||||
|
||||
private CancellationTokenSource _testCts; // 用于停止测试
|
||||
private bool _stopRequested;
|
||||
@@ -87,7 +88,8 @@ public partial class D7896ViewModel : ObservableObject
|
||||
|
||||
|
||||
[ObservableProperty] private double _sampleDensity = 1000.0; // 新增,密度默认值1000 kg/m³(水)
|
||||
|
||||
double heatingDuration = 0.8; // 加热时间 0.8 秒(需与您的加热脉冲宽度一致)
|
||||
double totalDuration = 1.6; // 总采样时间(加热 + 冷却)
|
||||
public D7896ViewModel()
|
||||
{
|
||||
_config = App.PlcConfig ?? new AppConfig();
|
||||
@@ -108,8 +110,8 @@ public partial class D7896ViewModel : ObservableObject
|
||||
// 初始化电压表服务
|
||||
// TH1963 IP 地址需要根据实际配置修改,建议从配置文件读取
|
||||
_th1963Ustd = new Th1963LanService();
|
||||
// 5位半万用表串口名,例如 "COM3"
|
||||
_fiveHalfUpt = new FiveHalfDmmService("COM6", 115200);
|
||||
|
||||
_th1953Ustd = new Th1963LanService();
|
||||
|
||||
StartBackgroundMonitoring();
|
||||
}
|
||||
@@ -123,17 +125,18 @@ public partial class D7896ViewModel : ObservableObject
|
||||
private async Task MonitorPlcValues()
|
||||
{
|
||||
if (!await _plcService.IsConnectedAsync()) return;
|
||||
if (Application.Current == null || Application.Current.Dispatcher == null) return;
|
||||
try
|
||||
{
|
||||
float rawResistance = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Resistance);
|
||||
double newResistance = rawResistance;
|
||||
Application.Current.Dispatcher.Invoke(() => PlatinumResistance = newResistance);
|
||||
Application.Current?.Dispatcher.Invoke(() => PlatinumResistance = newResistance);
|
||||
|
||||
float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
|
||||
Application.Current.Dispatcher.Invoke(() => ChamberPressure = rawPressure);
|
||||
Application.Current?.Dispatcher.Invoke(() => ChamberPressure = rawPressure);
|
||||
|
||||
float rawTemp = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Temperature);
|
||||
Application.Current.Dispatcher.Invoke(() => CurrentTestTemperature = rawTemp);
|
||||
Application.Current?.Dispatcher.Invoke(() => CurrentTestTemperature = rawTemp);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@@ -144,7 +147,7 @@ public partial class D7896ViewModel : ObservableObject
|
||||
try
|
||||
{
|
||||
float rawResistance = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Resistance);
|
||||
return rawResistance / 1000.0;
|
||||
return rawResistance;
|
||||
}
|
||||
catch { return 0; }
|
||||
}
|
||||
@@ -187,10 +190,12 @@ public partial class D7896ViewModel : ObservableObject
|
||||
|
||||
try
|
||||
{
|
||||
if (!_fiveHalfUpt.IsOpen) _fiveHalfUpt.Open();
|
||||
|
||||
await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
|
||||
await _th1963Ustd.ConfigureForHighSpeedDcvAsync();
|
||||
await _fiveHalfUpt.ConfigureHighSpeedDcvAsync();
|
||||
|
||||
await _th1953Ustd.ConnectAsync("192.168.1.13", 45454); // 改为实际IP
|
||||
await _th1953Ustd.ConfigureForHighSpeedDcvAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -219,6 +224,22 @@ public partial class D7896ViewModel : ObservableObject
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// 预热:进行一次虚拟测量
|
||||
await _th1963Ustd.ConfigureForHighSpeedDcvAsync();
|
||||
await _th1963Ustd.PrepareBatchAsync(10);
|
||||
await _th1963Ustd.TriggerAsync();
|
||||
await Task.Delay(100);
|
||||
await _th1963Ustd.FetchBatchAsync(); // 丢弃结果
|
||||
|
||||
|
||||
// 预热:进行一次虚拟测量
|
||||
await _th1953Ustd.ConfigureForHighSpeedDcvAsync();
|
||||
await _th1953Ustd.PrepareBatchAsync(10);
|
||||
await _th1953Ustd.TriggerAsync();
|
||||
await Task.Delay(100);
|
||||
await _th1953Ustd.FetchBatchAsync(); // 丢弃结果
|
||||
|
||||
for (int i = 1; i <= _config.TestParameters.MeasurementCount; i++)
|
||||
{
|
||||
if (_stopRequested) break;
|
||||
@@ -227,41 +248,56 @@ public partial class D7896ViewModel : ObservableObject
|
||||
StatusMessage = $"正在执行第 {i} 次测量...";
|
||||
|
||||
// 准备批量采集参数(每通道采样点数,采样率1000点/秒,加热时间1秒 -> 1000点)
|
||||
int samples = 1000; // 1秒 * 1000点/秒
|
||||
int samples = 800; // 1秒 * 1000点/秒
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 预配置两台表:进入等待触发状态
|
||||
await _th1963Ustd.PrepareBatchAsync(samples);
|
||||
await _fiveHalfUpt.PrepareBatchAsync(samples); // 需要在FiveHalfDmmService中实现PrepareBatchAsync,见补充
|
||||
await _th1953Ustd.PrepareBatchAsync(samples);
|
||||
|
||||
// 启动加热脉冲 (PLC)
|
||||
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, true);
|
||||
// 同时发送触发信号给两台电压表
|
||||
await Task.WhenAll(_th1963Ustd.TriggerAsync(), _fiveHalfUpt.TriggerAsync());
|
||||
|
||||
// 等待加热脉冲持续1秒
|
||||
await Task.Delay(1);
|
||||
// 等待极短时间确保电流稳定(如 5ms)
|
||||
await Task.Delay(5);
|
||||
// 同时发送触发信号给两台电压表
|
||||
await Task.WhenAll(_th1963Ustd.TriggerAsync(), _th1953Ustd.TriggerAsync());
|
||||
|
||||
// 等待加热结束
|
||||
await Task.Delay((int)(heatingDuration * 1000));
|
||||
|
||||
// 停止加热
|
||||
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);
|
||||
|
||||
// 等待采集完成(留出额外时间)
|
||||
await Task.Delay(500);
|
||||
// 等待采集完成(剩余时间)
|
||||
int remainingMs = (int)((totalDuration - heatingDuration) * 1000) + 100;
|
||||
await Task.Delay(remainingMs);
|
||||
|
||||
// 获取采集数据
|
||||
double[] ustd = await _th1963Ustd.FetchBatchAsync();
|
||||
double[] upt = await _fiveHalfUpt.FetchBatchAsync();
|
||||
double[] upt = await _th1953Ustd.FetchBatchAsync();
|
||||
|
||||
StandardResistorVoltage = ustd.Average();
|
||||
PlatinumVoltage = upt.Average();
|
||||
// 添加日志:原始电压统计
|
||||
Logger.Log($"测量 {i}: U_std 点数={ustd.Length}, 平均值={ustd.Average():F6} V, 最大值={ustd.Max():F6} V");
|
||||
Logger.Log($"测量 {i}: U_pt 点数={upt.Length}, 平均值={upt.Average():F6} V, 最大值={upt.Max():F6} V");
|
||||
|
||||
|
||||
// 构建时间数组(假设采样时间正好1秒,采样点数 = ustd.Length)
|
||||
double[] timeArray = new double[ustd.Length];
|
||||
for (int idx = 0; idx < timeArray.Length; idx++)
|
||||
{
|
||||
timeArray[idx] = idx / (double)samples; // 0 ~ 1 秒
|
||||
timeArray[idx] = idx * totalDuration / samples;
|
||||
}
|
||||
// 计算本次测量的 λ 和 α
|
||||
var (lambda, alpha, deltaT, coolingPoints) = ComputeThermalProperties(upt, ustd, timeArray, initialResistance, CurrentTestTemperature);
|
||||
|
||||
// 添加结果日志
|
||||
Logger.Log($"测量 {i} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s");
|
||||
|
||||
// 生成温升曲线图
|
||||
GenerateTemperatureCurveFromData(timeArray, deltaT, coolingPoints);
|
||||
|
||||
@@ -276,6 +312,18 @@ public partial class D7896ViewModel : ObservableObject
|
||||
Application.Current.Dispatcher.Invoke(() => Measurements.Add(result));
|
||||
StatusMessage = $"第 {i} 次测量完成,λ={lambda:F4} W/m·K";
|
||||
|
||||
// 在 result.CalculateVhcAndCp(SampleDensity); 之后添加
|
||||
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) (密度 = {SampleDensity:F1} kg/m³)");
|
||||
Logger.Log($"初始电阻 R0: {initialResistance:F6} Ω");
|
||||
Logger.Log($"测试温度: {CurrentTestTemperature:F2} °C");
|
||||
Logger.Log($"铂丝平均电阻: {PlatinumResistance:F6} Ω");
|
||||
Logger.Log($"样品池压力: {ChamberPressure:F2} kPa");
|
||||
Logger.Log("===========================================");
|
||||
|
||||
if (i < _config.TestParameters.MeasurementCount && !_stopRequested)
|
||||
await Task.Delay(_config.TestParameters.IntervalSeconds * 1000);
|
||||
}
|
||||
@@ -300,8 +348,9 @@ public partial class D7896ViewModel : ObservableObject
|
||||
await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, false);
|
||||
}
|
||||
IsTesting = false;
|
||||
_fiveHalfUpt.Close();
|
||||
//_fiveHalfUpt.Close();
|
||||
_th1963Ustd.Dispose();
|
||||
_th1953Ustd.Dispose();
|
||||
_testCts?.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -324,6 +373,10 @@ public partial class D7896ViewModel : ObservableObject
|
||||
ptResistance[i] = upt[i] / current[i];
|
||||
deltaT[i] = (ptResistance[i] - initialResistance) / (AlphaPt * initialResistance);
|
||||
}
|
||||
// 添加日志:中间数据统计
|
||||
Logger.Log($"电流平均值: {current.Average():F6} A, 最大值: {current.Max():F6} A");
|
||||
Logger.Log($"铂丝电阻平均值: {ptResistance.Average():F6} Ω, 初始电阻: {initialResistance:F6} Ω");
|
||||
Logger.Log($"温升最大值: {deltaT.Max():F4} ℃, 平均值: {deltaT.Average():F4} ℃");
|
||||
|
||||
// 2. ========== 加热段拟合 → 热导率 λ ==========
|
||||
double tStart = 0.1;
|
||||
@@ -342,14 +395,17 @@ public partial class D7896ViewModel : ObservableObject
|
||||
double slope = LeastSquaresSlope(heatingPoints);
|
||||
if (slope <= 0) slope = 0.0001;
|
||||
|
||||
Logger.Log($"加热段拟合斜率 B = {slope:F6} (ΔT vs ln(t))");
|
||||
|
||||
double avgCurrentSq = current.Average(c => c * c);
|
||||
double avgResistance = ptResistance.Average();
|
||||
double powerPerLength = (avgCurrentSq * avgResistance) / _config.TestParameters.PlatinumWireLength;
|
||||
double lambda = powerPerLength / (4 * Math.PI * slope);
|
||||
|
||||
Logger.Log($"单位长度加热功率 Q = {powerPerLength:F6} W/m");
|
||||
Logger.Log($"热导率 λ = {lambda:F6} W/(m·K)");
|
||||
// 3. ========== 冷却段拟合 → 热扩散率 α ==========
|
||||
double coolingStart = 1.0;
|
||||
double coolingEnd = 2.0;
|
||||
double coolingStart = heatingDuration; // 0.8 秒
|
||||
double coolingEnd = totalDuration; // 1.6 秒
|
||||
int coolingStartIdx = FindIndex(time, coolingStart);
|
||||
int coolingEndIdx = FindIndex(time, coolingEnd);
|
||||
if (coolingStartIdx < 0) coolingStartIdx = n / 2;
|
||||
@@ -369,6 +425,10 @@ public partial class D7896ViewModel : ObservableObject
|
||||
if (alpha <= 0 || double.IsNaN(alpha) || double.IsInfinity(alpha))
|
||||
alpha = 0.12e-6; // 默认值
|
||||
|
||||
Logger.Log($"冷却段拟合斜率 D = {coolingSlope:F6} (lnΔT vs t)");
|
||||
Logger.Log($"时间常数 τ = {tau:F6} s");
|
||||
Logger.Log($"热扩散率 α = {alpha:E6} m²/s");
|
||||
|
||||
// 准备冷却曲线数据点(用于绘图)
|
||||
var coolingPoints = new List<DataPoint>();
|
||||
for (int i = coolingStartIdx; i <= coolingEndIdx; i++)
|
||||
@@ -478,14 +538,6 @@ public partial class D7896ViewModel : ObservableObject
|
||||
CurveTitle = $"已完成 {CurrentMeasurementIndex} 次测量";
|
||||
}
|
||||
|
||||
private void GenerateTemperatureCurve(float lambda, float alpha) { /* 旧方法,不再使用 */ }
|
||||
|
||||
private OxyColor GetColorForIndex(int index)
|
||||
{
|
||||
var colors = new[] { OxyColors.Red, OxyColors.Blue, OxyColors.Green, OxyColors.Orange,
|
||||
OxyColors.Purple, OxyColors.Brown, OxyColors.Pink, OxyColors.Cyan, OxyColors.Magenta, OxyColors.Olive };
|
||||
return colors[(index - 1) % colors.Length];
|
||||
}
|
||||
|
||||
private void CalculateAverages()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Diagnostics; // 添加命名空间
|
||||
|
||||
namespace ASTM_D7896_Tester.ViewModels;
|
||||
|
||||
@@ -19,10 +20,20 @@ public partial class MeasurementResult : ObservableObject
|
||||
public void CalculateVhcAndCp(double density)
|
||||
{
|
||||
CalculateVhc(); // 先计算 VHC
|
||||
|
||||
// 日志:记录计算前的参数
|
||||
Debug.WriteLine($"[MeasurementResult] 计算比热容 - 密度: {density} kg/m³, 体积热容: {VolumetricHeatCapacity} kJ/(m³·K)");
|
||||
|
||||
if (density > 0)
|
||||
SpecificHeatCapacity = VolumetricHeatCapacity * 1000 / density; // 注意单位转换
|
||||
{
|
||||
SpecificHeatCapacity = VolumetricHeatCapacity * 1000 / density;
|
||||
Debug.WriteLine($"[MeasurementResult] 计算得到比热容: {SpecificHeatCapacity} J/(kg·K)");
|
||||
}
|
||||
else
|
||||
{
|
||||
SpecificHeatCapacity = 0;
|
||||
Debug.WriteLine($"[MeasurementResult] 警告: 密度无效 (density={density}),比热容设为0");
|
||||
}
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -30,10 +41,17 @@ public partial class MeasurementResult : ObservableObject
|
||||
|
||||
public void CalculateVhc()
|
||||
{
|
||||
if (ThermalDiffusivity > 0)
|
||||
VolumetricHeatCapacity = ThermalConductivity / (ThermalDiffusivity * 1e-6) / 1000.0;
|
||||
else
|
||||
VolumetricHeatCapacity = 0;
|
||||
}
|
||||
Debug.WriteLine($"[MeasurementResult] 计算体积热容 - 热导率: {ThermalConductivity} W/(m·K), 热扩散率: {ThermalDiffusivity} ×10⁻⁶ m²/s");
|
||||
|
||||
if (ThermalDiffusivity > 0)
|
||||
{
|
||||
VolumetricHeatCapacity = ThermalConductivity / (ThermalDiffusivity * 1e-6) / 1000.0;
|
||||
Debug.WriteLine($"[MeasurementResult] 计算得到体积热容: {VolumetricHeatCapacity} kJ/(m³·K)");
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumetricHeatCapacity = 0;
|
||||
Debug.WriteLine($"[MeasurementResult] 警告: 热扩散率为0,体积热容设为0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="768" d:DesignWidth="1024">
|
||||
d:DesignHeight="768" d:DesignWidth="1024" Loaded="UserControl_Loaded">
|
||||
|
||||
<UserControl.Resources>
|
||||
<!-- 全局字体 -->
|
||||
@@ -221,7 +221,7 @@
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="60"/>
|
||||
<DataGridTextColumn Header="热导率 (W/m·K)" Binding="{Binding ThermalConductivity, StringFormat=F5}" Width="*"/>
|
||||
<DataGridTextColumn Header="热扩散率 (×10⁻⁶ m²/s)" Binding="{Binding ThermalDiffusivity, StringFormat=F5}" Width="*"/>
|
||||
<DataGridTextColumn Header="热扩散率 (m²/s)" Binding="{Binding ThermalDiffusivity, StringFormat=F10}" Width="*"/>
|
||||
<DataGridTextColumn Header="体积热容 (kJ/m³·K)" Binding="{Binding VolumetricHeatCapacity, StringFormat=F2}" Width="*"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
@@ -29,5 +29,10 @@ namespace ASTM_D7896_Tester.Views
|
||||
InitializeComponent();
|
||||
DataContext = new D7896ViewModel();
|
||||
}
|
||||
|
||||
private void UserControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"TestParameters": {
|
||||
"MeasurementCount": 10,
|
||||
"IntervalSeconds": 30,
|
||||
"PlatinumWireLength": 0.07,
|
||||
"PlatinumWireLength": 0.07, //铂丝长度(单位:米)
|
||||
"PlatinumWireDiameter": 0.00006,
|
||||
"ReportOutputPath": "Reports\\",
|
||||
"DefaultSampleVolume": 40.0,
|
||||
|
||||
Reference in New Issue
Block a user