20260311 更新
This commit is contained in:
@@ -626,6 +626,41 @@ namespace COFTester.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发测试停止按钮 M32(复归型)
|
||||
/// M32 需要写入脉冲信号:true -> 延迟 -> false
|
||||
/// </summary>
|
||||
public virtual async Task TriggerTestStopAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_modbusMaster != null && _isConnected)
|
||||
{
|
||||
const ushort STOP_BUTTON_ADDRESS = 32; // M32 停止按钮
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] 触发测试停止按钮 M{STOP_BUTTON_ADDRESS}");
|
||||
|
||||
await _modbusMaster.WriteSingleCoilAsync(1, STOP_BUTTON_ADDRESS, true);
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] M{STOP_BUTTON_ADDRESS} = true");
|
||||
|
||||
await Task.Delay(100);
|
||||
|
||||
await _modbusMaster.WriteSingleCoilAsync(1, STOP_BUTTON_ADDRESS, false);
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] M{STOP_BUTTON_ADDRESS} = false");
|
||||
|
||||
await Task.Delay(100);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] M{STOP_BUTTON_ADDRESS} 脉冲信号发送完成");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OnErrorOccurred($"触发测试停止失败: {ex.Message}");
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] 触发 M32 异常: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取测试状态标记位 M31
|
||||
/// M31: 1=测试中,0=停止
|
||||
@@ -655,6 +690,46 @@ namespace COFTester.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取当前实时传感器数据,用于非测试状态下的界面实时显示。
|
||||
/// </summary>
|
||||
public virtual async Task<TestDataPoint?> ReadCurrentDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_modbusMaster == null || !_isConnected)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dataPoint = await ReadSensorDataAsync();
|
||||
if (dataPoint == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var (verticalPos, horizontalPos) = await ReadPositionDataAsync();
|
||||
dataPoint.VerticalPosition = verticalPos;
|
||||
dataPoint.HorizontalPosition = horizontalPos;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
dataPoint.VerticalPosition = 0;
|
||||
dataPoint.HorizontalPosition = 0;
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] 读取实时位置数据失败: {ex.Message}");
|
||||
}
|
||||
|
||||
return dataPoint;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[Modbus] 读取实时数据异常: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入启动/停止寄存器 M31(已弃用,请使用 TriggerTestStartAsync)
|
||||
/// M30 复归型, M31 标注为 1=开始,0=停止
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace COFTester.ViewModels
|
||||
private readonly IDataAcquisitionService _daqService;
|
||||
private readonly DataProcessingService _processingService;
|
||||
private readonly DispatcherTimer _clockTimer;
|
||||
private readonly DispatcherTimer _liveSensorTimer;
|
||||
private readonly DispatcherTimer _m31StatusTimer; // M31状态检查定时器
|
||||
private WpfPlot? _wpfPlot;
|
||||
private readonly AppConfig _config;
|
||||
@@ -40,6 +41,9 @@ namespace COFTester.ViewModels
|
||||
private bool _showAllCurves = true;
|
||||
private int _testCounter = 0;
|
||||
private bool _disposed = false;
|
||||
private bool _isRefreshingLiveSensorData = false;
|
||||
private bool _isTestTransitioning = false;
|
||||
private bool _stopRequestedByUser = false;
|
||||
private string _selectedDirection = ""; // 选中的方向:Up/Down/Right/Left
|
||||
private string _resetButtonText; // 复位按钮文本
|
||||
private string _testButtonText; // 测试按钮文本
|
||||
@@ -69,7 +73,7 @@ namespace COFTester.ViewModels
|
||||
DisconnectCommand = new RelayCommand(Disconnect, () => IsConnected && !_isTesting);
|
||||
ToggleConnectionCommand = new AsyncRelayCommand(ToggleConnectionAsync, () => !_isConnecting && !_isTesting);
|
||||
StartCommand = new RelayCommand(StartTest, CanStartTest);
|
||||
StopCommand = new RelayCommand(StopTest, () => _isTesting);
|
||||
StopCommand = new RelayCommand(StopTest, CanStopTest);
|
||||
ResetCommand = new RelayCommand(Reset, () => !_isTesting && IsConnected);
|
||||
SwitchLanguageCommand = new RelayCommand(SwitchLanguage);
|
||||
OpenConfigCommand = new RelayCommand(OpenConfig);
|
||||
@@ -111,6 +115,13 @@ namespace COFTester.ViewModels
|
||||
_m31StatusTimer.Tick += async (s, e) => await CheckM31StatusAsync();
|
||||
_m31StatusTimer.Start();
|
||||
|
||||
_liveSensorTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = TimeSpan.FromMilliseconds(200)
|
||||
};
|
||||
_liveSensorTimer.Tick += async (s, e) => await RefreshLiveSensorDataAsync();
|
||||
_liveSensorTimer.Start();
|
||||
|
||||
// 根據配置自動連接
|
||||
AutoConnectOnStartup();
|
||||
}
|
||||
@@ -173,8 +184,9 @@ namespace COFTester.ViewModels
|
||||
if (oldCanStartTest != _canStartTest)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[ViewModel] 开始按钮可用性变化: {_canStartTest}");
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -184,6 +196,48 @@ namespace COFTester.ViewModels
|
||||
{
|
||||
return _canStartTest;
|
||||
}
|
||||
|
||||
private bool CanStopTest()
|
||||
{
|
||||
return IsConnected && (_isTesting || _m31Status || _isTestTransitioning);
|
||||
}
|
||||
|
||||
private async Task RefreshLiveSensorDataAsync()
|
||||
{
|
||||
if (_disposed || _isRefreshingLiveSensorData || !IsConnected || _isTesting || _isTestTransitioning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_daqService is not ModbusServiceBase modbusService)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_isRefreshingLiveSensorData = true;
|
||||
|
||||
var point = await modbusService.ReadCurrentDataAsync();
|
||||
if (point == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentForce = point.Force;
|
||||
CurrentDisp = point.Displacement;
|
||||
LiftPosition = point.VerticalPosition;
|
||||
HorizontalPosition = point.HorizontalPosition;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[ViewModel] 实时数值刷新失败: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isRefreshingLiveSensorData = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 設置圖表控件(由TestPage調用)
|
||||
@@ -575,6 +629,13 @@ namespace COFTester.ViewModels
|
||||
TestButtonText = Lang.StartTest; // 测试完成后恢复按钮文本
|
||||
_m31Status = false; // 测试完成,M31应该为0
|
||||
UpdateCanStartTest(); // 更新按钮可用性
|
||||
if (_stopRequestedByUser)
|
||||
{
|
||||
_stopRequestedByUser = false;
|
||||
StatusMessage = Lang.TestStopped;
|
||||
return;
|
||||
}
|
||||
|
||||
StatusMessage = Lang.TestCompleted;
|
||||
|
||||
// 数据处理与计算
|
||||
@@ -661,6 +722,7 @@ namespace COFTester.ViewModels
|
||||
_m31Status = await modbusService.ReadTestStatusAsync();
|
||||
System.Diagnostics.Debug.WriteLine($"[ViewModel] 连接后M31状态: {(_m31Status ? "1 (测试中)" : "0 (停止)")}");
|
||||
UpdateCanStartTest();
|
||||
await RefreshLiveSensorDataAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -799,6 +861,10 @@ namespace COFTester.ViewModels
|
||||
// return;
|
||||
//}
|
||||
|
||||
_stopRequestedByUser = false;
|
||||
_isTestTransitioning = true;
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
|
||||
_realTimePoints.Clear();
|
||||
OnPropertyChanged(nameof(DataPointsCount));
|
||||
LatestResult = null;
|
||||
@@ -842,6 +908,8 @@ namespace COFTester.ViewModels
|
||||
{
|
||||
// 测试未启动,保持原状态
|
||||
_m31Status = false; // 更新M31状态
|
||||
_isTestTransitioning = false;
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
StatusMessage = "测试启动失败,请检查设备";
|
||||
System.Diagnostics.Debug.WriteLine("[ViewModel] M31 = 0,测试未启动");
|
||||
}
|
||||
@@ -853,6 +921,8 @@ namespace COFTester.ViewModels
|
||||
{
|
||||
StatusMessage = $"启动测试失败: {ex.Message}";
|
||||
_m31Status = false;
|
||||
_isTestTransitioning = false;
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
System.Diagnostics.Debug.WriteLine($"[ViewModel] 启动测试异常: {ex.Message}");
|
||||
});
|
||||
}
|
||||
@@ -861,21 +931,43 @@ namespace COFTester.ViewModels
|
||||
|
||||
// _daqService.StartDirectionTest(_selectedDirection); // 暂时注释掉
|
||||
_daqService.StartAcquisition(Parameters);
|
||||
_isTestTransitioning = false;
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
}
|
||||
|
||||
private void StopTest()
|
||||
private async void StopTest()
|
||||
{
|
||||
_stopRequestedByUser = true;
|
||||
_isTestTransitioning = true;
|
||||
CommandManager.InvalidateRequerySuggested();
|
||||
|
||||
// M30 复归型按钮,M31 状态标记位(1=测试中,0=停止)
|
||||
// M31 是只读状态位,由 PLC 控制,我们只需停止数据采集
|
||||
// PLC 会自动将 M31 设置为 0
|
||||
|
||||
_daqService.StopAcquisition();
|
||||
IsTesting = false;
|
||||
TestButtonText = Lang.StartTest; // 恢复按钮文本为"开始测试"
|
||||
StatusMessage = Lang.TestStopped;
|
||||
UpdateCanStartTest(); // 更新按钮可用性
|
||||
try
|
||||
{
|
||||
if (_daqService is ModbusServiceBase modbusService)
|
||||
{
|
||||
await modbusService.TriggerTestStopAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusMessage = $"停止测试失败: {ex.Message}";
|
||||
System.Diagnostics.Debug.WriteLine($"[ViewModel] 停止测试异常: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_daqService.StopAcquisition();
|
||||
IsTesting = false;
|
||||
TestButtonText = Lang.StartTest;
|
||||
StatusMessage = Lang.TestStopped;
|
||||
_isTestTransitioning = false;
|
||||
UpdateCanStartTest();
|
||||
|
||||
System.Diagnostics.Debug.WriteLine("[ViewModel] 停止测试,等待 PLC 将 M31 设置为 0");
|
||||
System.Diagnostics.Debug.WriteLine("[ViewModel] 已发送 M32 停止命令,并停止本地数据采集");
|
||||
}
|
||||
}
|
||||
|
||||
private async void Reset()
|
||||
@@ -1626,6 +1718,7 @@ namespace COFTester.ViewModels
|
||||
|
||||
// 停止M31状态检查定时器
|
||||
_m31StatusTimer?.Stop();
|
||||
_liveSensorTimer?.Stop();
|
||||
|
||||
// 取消訂閱事件
|
||||
if (_daqService != null)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="CSI-H238M 高配版摩擦系数仪、摩擦系数测定仪" Height="800" Width="1024"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
WindowState="Maximized"
|
||||
Background="#F0F3F5">
|
||||
<Window.Resources>
|
||||
<Style x:Key="NavButtonStyle" TargetType="RadioButton">
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
|
||||
<!-- 向右按钮 -->
|
||||
<Button x:Name="BtnRight" Content="{Binding Lang.DirectionRight}"
|
||||
Height="70" Width="100"
|
||||
@@ -273,6 +274,15 @@
|
||||
</Button>
|
||||
|
||||
<!-- 复位按钮 - 动态显示状态:复位 → 复位中 → 复位 -->
|
||||
<Button Content="{Binding Lang.Stop}" Command="{Binding StopCommand}"
|
||||
Height="70" Width="110" Margin="5">
|
||||
<Button.Style>
|
||||
<Style TargetType="Button" BasedOn="{StaticResource IndustrialButtonStyle}">
|
||||
<Setter Property="Background" Value="#C0392B"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
<Button Content="{Binding ResetButtonText}" Command="{Binding ResetCommand}"
|
||||
Height="70" Width="110" Background="#3498DB"
|
||||
Style="{StaticResource IndustrialButtonStyle}" Margin="5"/>
|
||||
|
||||
Reference in New Issue
Block a user