更新
This commit is contained in:
@@ -442,10 +442,80 @@ namespace COFTester.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 写入启动/停止寄存器 M31
|
/// 触发测试启动按钮 M30(复归型)
|
||||||
|
/// M30 是复归型按钮,需要写入脉冲信号:true → 延迟 → false
|
||||||
|
/// 然后通过读取 M31 来判断测试是否真正开始(1=测试中,0=停止)
|
||||||
|
/// </summary>
|
||||||
|
public virtual async Task TriggerTestStartAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_modbusMaster != null && _isConnected)
|
||||||
|
{
|
||||||
|
const ushort START_BUTTON_ADDRESS = 30; // M30 复归型按钮
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] 触发测试启动按钮 M{START_BUTTON_ADDRESS}");
|
||||||
|
|
||||||
|
// 写入 true(触发)
|
||||||
|
await _modbusMaster.WriteSingleCoilAsync(1, START_BUTTON_ADDRESS, true);
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] M{START_BUTTON_ADDRESS} = true");
|
||||||
|
|
||||||
|
// 延迟 100ms
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
// 写入 false(复位)
|
||||||
|
await _modbusMaster.WriteSingleCoilAsync(1, START_BUTTON_ADDRESS, false);
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] M{START_BUTTON_ADDRESS} = false");
|
||||||
|
|
||||||
|
// 延迟 100ms 确保 PLC 处理完成
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] M{START_BUTTON_ADDRESS} 脉冲信号发送完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnErrorOccurred($"触发测试启动失败: {ex.Message}");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] 触发 M30 异常: {ex.Message}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取测试状态标记位 M31
|
||||||
|
/// M31: 1=测试中,0=停止
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>true=测试中,false=停止</returns>
|
||||||
|
public virtual async Task<bool> ReadTestStatusAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_modbusMaster != null && _isConnected)
|
||||||
|
{
|
||||||
|
const ushort STATUS_FLAG_ADDRESS = 31; // M31 状态标记位
|
||||||
|
|
||||||
|
var coils = await _modbusMaster.ReadCoilsAsync(1, STATUS_FLAG_ADDRESS, 1);
|
||||||
|
bool isRunning = coils[0];
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] 读取测试状态 M{STATUS_FLAG_ADDRESS} = {(isRunning ? "1 (测试中)" : "0 (停止)")}");
|
||||||
|
|
||||||
|
return isRunning;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[Modbus] 读取 M31 状态异常: {ex.Message}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 写入启动/停止寄存器 M31(已弃用,请使用 TriggerTestStartAsync)
|
||||||
/// M30 复归型, M31 标注为 1=开始,0=停止
|
/// M30 复归型, M31 标注为 1=开始,0=停止
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">1=开始测试, 0=停止测试</param>
|
/// <param name="value">1=开始测试, 0=停止测试</param>
|
||||||
|
[Obsolete("请使用 TriggerTestStartAsync() 触发 M30,然后通过 ReadTestStatusAsync() 读取 M31 状态")]
|
||||||
public virtual async Task WriteStartStopRegisterAsync(ushort value)
|
public virtual async Task WriteStartStopRegisterAsync(ushort value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -649,6 +719,7 @@ namespace COFTester.Services
|
|||||||
/// 數據採集主循環
|
/// 數據採集主循環
|
||||||
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
||||||
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
||||||
|
/// M30 复归型按钮触发测试,M31 状态标记位(1=测试中,0=停止)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
||||||
{
|
{
|
||||||
@@ -666,11 +737,30 @@ namespace COFTester.Services
|
|||||||
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 注意:使用 M31=1 启动测试,M31=0 停止测试");
|
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 监控 M31 状态:1=测试中,0=停止");
|
||||||
|
|
||||||
// 循环读取传感器数据(包含力值、位移和位置)
|
// 循环读取传感器数据(包含力值、位移和位置)
|
||||||
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
||||||
{
|
{
|
||||||
|
// 每隔一定次数检查 M31 状态(避免频繁读取)
|
||||||
|
if (i % 10 == 0) // 每 10 个数据点检查一次
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
if (!isTestRunning)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ModbusTCP] M31 = 0,PLC 已停止测试");
|
||||||
|
break; // 退出采集循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 读取 M31 状态失败: {ex.Message}");
|
||||||
|
// 读取失败不影响数据采集,继续执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 读取力值和位移
|
// 读取力值和位移
|
||||||
var dataPoint = await ReadSensorDataAsync();
|
var dataPoint = await ReadSensorDataAsync();
|
||||||
|
|
||||||
@@ -707,7 +797,16 @@ namespace COFTester.Services
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_isAcquiring = false;
|
_isAcquiring = false;
|
||||||
System.Diagnostics.Debug.WriteLine("[ModbusTCP] 數據採集結束(不再發送 Stop 命令)");
|
System.Diagnostics.Debug.WriteLine("[ModbusTCP] 數據採集結束");
|
||||||
|
|
||||||
|
// 最后再检查一次 M31 状态
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusTCP] 采集结束时 M31 = {(isTestRunning ? "1 (测试中)" : "0 (停止)")}");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
OnTestFinished();
|
OnTestFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1106,6 +1205,7 @@ namespace COFTester.Services
|
|||||||
/// 數據採集主循環
|
/// 數據採集主循環
|
||||||
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
||||||
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
||||||
|
/// M30 复归型按钮触发测试,M31 状态标记位(1=测试中,0=停止)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
||||||
{
|
{
|
||||||
@@ -1123,11 +1223,30 @@ namespace COFTester.Services
|
|||||||
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 注意:使用 M31=1 启动测试,M31=0 停止测试");
|
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 监控 M31 状态:1=测试中,0=停止");
|
||||||
|
|
||||||
// 循环读取传感器数据(包含力值、位移和位置)
|
// 循环读取传感器数据(包含力值、位移和位置)
|
||||||
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
||||||
{
|
{
|
||||||
|
// 每隔一定次数检查 M31 状态(避免频繁读取)
|
||||||
|
if (i % 10 == 0) // 每 10 个数据点检查一次
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
if (!isTestRunning)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ModbusRTU] M31 = 0,PLC 已停止测试");
|
||||||
|
break; // 退出采集循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 读取 M31 状态失败: {ex.Message}");
|
||||||
|
// 读取失败不影响数据采集,继续执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 读取力值和位移
|
// 读取力值和位移
|
||||||
var dataPoint = await ReadSensorDataAsync();
|
var dataPoint = await ReadSensorDataAsync();
|
||||||
|
|
||||||
@@ -1164,7 +1283,16 @@ namespace COFTester.Services
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_isAcquiring = false;
|
_isAcquiring = false;
|
||||||
System.Diagnostics.Debug.WriteLine("[ModbusRTU] 數據採集結束(不再發送 Stop 命令)");
|
System.Diagnostics.Debug.WriteLine("[ModbusRTU] 數據採集結束");
|
||||||
|
|
||||||
|
// 最后再检查一次 M31 状态
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusRTU] 采集结束时 M31 = {(isTestRunning ? "1 (测试中)" : "0 (停止)")}");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
OnTestFinished();
|
OnTestFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1547,6 +1675,7 @@ namespace COFTester.Services
|
|||||||
/// 數據採集主循環
|
/// 數據採集主循環
|
||||||
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
/// 正確流程:1. 寫入測試參數 → 2. 循環讀取數據(力值、位移、位置)
|
||||||
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
/// 注意:不再發送 Start/Stop 命令,由方向控制(M0-M3)來控制運動
|
||||||
|
/// M30 复归型按钮触发测试,M31 状态标记位(1=测试中,0=停止)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
protected override async Task AcquisitionLoopAsync(TestParameters parameters, CancellationToken token)
|
||||||
{
|
{
|
||||||
@@ -1563,11 +1692,30 @@ namespace COFTester.Services
|
|||||||
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
int totalPoints = (int)(parameters.TestDuration * parameters.SamplingRate);
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 数据采集配置: {totalPoints} 点, 间隔 {intervalMs:F1}ms");
|
||||||
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 注意:使用 M31=1 启动测试,M31=0 停止测试");
|
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 监控 M31 状态:1=测试中,0=停止");
|
||||||
|
|
||||||
// 循环读取传感器数据(包含力值、位移和位置)
|
// 循环读取传感器数据(包含力值、位移和位置)
|
||||||
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
for (int i = 0; i < totalPoints && !token.IsCancellationRequested; i++)
|
||||||
{
|
{
|
||||||
|
// 每隔一定次数检查 M31 状态(避免频繁读取)
|
||||||
|
if (i % 10 == 0) // 每 10 个数据点检查一次
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
if (!isTestRunning)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ModbusASCII] M31 = 0,PLC 已停止测试");
|
||||||
|
break; // 退出采集循环
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 读取 M31 状态失败: {ex.Message}");
|
||||||
|
// 读取失败不影响数据采集,继续执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 读取力值和位移
|
// 读取力值和位移
|
||||||
var dataPoint = await ReadSensorDataAsync();
|
var dataPoint = await ReadSensorDataAsync();
|
||||||
|
|
||||||
@@ -1604,7 +1752,16 @@ namespace COFTester.Services
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
_isAcquiring = false;
|
_isAcquiring = false;
|
||||||
System.Diagnostics.Debug.WriteLine("[ModbusASCII] 数据采集结束(不再发送 Stop 命令)");
|
System.Diagnostics.Debug.WriteLine("[ModbusASCII] 数据采集结束");
|
||||||
|
|
||||||
|
// 最后再检查一次 M31 状态
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool isTestRunning = await ReadTestStatusAsync();
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[ModbusASCII] 采集结束时 M31 = {(isTestRunning ? "1 (测试中)" : "0 (停止)")}");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
OnTestFinished();
|
OnTestFinished();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -640,16 +640,40 @@ namespace COFTester.ViewModels
|
|||||||
StatusMessage = $"开始测试 - {_selectedDirection}方向";
|
StatusMessage = $"开始测试 - {_selectedDirection}方向";
|
||||||
UpdateScottPlot();
|
UpdateScottPlot();
|
||||||
|
|
||||||
// M30 复归型 M31标注为 1开始,0停止
|
// M30 复归型按钮,M31 状态标记位(1=测试中,0=停止)
|
||||||
// 向 M31 写入 1 开始测试
|
// 向 M30 写入复归型脉冲来触发测试启动
|
||||||
if (_daqService is ModbusServiceBase modbusService)
|
if (_daqService is ModbusServiceBase modbusService)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await modbusService.WriteStartStopRegisterAsync(1); // M31 = 1 开始
|
// 触发 M30 复归型按钮
|
||||||
System.Diagnostics.Debug.WriteLine("[ViewModel] M31 = 1 (开始测试)");
|
await modbusService.TriggerTestStartAsync();
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ViewModel] M30 脉冲已发送(触发测试启动)");
|
||||||
|
|
||||||
|
// 等待一小段时间让 PLC 处理
|
||||||
|
await Task.Delay(200);
|
||||||
|
|
||||||
|
// 读取 M31 确认测试是否真正开始
|
||||||
|
bool isTestRunning = await modbusService.ReadTestStatusAsync();
|
||||||
|
|
||||||
|
Application.Current?.Dispatcher.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
if (isTestRunning)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ViewModel] M31 = 1,测试已启动");
|
||||||
|
StatusMessage = "测试已启动";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ViewModel] M31 = 0,测试未启动");
|
||||||
|
StatusMessage = "测试启动失败,请检查设备";
|
||||||
|
// 启动失败时恢复按钮状态
|
||||||
|
IsTesting = false;
|
||||||
|
TestButtonText = Lang.StartTest;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -670,31 +694,16 @@ namespace COFTester.ViewModels
|
|||||||
|
|
||||||
private void StopTest()
|
private void StopTest()
|
||||||
{
|
{
|
||||||
// M30 复归型 M31标注为 1开始,0停止
|
// M30 复归型按钮,M31 状态标记位(1=测试中,0=停止)
|
||||||
// 向 M31 写入 0 停止测试
|
// M31 是只读状态位,由 PLC 控制,我们只需停止数据采集
|
||||||
if (_daqService is ModbusServiceBase modbusService)
|
// PLC 会自动将 M31 设置为 0
|
||||||
{
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await modbusService.WriteStartStopRegisterAsync(0); // M31 = 0 停止
|
|
||||||
System.Diagnostics.Debug.WriteLine("[ViewModel] M31 = 0 (停止测试)");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Application.Current?.Dispatcher.InvokeAsync(() =>
|
|
||||||
{
|
|
||||||
StatusMessage = $"停止测试失败: {ex.Message}";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_daqService.StopAcquisition();
|
_daqService.StopAcquisition();
|
||||||
IsTesting = false;
|
IsTesting = false;
|
||||||
TestButtonText = Lang.StartTest; // 恢复按钮文本为"开始测试"
|
TestButtonText = Lang.StartTest; // 恢复按钮文本为"开始测试"
|
||||||
StatusMessage = Lang.TestStopped;
|
StatusMessage = Lang.TestStopped;
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine("[ViewModel] 停止测试,等待 PLC 将 M31 设置为 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Reset()
|
private async void Reset()
|
||||||
|
|||||||
@@ -257,8 +257,7 @@
|
|||||||
|
|
||||||
<!-- 开始测试按钮 - 动态显示状态:开始测试 → 测试中(不可点击) → 开始测试 -->
|
<!-- 开始测试按钮 - 动态显示状态:开始测试 → 测试中(不可点击) → 开始测试 -->
|
||||||
<Button Content="{Binding TestButtonText}" Command="{Binding StartCommand}"
|
<Button Content="{Binding TestButtonText}" Command="{Binding StartCommand}"
|
||||||
Height="70" Width="110" Background="#27AE60"
|
Height="70" Width="110" Margin="5">
|
||||||
Style="{StaticResource IndustrialButtonStyle}" Margin="5">
|
|
||||||
<Button.Style>
|
<Button.Style>
|
||||||
<Style TargetType="Button" BasedOn="{StaticResource IndustrialButtonStyle}">
|
<Style TargetType="Button" BasedOn="{StaticResource IndustrialButtonStyle}">
|
||||||
<Setter Property="Background" Value="#27AE60"/>
|
<Setter Property="Background" Value="#27AE60"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user