Compare commits
14 Commits
76c911084e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| afd044ce09 | |||
| 9c7698e9cc | |||
| 75d9405770 | |||
| db8d255fdd | |||
| 87ca4b0a64 | |||
| bc893c4d53 | |||
| 00d17dc0eb | |||
| 785583a6c8 | |||
| 2ea0f95fec | |||
| a2d86b667e | |||
| fbab7e3c17 | |||
| 78f1cf038d | |||
| 8681cc0163 | |||
| ae5803431b |
2
App.xaml
2
App.xaml
@@ -1,7 +1,7 @@
|
|||||||
<Application x:Class="ASTM_D7896_Tester.App"
|
<Application x:Class="ASTM_D7896_Tester.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:converters="clr-namespace:ASTM_D7896_Tester.Converters"
|
xmlns:converters="clr-namespace:ASTM_D7896_Tester.Converters" StartupUri="Window1.xaml"
|
||||||
>
|
>
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||||
|
|||||||
BIN
L028需要采购给客户寄过去,不需要增加清单.xlsx
Normal file
BIN
L028需要采购给客户寄过去,不需要增加清单.xlsx
Normal file
Binary file not shown.
@@ -74,8 +74,6 @@ public class TestParameters
|
|||||||
public double FitStartTime { get; set; } = 0.25; // 默认0.35秒,避开早期扰动
|
public double FitStartTime { get; set; } = 0.25; // 默认0.35秒,避开早期扰动
|
||||||
public double FitEndTime { get; set; } = 0.60;
|
public double FitEndTime { get; set; } = 0.60;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AppSettings
|
public class AppSettings
|
||||||
@@ -91,6 +89,6 @@ public class CalibrationCoefficients
|
|||||||
public ushort PressureProtection { get; set; }
|
public ushort PressureProtection { get; set; }
|
||||||
public ushort TemperatureCoefficient { get; set; }
|
public ushort TemperatureCoefficient { get; set; }
|
||||||
public ushort ResistanceCoefficient { get; set; }
|
public ushort ResistanceCoefficient { get; set; }
|
||||||
public double ThermalConductivityCorrection { get; set; } = 47.305349f;//蒸馏水 比热率修正
|
public double ThermalConductivityCorrection { get; set; } = 17.305349f;//蒸馏水 比热率修正
|
||||||
public double ThermalDiffusivityCorrection { get; set; } = 0.312912;//导热率修正
|
public double ThermalDiffusivityCorrection { get; set; } = 0.158682538;//导热率修正
|
||||||
}
|
}
|
||||||
@@ -12,14 +12,11 @@ using PdfSharpCore.Pdf;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Ports;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Threading;
|
|
||||||
|
|
||||||
namespace ASTM_D7896_Tester.ViewModels;
|
namespace ASTM_D7896_Tester.ViewModels;
|
||||||
|
|
||||||
@@ -124,9 +121,6 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
_th1953Ustd = new Th1963LanService();
|
_th1953Ustd = new Th1963LanService();
|
||||||
|
|
||||||
StartBackgroundMonitoring();
|
StartBackgroundMonitoring();
|
||||||
|
|
||||||
Task.Run(() => initPort());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void StartBackgroundMonitoring()
|
private async void StartBackgroundMonitoring()
|
||||||
@@ -206,7 +200,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
BtnSet();
|
|
||||||
|
|
||||||
|
|
||||||
await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
|
await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
|
||||||
@@ -289,7 +283,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
int requiredCount = _config.TestParameters.MeasurementCount; // 需要多少有效数据
|
int requiredCount = _config.TestParameters.MeasurementCount; // 需要多少有效数据
|
||||||
int validCount = 0;
|
int validCount = 0;
|
||||||
int attemptCount = 0;
|
int attemptCount = 0;
|
||||||
int maxAttempts = requiredCount * 2; // 最多尝试次数,防止死循环
|
int maxAttempts = requiredCount * 4; // 最多尝试次数,防止死循环
|
||||||
|
|
||||||
// 存储每次成功测量的结果(用于后续异常判断)
|
// 存储每次成功测量的结果(用于后续异常判断)
|
||||||
List<double> validLambdaList = new List<double>();
|
List<double> validLambdaList = new List<double>();
|
||||||
@@ -300,7 +294,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
attemptCount++;
|
attemptCount++;
|
||||||
CurrentMeasurementIndex = attemptCount; // 显示当前尝试次数(不是有效次数)
|
CurrentMeasurementIndex = attemptCount; // 显示当前尝试次数(不是有效次数)
|
||||||
StatusMessage = $"正在执行第 {attemptCount} 次测量(有效:{validCount}/{requiredCount})...";
|
//StatusMessage = $"正在执行第{validCount}次测量)...";
|
||||||
|
|
||||||
// --- 步骤1:基线采集(加热前)---
|
// --- 步骤1:基线采集(加热前)---
|
||||||
await _th1963Ustd.PrepareBatchAsync(50);
|
await _th1963Ustd.PrepareBatchAsync(50);
|
||||||
@@ -397,7 +391,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
double vhc = lambda / alpha; // kJ/(m³·K)
|
double vhc = lambda / alpha; // kJ/(m³·K)
|
||||||
double cp = vhc / SampleDensity; // J/(kg·K)
|
double cp = vhc / SampleDensity; // J/(kg·K)
|
||||||
|
|
||||||
Logger.Log($"测量 {attemptCount} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s, Cp={cp:F2} J/(kg·K)");
|
Logger.Log($"测量 {validCount} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s, Cp={cp:F2} J/(kg·K)");
|
||||||
|
|
||||||
// ---- 异常值检测 ----
|
// ---- 异常值检测 ----
|
||||||
bool isOutlier = false;
|
bool isOutlier = false;
|
||||||
@@ -450,7 +444,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
// 测量间隔(即使舍弃也等待,让样品恢复)
|
// 测量间隔(即使舍弃也等待,让样品恢复)
|
||||||
if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts)
|
if (validCount < requiredCount && !_stopRequested && attemptCount < maxAttempts)
|
||||||
{
|
{
|
||||||
try { await Task.Delay(_config.TestParameters.IntervalSeconds * 1000, _testCts.Token); } catch (OperationCanceledException) { break; }
|
try { await Task.Delay(_config.TestParameters.IntervalSeconds * 150, _testCts.Token); } catch (OperationCanceledException) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +719,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
if (TemperatureCurveModel == null)
|
if (TemperatureCurveModel == null)
|
||||||
{
|
{
|
||||||
TemperatureCurveModel = new PlotModel { Title = "温升与冷却曲线", Background = OxyColors.White };
|
TemperatureCurveModel = new PlotModel { };
|
||||||
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (s)" });
|
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (s)" });
|
||||||
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "温升 (℃)" });
|
TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "温升 (℃)" });
|
||||||
}
|
}
|
||||||
@@ -770,7 +764,7 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
TemperatureCurveModel.InvalidatePlot(true);
|
TemperatureCurveModel.InvalidatePlot(true);
|
||||||
CurveTitle = $"已完成 {CurrentMeasurementIndex} 次测量";
|
//CurveTitle = $"已完成 {CurrentMeasurementIndex} 次测量";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -782,18 +776,6 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity);
|
AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[RelayCommand]
|
|
||||||
//private void Reset()
|
|
||||||
//{
|
|
||||||
// //Measurements.Clear();
|
|
||||||
// //AverageThermalConductivity = AverageThermalDiffusivity = AverageVolumetricHeatCapacity = 0;
|
|
||||||
// //CurrentMeasurementIndex = 0;
|
|
||||||
// //StatusMessage = "已重置";
|
|
||||||
// //TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
// //TemperatureCurveModel = null;
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void Reset()
|
private void Reset()
|
||||||
{
|
{
|
||||||
@@ -1067,150 +1049,8 @@ public partial class D7896ViewModel : ObservableObject
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
|
float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
|
||||||
ChamberPressure = rawPressure / 10.0;
|
ChamberPressure = rawPressure;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private SerialPort _serialPort;
|
|
||||||
private bool _isConnected = false;
|
|
||||||
|
|
||||||
private async Task initPort()
|
|
||||||
{
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string port = "COM10";
|
|
||||||
int baud = 19200;
|
|
||||||
_serialPort = new SerialPort(port, baud, Parity.None, 8, StopBits.One);
|
|
||||||
_serialPort.ReadTimeout = 1000; // 关键:避免永久阻塞
|
|
||||||
_serialPort.WriteTimeout = 1000;
|
|
||||||
_serialPort.Open();
|
|
||||||
|
|
||||||
_isConnected = true;
|
|
||||||
|
|
||||||
|
|
||||||
// 发送配置命令(不输出电流,只设置模式),同样异步等待但不死锁
|
|
||||||
await ConfigureOptimalMode();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show($"连接失败: {ex.Message}");
|
|
||||||
_isConnected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ConfigureOptimalMode()
|
|
||||||
{
|
|
||||||
// 构造命令:电流 0,但强制 PC 模式和跟踪模式
|
|
||||||
byte[] configCmd = new byte[12];
|
|
||||||
configCmd[0] = 0xFE;
|
|
||||||
configCmd[1] = 0xFE;
|
|
||||||
configCmd[2] = 0x55; // 识别码高
|
|
||||||
configCmd[3] = 0xAA; // 识别码低
|
|
||||||
configCmd[4] = 0x00; // 电流高字节 (0A)
|
|
||||||
configCmd[5] = 0x00; // 电流低字节
|
|
||||||
configCmd[6] = 0x01; // PC调节模式
|
|
||||||
configCmd[7] = 0x01;
|
|
||||||
configCmd[8] = 0x00; // 开启跟踪模式
|
|
||||||
configCmd[9] = 0x00;
|
|
||||||
configCmd[10] = 0xFF;
|
|
||||||
configCmd[11] = 0xFF;
|
|
||||||
|
|
||||||
await SendCommandSafe(configCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 安全的命令发送(异步读取,不卡UI)
|
|
||||||
private async Task<bool> SendCommandSafe(byte[] command)
|
|
||||||
{
|
|
||||||
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
|
|
||||||
{
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 清空缓冲区
|
|
||||||
_serialPort.DiscardInBuffer();
|
|
||||||
_serialPort.DiscardOutBuffer();
|
|
||||||
|
|
||||||
// 发送命令
|
|
||||||
await _serialPort.BaseStream.WriteAsync(command, 0, command.Length);
|
|
||||||
|
|
||||||
|
|
||||||
// 异步读取12字节(带超时)
|
|
||||||
byte[] buffer = new byte[12];
|
|
||||||
int totalRead = 0;
|
|
||||||
DateTime start = DateTime.Now;
|
|
||||||
while (totalRead < 12 && (DateTime.Now - start).TotalMilliseconds < 1500)
|
|
||||||
{
|
|
||||||
if (_serialPort.BytesToRead > 0)
|
|
||||||
{
|
|
||||||
int read = await _serialPort.BaseStream.ReadAsync(buffer, totalRead, 12 - totalRead);
|
|
||||||
if (read > 0) totalRead += read;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
await Task.Delay(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalRead == 12)
|
|
||||||
{
|
|
||||||
|
|
||||||
// 解析回采电流 (byte4, byte5)
|
|
||||||
int rawCurrent = (buffer[4] << 8) | buffer[5];
|
|
||||||
double actualCurrent = rawCurrent / 1000.0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private async void BtnSet()
|
|
||||||
{
|
|
||||||
if (!_isConnected)
|
|
||||||
{
|
|
||||||
MessageBox.Show("请先连接串口");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double target = 0.650;
|
|
||||||
|
|
||||||
// 构造12字节电流命令
|
|
||||||
int raw = (int)(target * 1000);
|
|
||||||
byte cmdH = (byte)((raw >> 8) & 0xFF);
|
|
||||||
byte cmdL = (byte)(raw & 0xFF);
|
|
||||||
|
|
||||||
byte[] currentCmd = new byte[12];
|
|
||||||
currentCmd[0] = 0xFE;
|
|
||||||
currentCmd[1] = 0xFE;
|
|
||||||
currentCmd[2] = 0x55;
|
|
||||||
currentCmd[3] = 0xAA;
|
|
||||||
currentCmd[4] = cmdH;
|
|
||||||
currentCmd[5] = cmdL;
|
|
||||||
currentCmd[6] = 0x01;
|
|
||||||
currentCmd[7] = 1;
|
|
||||||
currentCmd[8] = 0;
|
|
||||||
currentCmd[9] = 0x00;
|
|
||||||
currentCmd[10] = 0xFF;
|
|
||||||
currentCmd[11] = 0xFF;
|
|
||||||
|
|
||||||
await SendCommandSafe(currentCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,9 @@
|
|||||||
xmlns:oxy="http://oxyplot.org/wpf"
|
xmlns:oxy="http://oxyplot.org/wpf"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:ASTM_D7896_Tester.Views"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
|
xmlns:converters="clr-namespace:ASTM_D7896_Tester.Converters"
|
||||||
d:DesignHeight="768" d:DesignWidth="1024" Loaded="UserControl_Loaded">
|
d:DesignHeight="768" d:DesignWidth="1024" Loaded="UserControl_Loaded">
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
@@ -35,7 +37,7 @@
|
|||||||
</Setter>
|
</Setter>
|
||||||
<Setter Property="BorderBrush" Value="#ADADAD"/>
|
<Setter Property="BorderBrush" Value="#ADADAD"/>
|
||||||
<Setter Property="BorderThickness" Value="1"/>
|
<Setter Property="BorderThickness" Value="1"/>
|
||||||
<Setter Property="Padding" Value="12,6"/>
|
<Setter Property="Padding" Value="8,4"/>
|
||||||
<Setter Property="Cursor" Value="Hand"/>
|
<Setter Property="Cursor" Value="Hand"/>
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<Trigger Property="IsMouseOver" Value="True">
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
@@ -62,10 +64,10 @@
|
|||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<!-- 卡片阴影效果 -->
|
<!-- 卡片阴影 -->
|
||||||
<DropShadowEffect x:Key="CardShadow" BlurRadius="8" ShadowDepth="2" Opacity="0.15" Color="Gray"/>
|
<DropShadowEffect x:Key="CardShadow" BlurRadius="5" ShadowDepth="1" Opacity="0.1" Color="Gray"/>
|
||||||
|
|
||||||
<!-- 主按钮绿色渐变(修复:将资源定义在正确的位置) -->
|
<!-- 主按钮绿色渐变 -->
|
||||||
<LinearGradientBrush x:Key="PrimaryButtonBrush" EndPoint="0,1" StartPoint="0,0">
|
<LinearGradientBrush x:Key="PrimaryButtonBrush" EndPoint="0,1" StartPoint="0,0">
|
||||||
<GradientStop Color="#4CAF50" Offset="0"/>
|
<GradientStop Color="#4CAF50" Offset="0"/>
|
||||||
<GradientStop Color="#388E3C" Offset="1"/>
|
<GradientStop Color="#388E3C" Offset="1"/>
|
||||||
@@ -75,7 +77,7 @@
|
|||||||
<Style TargetType="DataGrid">
|
<Style TargetType="DataGrid">
|
||||||
<Setter Property="FontFamily" Value="Segoe UI"/>
|
<Setter Property="FontFamily" Value="Segoe UI"/>
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="12"/>
|
||||||
<Setter Property="RowHeight" Value="28"/>
|
<Setter Property="RowHeight" Value="26"/>
|
||||||
<Setter Property="HeadersVisibility" Value="Column"/>
|
<Setter Property="HeadersVisibility" Value="Column"/>
|
||||||
<Setter Property="GridLinesVisibility" Value="Horizontal"/>
|
<Setter Property="GridLinesVisibility" Value="Horizontal"/>
|
||||||
<Setter Property="BorderBrush" Value="#E0E0E0"/>
|
<Setter Property="BorderBrush" Value="#E0E0E0"/>
|
||||||
@@ -95,92 +97,88 @@
|
|||||||
<Setter Property="BorderThickness" Value="0,0,1,1"/>
|
<Setter Property="BorderThickness" Value="0,0,1,1"/>
|
||||||
<Setter Property="Foreground" Value="#333333"/>
|
<Setter Property="Foreground" Value="#333333"/>
|
||||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||||
<Setter Property="Height" Value="32"/>
|
<Setter Property="Height" Value="28"/>
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<!-- 逆布尔转换器(如果还没在App.xaml中定义,可以在这里定义) -->
|
<!-- 逆布尔转换器(请确保已在 App.xaml 或本资源中定义) -->
|
||||||
<!-- 注意:如果已经在App.xaml中定义了InverseBooleanConverter,请注释掉下面这一行 -->
|
<converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
|
||||||
<!-- <converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/> -->
|
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
|
<!-- 去掉滚动条,使用 Grid 直接布局,紧凑边距 -->
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Background="#F2F2F2">
|
<Grid Background="#F2F2F2" Margin="5">
|
||||||
<Grid Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<!-- 样品信息 -->
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<!-- 仪表盘 -->
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<!-- 体积/密度/加压 -->
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<!-- 曲线图(固定高度380) -->
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="*"/>
|
<!-- 数据表格(占满剩余高度) -->
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<!-- 平均值+按钮 -->
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- 1. 样品信息 + 复选框(合并的4项确认) -->
|
<!-- 1. 样品信息 + 复选框 -->
|
||||||
<Border Grid.Row="0" Background="White" CornerRadius="6" Padding="10" Margin="0,0,0,8" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="0" Background="White" CornerRadius="4" Padding="8" Margin="0,0,0,4" Effect="{StaticResource CardShadow}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<WrapPanel Margin="0,0,0,8">
|
<WrapPanel Margin="0,0,0,5">
|
||||||
<TextBlock Text="样品ID:" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
<TextBlock Text="样品ID:" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
||||||
<TextBox Text="{Binding SampleId}" Width="120" Margin="0,0,20,0"/>
|
<TextBox Text="{Binding SampleId}" Width="120" Margin="0,0,15,0"/>
|
||||||
<TextBlock Text="测试温度(℃):" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
<TextBlock Text="测试温度(℃):" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
||||||
<TextBox Text="{Binding TestTemperature}" Width="70" IsReadOnly="True" Background="#F0F8FF" Margin="0,0,20,0"/>
|
<TextBox Text="{Binding TestTemperature}" Width="70" IsReadOnly="True" Background="#F0F8FF" Margin="0,0,15,0"/>
|
||||||
<TextBlock Text="日期:" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
<TextBlock Text="日期:" VerticalAlignment="Center" FontWeight="SemiBold" Margin="0,0,8,0"/>
|
||||||
<TextBox Text="{Binding TestDateTime}" Width="140" IsReadOnly="True" Background="#F0F8FF"/>
|
<TextBox Text="{Binding TestDateTime}" Width="140" IsReadOnly="True" Background="#F0F8FF"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<!-- 四个确认复选框,默认勾选 -->
|
<CheckBox IsChecked="{Binding IsCleanConfirmed}" Content="采样池清洁 (7.1)" Margin="0,0,12,0"/>
|
||||||
<CheckBox IsChecked="{Binding IsCleanConfirmed}" Content="采样池清洁 (7.1)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding BubbleRemoved}" Content="气泡清除 (7.6)" Margin="0,0,12,0"/>
|
||||||
<CheckBox IsChecked="{Binding BubbleRemoved}" Content="气泡清除 (7.6)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding PlatinumCompatible}" Content="铂兼容性 (1.4)" Margin="0,0,12,0"/>
|
||||||
<CheckBox IsChecked="{Binding PlatinumCompatible}" Content="铂兼容性 (1.4)" Margin="0,0,15,0"/>
|
|
||||||
<CheckBox IsChecked="{Binding AmbientCalibrated}" Content="采样池温度校准 (8.1)" Margin="0,0,15,0"/>
|
<CheckBox IsChecked="{Binding AmbientCalibrated}" Content="采样池温度校准 (8.1)" Margin="0,0,15,0"/>
|
||||||
<TextBlock Text="状态:" VerticalAlignment="Center" Margin="20,0,5,0"/>
|
<TextBlock Text="状态:" VerticalAlignment="Center" Margin="10,0,5,0"/>
|
||||||
<TextBox Text="{Binding StatusMessage}" Width="200" IsReadOnly="True" Background="#FFF7E6"/>
|
<TextBox Text="{Binding StatusMessage}" Width="180" IsReadOnly="True" Background="#FFF7E6"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 2. 核心参数仪表盘(温度、电压、电阻、压力) -->
|
<!-- 2. 核心参数仪表盘 -->
|
||||||
<Border Grid.Row="1" Background="White" CornerRadius="6" Padding="10" Margin="0,5" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="1" Background="White" CornerRadius="4" Padding="6" Margin="0,4" Effect="{StaticResource CardShadow}">
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
|
<Border Background="#E8F0FE" Padding="5" CornerRadius="4" Margin="0,0,10,0">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 核心参数仪表盘 - 更新绑定属性 -->
|
|
||||||
<Border Background="#E8F0FE" Padding="6" CornerRadius="4" Margin="0,0,15,0">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="🌡️ 样品温度:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
<TextBlock Text="🌡️ 样品温度:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding CurrentTestTemperature, StringFormat=F2}" Width="60" IsReadOnly="True"/>
|
<TextBox Text="{Binding CurrentTestTemperature, StringFormat=F2}" Width="55" IsReadOnly="True"/>
|
||||||
<TextBlock Text="℃" Margin="3,0,0,0"/>
|
<TextBlock Text="℃" Margin="3,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Background="#E8F0FE" Padding="6" CornerRadius="4" Margin="0,0,15,0">
|
<Border Background="#E8F0FE" Padding="5" CornerRadius="4" Margin="0,0,10,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="⏲️ 压力:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
<TextBlock Text="⏲️ 压力:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding ChamberPressure, StringFormat=F2}" Width="60" IsReadOnly="True"/>
|
<TextBox Text="{Binding ChamberPressure, StringFormat=F2}" Width="55" IsReadOnly="True"/>
|
||||||
<TextBlock Text="kPa" Margin="3,0,0,0"/>
|
<TextBlock Text="kPa" Margin="3,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Background="#E8F0FE" Padding="6" CornerRadius="4" Margin="0,0,15,0">
|
<Border Background="#E8F0FE" Padding="5" CornerRadius="4" Margin="0,0,10,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="⚡ 电阻电压:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
<TextBlock Text="⚡ 电阻电压:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding StandardResistorVoltage, StringFormat=F10}" Width="120" IsReadOnly="True"/>
|
<TextBox Text="{Binding StandardResistorVoltage, StringFormat=F10}" Width="110" IsReadOnly="True"/>
|
||||||
<TextBlock Text="V" Margin="3,0,0,0"/>
|
<TextBlock Text="V" Margin="3,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Background="#E8F0FE" Padding="6" CornerRadius="4" Margin="0,0,15,0">
|
<Border Background="#E8F0FE" Padding="5" CornerRadius="4" Margin="0,0,10,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="⚡ 铂丝电压:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
<TextBlock Text="⚡ 铂丝电压:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding PlatinumVoltage, StringFormat=F4}" Width="70" IsReadOnly="True"/>
|
<TextBox Text="{Binding PlatinumVoltage, StringFormat=F4}" Width="65" IsReadOnly="True"/>
|
||||||
<TextBlock Text="V" Margin="3,0,0,0"/>
|
<TextBlock Text="V" Margin="3,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<Border Background="#E8F0FE" Padding="6" CornerRadius="4" Margin="0,0,15,0">
|
<Border Background="#E8F0FE" Padding="5" CornerRadius="4" Margin="0,0,10,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="🔌 铂丝电阻:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
<TextBlock Text="🔌 铂丝电阻:" FontWeight="SemiBold" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding PlatinumResistance, StringFormat=F4}" Width="70" IsReadOnly="True"/>
|
<TextBox Text="{Binding PlatinumResistance, StringFormat=F4}" Width="65" IsReadOnly="True"/>
|
||||||
<TextBlock Text="Ω" Margin="3,0,0,0"/>
|
<TextBlock Text="Ω" Margin="3,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
@@ -188,152 +186,112 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 3. 样品体积 + 密度 + 加压设置 -->
|
<!-- 3. 样品体积 + 密度 + 加压设置 -->
|
||||||
<Border Grid.Row="2" Background="White" CornerRadius="6" Padding="10" Margin="0,5" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="2" Background="White" CornerRadius="4" Padding="6" Margin="0,4" Effect="{StaticResource CardShadow}">
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<TextBlock Text="样品体积 (mL):" VerticalAlignment="Center" Width="100"/>
|
<TextBlock Text="样品体积 (mL):" VerticalAlignment="Center" Width="95"/>
|
||||||
<TextBox Text="{Binding SampleVolume}" Width="60" Margin="0,0,20,0"/>
|
<TextBox Text="{Binding SampleVolume}" Width="60" Margin="0,0,20,0"/>
|
||||||
|
<TextBlock Text="密度 (kg/m³):" VerticalAlignment="Center" Width="95"/>
|
||||||
<!-- 新增密度输入框 -->
|
|
||||||
<TextBlock Text="密度 (kg/m³):" VerticalAlignment="Center" Width="100"/>
|
|
||||||
<TextBox Text="{Binding SampleDensity}" Width="80" Margin="0,0,20,0" ToolTip="输入样品密度,用于计算比热容"/>
|
<TextBox Text="{Binding SampleDensity}" Width="80" Margin="0,0,20,0" ToolTip="输入样品密度,用于计算比热容"/>
|
||||||
|
<CheckBox IsChecked="{Binding UsePressure}" Content="加压测试" VerticalAlignment="Center" Margin="0,0,12,0"/>
|
||||||
<CheckBox IsChecked="{Binding UsePressure}" Content="加压测试" VerticalAlignment="Center" Margin="0,0,15,0"/>
|
|
||||||
<TextBlock Text="压力 (kPa):" VerticalAlignment="Center" Margin="0,0,5,0"/>
|
<TextBlock Text="压力 (kPa):" VerticalAlignment="Center" Margin="0,0,5,0"/>
|
||||||
<TextBox Text="{Binding PressureValue}" Width="60" IsEnabled="{Binding UsePressure}" Margin="0,0,20,0"/>
|
<TextBox Text="{Binding PressureValue}" Width="60" IsEnabled="{Binding UsePressure}" Margin="0,0,15,0"/>
|
||||||
<TextBlock Text="(蒸气压>33.8kPa时需加压)" Foreground="Gray" VerticalAlignment="Center"/>
|
<TextBlock Text="(蒸气压>33.8kPa时需加压)" Foreground="Gray" VerticalAlignment="Center"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 4. 温升曲线图(核心新增) -->
|
<!-- 4. 温升曲线图(加高,使用 * 行高) -->
|
||||||
<Border Grid.Row="3" Background="White" CornerRadius="6" Padding="8" Margin="0,5" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="3" Background="White" CornerRadius="4" Padding="6" Margin="0,4" Effect="{StaticResource CardShadow}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock Text="{Binding CurveTitle}" FontWeight="Bold" FontSize="13" Margin="0,0,0,5" Foreground="#1E4F7A"/>
|
<TextBlock Text="{Binding CurveTitle}" FontWeight="Bold" FontSize="13" Margin="0,0,0,3" Foreground="#1E4F7A"/>
|
||||||
<oxy:PlotView Model="{Binding TemperatureCurveModel}" Height="350"/>
|
<!-- 将高度从350提升到380,并让控件随网格拉伸 -->
|
||||||
|
<oxy:PlotView Model="{Binding TemperatureCurveModel}" Height="220"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 5. 测量数据表格(占用剩余高度) -->
|
<!-- 5. 测量数据表格(占据剩余高度,带滚动条,最小高度保证可见) -->
|
||||||
<Border Grid.Row="4" Background="White" CornerRadius="6" Padding="8" Margin="0,5" Effect="{StaticResource CardShadow}">
|
<Border Grid.Row="4" Background="White" CornerRadius="4" Padding="6" Margin="0,4" Effect="{StaticResource CardShadow}">
|
||||||
<DataGrid ItemsSource="{Binding Measurements}" AutoGenerateColumns="False" HorizontalAlignment="Center" VerticalAlignment="Center"
|
<DataGrid ItemsSource="{Binding Measurements}" AutoGenerateColumns="False"
|
||||||
CanUserAddRows="False" IsReadOnly="True"
|
CanUserAddRows="False" IsReadOnly="True"
|
||||||
HeadersVisibility="Column" GridLinesVisibility="Horizontal"
|
HeadersVisibility="Column" GridLinesVisibility="Horizontal"
|
||||||
RowHeight="28" MinHeight="150">
|
RowHeight="24"
|
||||||
|
Height="120"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="60">
|
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="60">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
<DataGridTextColumn.HeaderStyle>
|
|
||||||
<Style TargetType="DataGridColumnHeader">
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.HeaderStyle>
|
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
|
|
||||||
<DataGridTextColumn Header="热导率 (W/m·K)" Binding="{Binding ThermalConductivity, StringFormat=F5}" Width="*">
|
<DataGridTextColumn Header="热导率 (W/m·K)" Binding="{Binding ThermalConductivity, StringFormat=F5}" Width="*">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
<DataGridTextColumn.HeaderStyle>
|
|
||||||
<Style TargetType="DataGridColumnHeader">
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.HeaderStyle>
|
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
|
|
||||||
<DataGridTextColumn Header="热扩散率 (m²/s)" Binding="{Binding ThermalDiffusivity, StringFormat=F10}" Width="*">
|
<DataGridTextColumn Header="热扩散率 (m²/s)" Binding="{Binding ThermalDiffusivity, StringFormat=F10}" Width="*">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
<DataGridTextColumn.HeaderStyle>
|
|
||||||
<Style TargetType="DataGridColumnHeader">
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.HeaderStyle>
|
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
|
|
||||||
<DataGridTextColumn Header="体积热容 (kJ/m³·K)" Binding="{Binding VolumetricHeatCapacity, StringFormat=F2}" Width="*">
|
<DataGridTextColumn Header="体积热容 (kJ/m³·K)" Binding="{Binding VolumetricHeatCapacity, StringFormat=F2}" Width="*">
|
||||||
<DataGridTextColumn.ElementStyle>
|
<DataGridTextColumn.ElementStyle>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.ElementStyle>
|
</DataGridTextColumn.ElementStyle>
|
||||||
<DataGridTextColumn.HeaderStyle>
|
|
||||||
<Style TargetType="DataGridColumnHeader">
|
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
|
||||||
</Style>
|
|
||||||
</DataGridTextColumn.HeaderStyle>
|
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 6. 平均值 + 操作按钮 -->
|
|
||||||
<Border Grid.Row="5" Background="#E8F0FE" CornerRadius="6" Padding="10" Margin="0,5" Effect="{StaticResource CardShadow}">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 6. 平均值 + 按钮(水平排列并放大) -->
|
||||||
|
<Border Grid.Row="5" Background="#E8F0FE" CornerRadius="4" Padding="8" Margin="0,4,0,0" Effect="{StaticResource CardShadow}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
<!-- 平均值显示行(保持不变) -->
|
||||||
<WrapPanel Margin="0,0,0,8">
|
<WrapPanel Margin="0,0,0,8">
|
||||||
<TextBlock Text="平均热导率:" Width="100" FontWeight="SemiBold"/>
|
<TextBlock Text="平均热导率:" Width="90" FontWeight="SemiBold"/>
|
||||||
<TextBox Text="{Binding AverageThermalConductivity, StringFormat=F5}" Width="100" IsReadOnly="True"/>
|
<TextBox Text="{Binding AverageThermalConductivity, StringFormat=F5}" Width="90" IsReadOnly="True"/>
|
||||||
<TextBlock Text="W/m·K" Margin="6,0,30,0"/>
|
<TextBlock Text="W/m·K" Margin="5,0,25,0"/>
|
||||||
<TextBlock Text="平均热扩散率:" Width="120" FontWeight="SemiBold"/>
|
<TextBlock Text="平均热扩散率:" Width="110" FontWeight="SemiBold"/>
|
||||||
<TextBox Text="{Binding AverageThermalDiffusivity, StringFormat=F10}" Width="100" IsReadOnly="True"/>
|
<TextBox Text="{Binding AverageThermalDiffusivity, StringFormat=F10}" Width="100" IsReadOnly="True"/>
|
||||||
<TextBlock Text="m²/s" Margin="6,0,30,0"/>
|
<TextBlock Text="m²/s" Margin="5,0,25,0"/>
|
||||||
<TextBlock Text="平均体积热容:" Width="100" FontWeight="SemiBold"/>
|
<TextBlock Text="平均体积热容:" Width="100" FontWeight="SemiBold"/>
|
||||||
<TextBox Text="{Binding AverageVolumetricHeatCapacity, StringFormat=F2}" Width="100" IsReadOnly="True"/>
|
<TextBox Text="{Binding AverageVolumetricHeatCapacity, StringFormat=F2}" Width="90" IsReadOnly="True"/>
|
||||||
<TextBlock Text="kJ/m³·K" Margin="6,0,0,0"/>
|
<TextBlock Text="kJ/m³·K" Margin="5,0,0,0"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<!-- 新增:压力校准、电阻归零、进排气按钮 -->
|
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,8">
|
|
||||||
<Button Content="压力校准" Command="{Binding PressureCalibrationCommand}" Width="90" Margin="5"/>
|
|
||||||
<Button Content="电阻归零" Command="{Binding ResistanceZeroCommand}" Width="90" Margin="5"/>
|
|
||||||
<Button Content="进气阀" Command="{Binding InletValveControlCommand}" Width="80" Margin="5"/>
|
|
||||||
<Button Content="排气阀" Command="{Binding OutletValveControlCommand}" Width="80" Margin="5"/>
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
|
||||||
|
|
||||||
<Button Content="▶ 开始测试" Command="{Binding StartTestCommand}" Width="130" Height="36" Margin="8"
|
<!-- 按钮区域:一排,放大按钮 -->
|
||||||
|
<WrapPanel HorizontalAlignment="Center" Margin="0,4">
|
||||||
|
<Button Content="压力校准" Command="{Binding PressureCalibrationCommand}"
|
||||||
|
Width="100" Height="36" Margin="5" FontSize="13"/>
|
||||||
|
<Button Content="电阻归零" Command="{Binding ResistanceZeroCommand}"
|
||||||
|
Width="100" Height="36" Margin="5" FontSize="13"/>
|
||||||
|
<Button Content="进气阀" Command="{Binding InletValveControlCommand}"
|
||||||
|
Width="90" Height="36" Margin="5" FontSize="13"/>
|
||||||
|
<Button Content="排气阀" Command="{Binding OutletValveControlCommand}"
|
||||||
|
Width="90" Height="36" Margin="5" FontSize="13"/>
|
||||||
|
<Button Content="▶ 开始测试" Command="{Binding StartTestCommand}"
|
||||||
|
Width="130" Height="40" Margin="5" FontSize="14" FontWeight="Bold"
|
||||||
IsEnabled="{Binding IsTesting, Converter={StaticResource InverseBooleanConverter}}"
|
IsEnabled="{Binding IsTesting, Converter={StaticResource InverseBooleanConverter}}"
|
||||||
Background="{StaticResource PrimaryButtonBrush}"/>
|
Background="{StaticResource PrimaryButtonBrush}"/>
|
||||||
|
<Button Content="■ 停止测试" Command="{Binding StopTestCommand}"
|
||||||
<Button Content="■ 停止测试" Command="{Binding StopTestCommand}" Width="130" Height="36" Margin="8" Background="Orange"/>
|
Width="130" Height="40" Margin="5" FontSize="14" FontWeight="Bold"
|
||||||
|
Background="Orange"/>
|
||||||
|
<Button Content="⟳ 重置" Command="{Binding ResetCommand}"
|
||||||
<Button Content="⟳ 重置" Command="{Binding ResetCommand}" Width="100" Height="36" Margin="8"/>
|
Width="100" Height="36" Margin="5" FontSize="13"/>
|
||||||
<Button Content="📄 生成报告" Command="{Binding GenerateReportCommand}" Width="110" Height="36" Margin="8"/>
|
<Button Content="📄 生成报告" Command="{Binding GenerateReportCommand}"
|
||||||
</StackPanel>
|
Width="110" Height="36" Margin="5" FontSize="13"/>
|
||||||
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<!-- 7. 系统校准(可选,可收起到折叠区域,为节省空间放在底部) -->
|
|
||||||
<!--<Border Grid.Row="6" Background="White" CornerRadius="6" Padding="8" Margin="0,5" Effect="{StaticResource CardShadow}">
|
|
||||||
<StackPanel>
|
|
||||||
<TextBlock Text="系统校准 (附录A3)" FontWeight="Bold" Margin="0,0,0,5"/>
|
|
||||||
<WrapPanel>
|
|
||||||
<TextBlock Text="参考液:" VerticalAlignment="Center"/>
|
|
||||||
<ComboBox ItemsSource="{Binding ReferenceLiquids}" SelectedItem="{Binding SelectedReferenceLiquid}" Width="100" Margin="5,0"/>
|
|
||||||
<TextBlock Text="参考热导率 (W/m·K):" VerticalAlignment="Center" Margin="10,0,5,0"/>
|
|
||||||
<TextBox Text="{Binding ReferenceConductivity}" Width="70" Margin="0,0,10,0"/>
|
|
||||||
-->
|
|
||||||
<!--<Button Content="开始校准" Command="{Binding PerformSystemCalibrationCommand}" Width="100"/>-->
|
|
||||||
<!--
|
|
||||||
</WrapPanel>
|
|
||||||
<TextBlock Text="{Binding CalibrationStatus}" FontSize="11" Foreground="Blue" Margin="0,5,0,0"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Border>-->
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
64
Window1.xaml
Normal file
64
Window1.xaml
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<Window x:Class="ConstantCurrentControl.Window1"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="SN-5A 恒流源控制" Height="500" Width="650"
|
||||||
|
WindowStartupLocation="CenterScreen">
|
||||||
|
<Grid Margin="10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="*"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<!-- 串口设置 -->
|
||||||
|
<GroupBox Header="串口设置" Grid.Row="0" Margin="5">
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="5">
|
||||||
|
<Label Content="端口:"/>
|
||||||
|
<ComboBox x:Name="cmbPort" Width="80" IsEditable="True" Text="COM2"/>
|
||||||
|
<Label Content="波特率:" Margin="10,0,0,0"/>
|
||||||
|
<ComboBox x:Name="cmbBaudrate" Width="80" SelectedIndex="1">
|
||||||
|
<ComboBoxItem>9600</ComboBoxItem>
|
||||||
|
<ComboBoxItem>19200</ComboBoxItem>
|
||||||
|
<ComboBoxItem>38400</ComboBoxItem>
|
||||||
|
<ComboBoxItem>115200</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
<Button x:Name="btnConnect" Content="连接" Click="BtnConnect_Click" Width="60" Margin="10,0,0,0"/>
|
||||||
|
<Button x:Name="btnDisconnect" Content="断开" Click="BtnDisconnect_Click" Width="60" Margin="5,0,0,0" IsEnabled="False"/>
|
||||||
|
</StackPanel>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<!-- 参数设置 -->
|
||||||
|
<GroupBox Header="输出参数(最优稳定性)" Grid.Row="1" Margin="5">
|
||||||
|
<StackPanel Margin="5">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
|
||||||
|
<Label Content="频率:"/>
|
||||||
|
<RadioButton x:Name="rb50Hz" Content="50 Hz" GroupName="Freq" IsChecked="True" Margin="5,0,15,0"/>
|
||||||
|
<RadioButton x:Name="rb60Hz" Content="60 Hz" GroupName="Freq"/>
|
||||||
|
<Label Content="设定电流 (A):" Margin="20,0,0,0"/>
|
||||||
|
<TextBox x:Name="txtSetCurrent" Text="1" Width="80" TextAlignment="Center"/>
|
||||||
|
<Label Content="A"/>
|
||||||
|
<Button x:Name="btnSet" Content="直接设定" Click="BtnSet_Click" Width="80" Margin="10,0,0,0"/>
|
||||||
|
<Button x:Name="btnStop" Content="禁止输出" Click="BtnStop_Click" Width="80" Margin="5,0,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
<CheckBox x:Name="chkSmooth" Content="启用平滑过渡 (步进0.05A, 间隔200ms)" IsChecked="True" Margin="0,5,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 日志 -->
|
||||||
|
<GroupBox Header="通讯日志" Grid.Row="3" Margin="5">
|
||||||
|
<ListBox x:Name="lstLog" Height="120" FontFamily="Consolas"/>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<!-- 说明 -->
|
||||||
|
<TextBlock Grid.Row="4" TextWrapping="Wrap" FontSize="11" Foreground="Gray" Margin="5">
|
||||||
|
※ 协议:12字节命令 (FE FE + 识别码 + 电流高/低 + 模式+频率+跟踪 + FF FF)
|
||||||
|
※ 开启跟踪 (byte8=1) 和 PC调节 (byte6=1) 可获最低噪声与最小温漂
|
||||||
|
※ 平滑过渡可避免电流突变产生的冲击噪声
|
||||||
|
</TextBlock>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
253
Window1.xaml.cs
Normal file
253
Window1.xaml.cs
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
namespace ConstantCurrentControl
|
||||||
|
{
|
||||||
|
public partial class Window1 : Window
|
||||||
|
{
|
||||||
|
private SerialPort _serialPort;
|
||||||
|
private bool _isConnected = false;
|
||||||
|
private DispatcherTimer _readTimer;
|
||||||
|
private List<byte> _receiveBuffer = new List<byte>(); // 接收缓存
|
||||||
|
|
||||||
|
public Window1()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Loaded += MainWindow_Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
cmbPort.ItemsSource = SerialPort.GetPortNames();
|
||||||
|
if (cmbPort.Items.Count > 0) cmbPort.SelectedIndex = 0;
|
||||||
|
|
||||||
|
// 初始化定时器(50ms 间隔,UI 线程)
|
||||||
|
_readTimer = new DispatcherTimer();
|
||||||
|
_readTimer.Interval = TimeSpan.FromMilliseconds(50);
|
||||||
|
_readTimer.Tick += ReadTimer_Tick;
|
||||||
|
cmbPort.Text = "COM2";
|
||||||
|
}
|
||||||
|
|
||||||
|
#region 串口连接
|
||||||
|
private async void BtnConnect_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (cmbPort.SelectedItem == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请选择串口号");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string port = cmbPort.SelectedItem.ToString();
|
||||||
|
int baud = int.Parse((cmbBaudrate.SelectedItem as ComboBoxItem).Content.ToString());
|
||||||
|
_serialPort = new SerialPort(port, baud, Parity.None, 8, StopBits.One);
|
||||||
|
_serialPort.ReadTimeout = 100;
|
||||||
|
_serialPort.WriteTimeout = 1000;
|
||||||
|
_serialPort.Open();
|
||||||
|
|
||||||
|
_isConnected = true;
|
||||||
|
btnConnect.IsEnabled = false;
|
||||||
|
btnDisconnect.IsEnabled = true;
|
||||||
|
AddLog($"已连接 {port} @ {baud} bps");
|
||||||
|
|
||||||
|
// 清空接收缓存和串口缓冲区
|
||||||
|
_receiveBuffer.Clear();
|
||||||
|
_serialPort.DiscardInBuffer();
|
||||||
|
|
||||||
|
// 启动定时器读取
|
||||||
|
_readTimer.Start();
|
||||||
|
|
||||||
|
// 发送配置命令(不跟踪模式,byte8=0)
|
||||||
|
await ConfigureOptimalMode();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"连接失败: {ex.Message}");
|
||||||
|
_isConnected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BtnDisconnect_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_readTimer != null) _readTimer.Stop();
|
||||||
|
if (_serialPort != null && _serialPort.IsOpen)
|
||||||
|
{
|
||||||
|
_serialPort.Close();
|
||||||
|
_serialPort.Dispose();
|
||||||
|
_serialPort = null;
|
||||||
|
}
|
||||||
|
_isConnected = false;
|
||||||
|
btnConnect.IsEnabled = true;
|
||||||
|
btnDisconnect.IsEnabled = false;
|
||||||
|
AddLog("已断开连接");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 定时器读取数据
|
||||||
|
private void ReadTimer_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int bytesToRead = _serialPort.BytesToRead;
|
||||||
|
if (bytesToRead > 0)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[bytesToRead];
|
||||||
|
_serialPort.Read(buffer, 0, bytesToRead);
|
||||||
|
_receiveBuffer.AddRange(buffer);
|
||||||
|
|
||||||
|
// 解析完整帧(12字节,以 FE FE 开头,FF FF 结尾)
|
||||||
|
ParseCompleteFrames();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AddLog($"读取错误: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ParseCompleteFrames()
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= _receiveBuffer.Count - 12; i++)
|
||||||
|
{
|
||||||
|
if (_receiveBuffer[i] == 0xFE && _receiveBuffer[i + 1] == 0xFE &&
|
||||||
|
_receiveBuffer[i + 10] == 0xFF && _receiveBuffer[i + 11] == 0xFF)
|
||||||
|
{
|
||||||
|
byte[] frame = _receiveBuffer.Skip(i).Take(12).ToArray();
|
||||||
|
ProcessFrame(frame);
|
||||||
|
// 移除已处理的帧
|
||||||
|
_receiveBuffer.RemoveRange(0, i + 12);
|
||||||
|
i = -1; // 重新扫描
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 防止缓存无限增长
|
||||||
|
if (_receiveBuffer.Count > 200)
|
||||||
|
_receiveBuffer.RemoveRange(0, _receiveBuffer.Count - 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessFrame(byte[] frame)
|
||||||
|
{
|
||||||
|
// 解析电流(byte4, byte5)
|
||||||
|
int rawCurrent = (frame[4] << 8) | frame[5];
|
||||||
|
double current = rawCurrent / 1000.0;
|
||||||
|
|
||||||
|
AddLog($"回采帧: {BitConverter.ToString(frame)} 电流={current:F3}A");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 发送命令(只写,不等待读)
|
||||||
|
private async Task<bool> SendCommand(byte[] command)
|
||||||
|
{
|
||||||
|
if (!_isConnected || _serialPort == null || !_serialPort.IsOpen)
|
||||||
|
{
|
||||||
|
AddLog("串口未打开");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _serialPort.BaseStream.WriteAsync(command, 0, command.Length);
|
||||||
|
AddLog($"发送: {BitConverter.ToString(command)}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AddLog($"发送失败: {ex.Message}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ConfigureOptimalMode()
|
||||||
|
{
|
||||||
|
byte[] configCmd = new byte[12];
|
||||||
|
configCmd[0] = 0xFE;
|
||||||
|
configCmd[1] = 0xFE;
|
||||||
|
configCmd[2] = 0x55;
|
||||||
|
configCmd[3] = 0xAA;
|
||||||
|
configCmd[4] = 0x00;
|
||||||
|
configCmd[5] = 0x00;
|
||||||
|
configCmd[6] = 0x01; // PC调节
|
||||||
|
configCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
|
||||||
|
configCmd[8] = 0x00; // 不跟踪(你实测稳定)
|
||||||
|
configCmd[9] = 0x00;
|
||||||
|
configCmd[10] = 0xFF;
|
||||||
|
configCmd[11] = 0xFF;
|
||||||
|
await SendCommand(configCmd);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region UI操作
|
||||||
|
private async void BtnSet_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("请先连接串口");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!double.TryParse(txtSetCurrent.Text, out double target) || target < 0 || target > 5)
|
||||||
|
{
|
||||||
|
MessageBox.Show("电流需为 0~5.000 A");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw = (int)(target * 1000);
|
||||||
|
byte cmdH = (byte)((raw >> 8) & 0xFF);
|
||||||
|
byte cmdL = (byte)(raw & 0xFF);
|
||||||
|
|
||||||
|
byte[] currentCmd = new byte[12];
|
||||||
|
currentCmd[0] = 0xFE;
|
||||||
|
currentCmd[1] = 0xFE;
|
||||||
|
currentCmd[2] = 0x55;
|
||||||
|
currentCmd[3] = 0xAA;
|
||||||
|
currentCmd[4] = cmdH;
|
||||||
|
currentCmd[5] = cmdL;
|
||||||
|
currentCmd[6] = 0x01;
|
||||||
|
currentCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
|
||||||
|
currentCmd[8] = 0x00; // 不跟踪
|
||||||
|
currentCmd[9] = 0x00;
|
||||||
|
currentCmd[10] = 0xFF;
|
||||||
|
currentCmd[11] = 0xFF;
|
||||||
|
|
||||||
|
await SendCommand(currentCmd);
|
||||||
|
AddLog($"设定电流 = {target:F3} A");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void BtnStop_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_isConnected) return;
|
||||||
|
byte[] stopCmd = new byte[12];
|
||||||
|
stopCmd[0] = 0xFE;
|
||||||
|
stopCmd[1] = 0xFE;
|
||||||
|
stopCmd[2] = 0x55;
|
||||||
|
stopCmd[3] = 0xAA;
|
||||||
|
stopCmd[4] = 0x00;
|
||||||
|
stopCmd[5] = 0x00;
|
||||||
|
stopCmd[6] = 0x01;
|
||||||
|
stopCmd[7] = rb50Hz.IsChecked == true ? (byte)1 : (byte)2;
|
||||||
|
stopCmd[8] = 0x00; // 不跟踪
|
||||||
|
stopCmd[9] = 0x00;
|
||||||
|
stopCmd[10] = 0xFF;
|
||||||
|
stopCmd[11] = 0xFF;
|
||||||
|
await SendCommand(stopCmd);
|
||||||
|
AddLog("禁止输出 (0A)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddLog(string msg)
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
lstLog.Items.Insert(0, $"{DateTime.Now:HH:mm:ss} {msg}");
|
||||||
|
if (lstLog.Items.Count > 50) lstLog.Items.RemoveAt(lstLog.Items.Count - 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
//"PlatinumWireDiameter": 0.000032,
|
//"PlatinumWireDiameter": 0.000032,
|
||||||
//"PlatinumWireLength": 0.056, //铂丝长度(单位:米)
|
//"PlatinumWireLength": 0.056, //铂丝长度(单位:米)
|
||||||
//"PlatinumWireDiameter": 0.00006,
|
//"PlatinumWireDiameter": 0.00006,
|
||||||
"PlatinumWireLength": 0.04, //铂丝长度(单位:米)
|
"PlatinumWireLength": 0.035, //铂丝长度(单位:米)
|
||||||
"PlatinumWireDiameter": 0.00006,
|
"PlatinumWireDiameter": 0.00010,
|
||||||
"ReportOutputPath": "Reports\\",
|
"ReportOutputPath": "Reports\\",
|
||||||
"DefaultSampleVolume": 40.0,
|
"DefaultSampleVolume": 40.0,
|
||||||
"DefaultPressure": 0.0,
|
"DefaultPressure": 0.0,
|
||||||
|
|||||||
BIN
瞬态热线法说明书.docx
BIN
瞬态热线法说明书.docx
Binary file not shown.
Reference in New Issue
Block a user