From 52b8cecddc8f4f39cdefbf6d70726c1a0183568f Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Fri, 30 Jan 2026 13:46:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CSI-H238M/CSI-H238M/Services/ModbusService.cs | 74 +++++++++++++++++++ CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs | 49 ++++++++---- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/CSI-H238M/CSI-H238M/Services/ModbusService.cs b/CSI-H238M/CSI-H238M/Services/ModbusService.cs index 3c480b7..8b882fd 100644 --- a/CSI-H238M/CSI-H238M/Services/ModbusService.cs +++ b/CSI-H238M/CSI-H238M/Services/ModbusService.cs @@ -242,8 +242,82 @@ namespace COFTester.Services /// 实现方式:读取当前状态 → 写入相反状态 → 延迟 100ms /// 参考:case ButtonType.切换型 /// + /// + /// 触发复位按钮 M90(复归型) + /// M90 是复归型按钮,需要写入脉冲信号:true → 延迟 → false + /// 然后通过读取 M92 来判断复位是否完成(1=复位中,0=复位完成) + /// + public virtual async Task TriggerResetAsync() + { + try + { + if (_modbusMaster != null && _isConnected) + { + const ushort RESET_BUTTON_ADDRESS = 90; // M90 复归型按钮 + + System.Diagnostics.Debug.WriteLine($"[Modbus] 触发复位按钮 M{RESET_BUTTON_ADDRESS}"); + + // 写入 true(触发) + await _modbusMaster.WriteSingleCoilAsync(1, RESET_BUTTON_ADDRESS, true); + System.Diagnostics.Debug.WriteLine($"[Modbus] M{RESET_BUTTON_ADDRESS} = true"); + + // 延迟 100ms + await Task.Delay(100); + + // 写入 false(复位) + await _modbusMaster.WriteSingleCoilAsync(1, RESET_BUTTON_ADDRESS, false); + System.Diagnostics.Debug.WriteLine($"[Modbus] M{RESET_BUTTON_ADDRESS} = false"); + + // 延迟 100ms 确保 PLC 处理完成 + await Task.Delay(100); + + System.Diagnostics.Debug.WriteLine($"[Modbus] M{RESET_BUTTON_ADDRESS} 脉冲信号发送完成"); + } + } + catch (Exception ex) + { + OnErrorOccurred($"触发复位失败: {ex.Message}"); + System.Diagnostics.Debug.WriteLine($"[Modbus] 触发 M90 异常: {ex.Message}"); + throw; + } + } + + /// + /// 读取复位状态标记位 M92 + /// M92: 1=复位中,0=复位完成 + /// + /// true=复位中,false=复位完成 + public virtual async Task ReadResetStatusAsync() + { + try + { + if (_modbusMaster != null && _isConnected) + { + const ushort RESET_STATUS_ADDRESS = 92; // M92 状态标记位 + + var coils = await _modbusMaster.ReadCoilsAsync(1, RESET_STATUS_ADDRESS, 1); + bool isResetting = coils[0]; + + System.Diagnostics.Debug.WriteLine($"[Modbus] 读取复位状态 M{RESET_STATUS_ADDRESS} = {(isResetting ? "1 (复位中)" : "0 (复位完成)")}"); + + return isResetting; + } + return false; + } + catch (Exception ex) + { + System.Diagnostics.Debug.WriteLine($"[Modbus] 读取 M92 状态异常: {ex.Message}"); + return false; + } + } + + /// + /// 切换型复位操作(已弃用,请使用 TriggerResetAsync) + /// M90 复归型按钮,M92 状态标记位(1=复位中,0=复位完成) + /// /// 线圈地址(例如:M1301) /// 返回操作是否成功 + [Obsolete("请使用 TriggerResetAsync() 触发 M90,然后通过 ReadResetStatusAsync() 读取 M92 状态")] public virtual async Task ToggleResetAsync(ushort address) { try diff --git a/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs b/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs index 0b7d6d7..e3bf902 100644 --- a/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs +++ b/CSI-H238M/CSI-H238M/ViewModels/ViewModel.cs @@ -722,21 +722,46 @@ namespace COFTester.ViewModels CurrentDisp = 0; UpdateScottPlot(); - // 3. 执行切换型复位操作(使用 NModbus 3.0.81 API) - // 复位线圈地址为 M90 - const ushort RESET_COIL_ADDRESS = 90; - + // 3. M90 复归型按钮,M92 状态标记位(1=复位中,0=复位完成) + // 向 M90 写入复归型脉冲来触发复位 if (_daqService is ModbusServiceBase modbusService) { - bool success = await modbusService.ToggleResetAsync(RESET_COIL_ADDRESS); + // 触发 M90 复归型按钮 + await modbusService.TriggerResetAsync(); + System.Diagnostics.Debug.WriteLine("[ViewModel] M90 脉冲已发送(触发复位)"); - if (success) + // 等待一小段时间让 PLC 处理 + await Task.Delay(200); + + // 持续读取 M92 直到复位完成 + int maxAttempts = 50; // 最多等待 5 秒(50 * 100ms) + int attempts = 0; + bool isResetting = true; + + while (isResetting && attempts < maxAttempts) { - StatusMessage = Lang.SystemReset; + isResetting = await modbusService.ReadResetStatusAsync(); + + if (isResetting) + { + // M92 = 1,复位中 + System.Diagnostics.Debug.WriteLine($"[ViewModel] M92 = 1,复位中... (尝试 {attempts + 1}/{maxAttempts})"); + await Task.Delay(100); // 等待 100ms 后再次检查 + attempts++; + } + else + { + // M92 = 0,复位完成 + System.Diagnostics.Debug.WriteLine("[ViewModel] M92 = 0,复位完成"); + StatusMessage = Lang.SystemReset; + break; + } } - else + + if (attempts >= maxAttempts) { - StatusMessage = "复位失败"; + System.Diagnostics.Debug.WriteLine("[ViewModel] 复位超时"); + StatusMessage = "复位超时,请检查设备"; } } else @@ -754,10 +779,8 @@ namespace COFTester.ViewModels finally { // 4. 恢复按钮文本为"复位" - ResetButtonText = Lang.ResetComplete; - - // 延迟 500ms 后恢复原始文本 - await Task.Delay(500); + ResetButtonText = Lang.ResetSystem; + } ResetButtonText = Lang.ResetSystem; } }