using Modbus.Device; using Modbus; using OxyPlot.Series; using OxyPlot; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Threading; using OxyPlot.Axes; using OxyPlot.Legends; using 口罩泄露定制款; using 睡眠呼吸暂停治疗面罩多功能测试仪.Data; namespace ShanghaiEnvironmentalTechnology { /// /// Window6.xaml 的交互逻辑 /// public partial class Window6 : Window { DataChange c = new DataChange(); #region 寄存器/线圈地址定义(按功能分组,标注物理意义) // 控制线圈(M代码) private readonly ushort _OutBreathUpAddress = 0x0011; // 呼上(M17) private readonly ushort _OutBreathDownAddress = 0x0010; // 呼下(M16) private readonly ushort _InBreathUpAddress = 0x001E; // 吸上(M30) private readonly ushort _InBreathDownAddress = 0x001F; // 吸下(M31) private readonly ushort _HandInBreathUpAddress = 0x0013; // 手动吸(M19) private readonly ushort _HandInBreathDownAddress = 0x0012; // 手动呼(M18) private readonly ushort _BreathUpAddress = 0x002A; // 呼气校准(M42) private readonly ushort _BreathDownAddress = 0x002B; // 吸气校准(M43) private readonly ushort _PressCheckAddress = 41; // 压力校准(M41) Function fc; #endregion #region 寄存器/线圈地址定义 // 控制线圈(D代码) private readonly ushort _handSpeedAddress = 218; // 手动速度(D218) //潮气量系数 private readonly ushort _moistureAddress = 3700; //设置呼气流量系数 D1218呼流量系数 private readonly ushort _OutFowRateAddress = 1218; // 手动速度(D1218呼流量系数) //设置吸气流量系数 D1318呼流量系数 private readonly ushort _InFowRateAddress = 1318; // 手动速度(D1318呼流量系数) //设置压力系数 D1118 private readonly ushort _PressRateAddress = 1118; // 手动速度(D1118) //位置 private readonly ushort _PositionAddress = 0x002A; // D42 //压力 private readonly ushort _PressAddress = 0x0BD6; // 手动速度(D3030) //呼气流量 private readonly ushort _OutBreathAddress = 0x1398; // D5016 //吸气流量 private readonly ushort _InBreathAddress = 0x1396; // D5014 //复位 private readonly ushort _resetAddress = 0x0002; // D5014 #endregion // 定时器(按功能分组) private System.Timers.Timer _ReadTimer; // 实时监控数据 // Modbus通信 private TcpClient _tcpClient; private IModbusMaster _modbusMaster; private System.Timers.Timer resetTimer; // 启动状态实时定时器 string currentLang = LanguageManager.CurrentLanguage; #region 统计相关 private PlotModel _plotModel; private LineSeries _exhalationSeries; private LineSeries _inhalationSeries; private List _exhalationData; private List _inhalationData; private int _timeCounter; #region 私有字段(编辑状态+定时器+寄存器地址) // 编辑状态标志位(控制定时器是否更新) private bool _isEditingHandmovement; // 手动速度 private bool _isEditingMoisture; // 潮气量系数 private bool _isEditingOutFlow; // 呼气流量系数 private bool _isEditingInFlow; // 吸气流量系数 private bool _isEditingPress; // 压力系数 // 实时读取定时器(1个定时器管理5个参数) private System.Timers.Timer _paramReadTimer; // 下位机寄存器地址(根据实际PLC地址修改) //private readonly ushort _handmovementAddr = 0x0300; // 手动速度 //private readonly ushort _moistureAddr = 0x0301; // 潮气量系数 //private readonly ushort _outFlowAddr = 0x0302; // 呼气流量系数 //private readonly ushort _inFlowAddr = 0x0303; // 吸气流量系数 //private readonly ushort _pressAddr = 0x0304; // 压力系数 #endregion private void OnResetTimerElapsed(object sender, ElapsedEventArgs e) { try { bool[] result = _modbusMaster?.ReadCoils(0x01, 3, 1); bool isTestRunning = result != null && result.Length > 0 && result[0]; ResetBtn.Dispatcher.Invoke(() => { if (isTestRunning) { ResetBtn.Content = "复位成功"; ResetBtn.Foreground = Brushes.LightGreen; } else { if (LanguageManager.IsEnglish) { // 英文逻辑 ResetBtn.Content = "Reset"; } else if (LanguageManager.IsChinese) { // 中文逻辑 ResetBtn.Content = "复位"; } //ResetBtn.Content = "复位"; ResetBtn.Foreground = Brushes.White; } }); } catch (Exception ex) { Console.WriteLine($"读取线圈或更新UI失败:{ex.Message}"); } } #endregion public Window6() { InitializeComponent(); InitializeModbusTcp(); InitializePlot(); StartDataUpdate(); _paramReadTimer = new System.Timers.Timer(1000) { AutoReset = true, Enabled = true }; _paramReadTimer.Elapsed += OnParamTimerElapsed; // 绑定定时读取事件 resetTimer = CreateTimer(1000, OnResetTimerElapsed); Loaded += (s, e) => _paramReadTimer.Start(); //Hertbean(); } #region 定时器实时读取下位机数据(核心:根据编辑状态判断是否更新UI) private void OnParamTimerElapsed(object sender, ElapsedEventArgs e) { // 1. 手动速度(焦点不在时更新) if (!_isEditingHandmovement) { ReadAndUpdateParam( address: _handSpeedAddress, isFloat: true, updateAction: (value) => UpdateTextBox(handmovementTxt, value.ToString()) ); } // 2. 潮气量系数 if (!_isEditingMoisture) { ReadAndUpdateParam( address: _moistureAddress, isFloat: true, updateAction: (value) => UpdateTextBox(moistureTxt, value.ToString()) ); } // 3. 呼气流量系数 if (!_isEditingOutFlow) { ReadAndUpdateParam( address: _OutFowRateAddress, isFloat: true, updateAction: (value) => UpdateTextBox(OutFowRateTxt, value.ToString()) ); } // 4. 吸气流量系数 if (!_isEditingInFlow) { ReadAndUpdateParam( address: _InFowRateAddress, isFloat: true, updateAction: (value) => UpdateTextBox(InFowRateTxt, value.ToString()) ); } // 5. 压力系数 if (!_isEditingPress) { ReadAndUpdateParam( address: _PressRateAddress, isFloat: true, updateAction: (value) => UpdateTextBox(PressRateTxt, value.ToString()) ); } } #endregion // 读取下位机参数通用方法 private void ReadAndUpdateParam(ushort address, bool isFloat, Action updateAction) { if (!IsModbusConnected()) { //updateAction("离线"); //// 2. 直接判断是否是英文 if (LanguageManager.IsEnglish) { // 英文逻辑 updateAction("Offline"); } else if (LanguageManager.IsChinese) { // 中文逻辑 updateAction("离线"); } return; } try { ushort[] data = _modbusMaster?.ReadHoldingRegisters(0x01, address, isFloat ? (ushort)2 : (ushort)1); object value = isFloat ? Convert.ToSingle(c.UshortToFloat(data[1], data[0])) // 浮点数(需转换) : data[0]; // 整数 updateAction(value); } catch { updateAction("读取失败"); } } private void UpdateTextBox(TextBox textBox, string value) { Dispatcher.Invoke(() => { if (textBox.IsVisible) // 控件可见时才更新 { textBox.Text = value; } }); } private void InitializePlot() { _plotModel = new PlotModel { Title = "呼气流量与吸气流量", Background = OxyColor.FromRgb(240, 240, 240) // 设置背景色 }; _exhalationSeries = new LineSeries { Title = "呼气流量 (D5016)", Color = OxyColor.FromRgb(255, 0, 0), StrokeThickness = 2, // 设置线条宽度 MarkerType = MarkerType.Circle, // 添加标记 MarkerSize = 4 }; _inhalationSeries = new LineSeries { Title = "吸气流量 (D5014)", Color = OxyColor.FromRgb(0, 0, 255), StrokeThickness = 2, MarkerType = MarkerType.Circle, MarkerSize = 4 }; _exhalationData = new List(); _inhalationData = new List(); _plotModel.Series.Add(_exhalationSeries); _plotModel.Series.Add(_inhalationSeries); // 添加轴标签 _plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (秒)" }); _plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "流量 (单位)" }); // 在InitializePlot方法的轴配置中添加 _plotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (秒)", IsZoomEnabled = false, // 禁用手动缩放 IsPanEnabled = false, // 禁用手动平移 MaximumPadding = 0.1, // 轴最大值留10%余量 MinimumPadding = 0.1 // 轴最小值留10%余量 }); // 添加图例 _plotModel.IsLegendVisible = true; // 设置图例可见 plotView.Model = _plotModel; } private void StartDataUpdate() { DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; timer.Tick += async (s, e) => await UpdateData(); timer.Start(); } private async Task UpdateData() { if (!IsModbusConnected()) return; try { // 读取寄存器值(保持不变) ushort[] exhalationData = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(0x01, _OutBreathAddress, 2)); ushort[] inhalationData = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(0x01, _InBreathAddress, 2)); // 解析呼气流量(保持不变) ushort a = exhalationData[0]; ushort b = exhalationData[1]; float floatValue = c.UshortToFloat(b, a); floatValue = (float)Math.Round(floatValue, 2); // 解析吸气流量(保持不变) ushort a1 = inhalationData[0]; ushort b1 = inhalationData[1]; float floatValue1 = c.UshortToFloat(b1, a1); floatValue1 = (float)Math.Round(floatValue1, 2); double exhalationValue = floatValue; double inhalationValue = floatValue1; // 关键修改:添加新数据后,只保留最新的10个数据点 _exhalationData.Add(new DataPoint(_timeCounter, exhalationValue)); _inhalationData.Add(new DataPoint(_timeCounter, inhalationValue)); _timeCounter++; // 时间计数器统一递增(避免两条线时间轴不一致) // 限制数据列表长度为10(只保留最新数据) if (_exhalationData.Count > 10) { _exhalationData.RemoveRange(0, _exhalationData.Count - 10); // 移除旧数据 } if (_inhalationData.Count > 10) { _inhalationData.RemoveRange(0, _inhalationData.Count - 10); } // 更新图表数据(保持不变) _exhalationSeries.Points.Clear(); _inhalationSeries.Points.Clear(); foreach (var point in _exhalationData) { _exhalationSeries.Points.Add(point); } foreach (var point in _inhalationData) { _inhalationSeries.Points.Add(point); } _plotModel.InvalidatePlot(true); } catch (Exception ex) { Console.WriteLine($"读取数据失败: {ex.Message}"); } } /// /// 初始化Modbus连接和定时器 /// private void InitializeModbusTcp() { try { // 从配置读取PLC连接信息 string plcIp = ConfigurationManager.AppSettings["PLC2_IP"]; int plcPort = int.Parse(ConfigurationManager.AppSettings["PLC2_Port"]); _tcpClient = new TcpClient(plcIp, plcPort); _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient); _modbusMaster.Transport.ReadTimeout = 3000; _modbusMaster.Transport.WriteTimeout = 3000; fc = new Function(_modbusMaster); // 初始化定时器 InitializeTimers(); // 初始化数据库 //InitializeDatabase(); } catch (Exception ex) { ShowError($"Modbus初始化失败: {ex.Message}"); } } /// /// 统一初始化所有定时器(避免重复配置) /// private void InitializeTimers() { _ReadTimer = CreateTimer(1000, OnRealTimerElapsed); } /// /// /// private void OnRealTimerElapsed(object sender, ElapsedEventArgs e) { ReadAndUpdateDualRegister( _PositionAddress, _PressAddress, _OutBreathAddress, _InBreathAddress, (a, b, c, d) => UpdateTimerUI(a.ToString(), b.ToString(), c.ToString(), d.ToString()) ); } /// /// 更新呼吸计时UI /// private void UpdateTimerUI(string a, string b, string c, string d) { UpdateUiSafely(() => { positionTxt.Text = IsModbusConnected() ? a : "连接断开"; pressTxt.Text = IsModbusConnected() ? b : "连接断开"; OutFowTxt.Text = IsModbusConnected() ? c : "连接断开"; InFlowTxt.Text = IsModbusConnected() ? d : "连接断开"; }); } /// /// 线程安全的UI更新通用方法(统一实现) /// private void UpdateUiSafely(Action action) { if (action == null) return; if (Dispatcher.HasShutdownStarted) { return; } try { if (!Dispatcher.CheckAccess()) { Dispatcher.Invoke(action, TimeSpan.FromSeconds(2)); } else { action.Invoke(); } } catch (TaskCanceledException) { } catch (Exception ex) { Console.WriteLine($"UI更新失败:{ex.Message}"); } } /// /// 读取两个寄存器并更新UI(统一处理连接状态) /// private void ReadAndUpdateDualRegister(ushort address1, ushort address2, ushort address3, ushort address4, Action updateAction) { if (!IsModbusConnected()) { updateAction?.Invoke(0, 0, 0, 0); // 触发UI显示"连接断开" return; } try { ushort[] data1 = _modbusMaster?.ReadHoldingRegisters(0x01, address1, 2); ushort[] data2 = _modbusMaster?.ReadHoldingRegisters(0x01, address2, 2); ushort[] data3 = _modbusMaster?.ReadHoldingRegisters(0x01, address3, 2); ushort[] data4 = _modbusMaster?.ReadHoldingRegisters(0x01, address4, 2); // 2. 解析寄存器值(data[0]是D312,data[1]是D313) ushort a1 = data1[0]; // 高位寄存器值 ushort b1 = data1[1]; // 低位寄存器值 float floatValue1 = c.UshortToFloat(b1, a1); floatValue1 = (float)Math.Round(floatValue1, 2); // 2. 解析寄存器值(data[0]是D312,data[1]是D313) ushort a2 = data2[0]; // 高位寄存器值 ushort b2 = data2[1]; // 低位寄存器值 float floatValue2 = c.UshortToFloat(b2, a2); floatValue2 = (float)Math.Round(floatValue2, 2); // 2. 解析寄存器值(data[0]是D312,data[1]是D313) ushort a3 = data3[0]; // 高位寄存器值 ushort b3 = data3[1]; // 低位寄存器值 float floatValue3 = c.UshortToFloat(b3, a3); floatValue3 = (float)Math.Round(floatValue3, 2); // 2. 解析寄存器值(data[0]是D312,data[1]是D313) ushort a4 = data4[0]; // 高位寄存器值 ushort b4 = data4[1]; // 低位寄存器值 float floatValue4 = c.UshortToFloat(b4, a4); floatValue4 = (float)Math.Round(floatValue4, 2); updateAction?.Invoke(floatValue1, floatValue2, floatValue3, floatValue4); } catch (Exception ex) { Console.WriteLine($"读取寄存器[{address1:X4},{address2:X4}]失败: {ex.Message}"); updateAction?.Invoke(0, 0, 0, 0); // 触发UI显示"读取失败" } } /// /// 通用定时器创建方法(统一配置) /// private System.Timers.Timer CreateTimer(int intervalMs, ElapsedEventHandler elapsedAction) { var timer = new System.Timers.Timer(intervalMs) { AutoReset = true, Enabled = true }; timer.Elapsed += elapsedAction; return timer; } private void Button_Click(object sender, RoutedEventArgs e) { } private void Window_Loaded(object sender, RoutedEventArgs e) { try { string imagePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/sleep2.jpg"); if (System.IO.File.Exists(imagePath)) { Background = new ImageBrush { ImageSource = new BitmapImage(new Uri(imagePath, UriKind.Absolute)) }; } else { Console.WriteLine($"背景图片不存在: {imagePath}"); } } catch (Exception ex) { Console.WriteLine($"加载背景失败: {ex.Message}"); } } private void Button_Click_1(object sender, RoutedEventArgs e) { new Window5().ShowDialog(); Close(); } private async Task WriteRegisterWithValidation( TextBox inputControl, ushort registerAddress, float minValue, float maxValue) { if (!IsModbusConnected()) { ShowError("Modbus TCP 未连接"); return; } try { inputControl.Text = "操作中..."; Function ma = new Function(_modbusMaster); ma.WriteToPLCForNew("", registerAddress, Function.DataType.浮点型); //// 等待并刷新 //await Task.Delay(300); //ReadAndUpdateRegister(registerAddress, true, v => UpdatePressureUI(v.ToString())); } catch (Exception ex) { ShowError($"操作失败: {ex.Message}"); } finally { } } /// /// 写入单个寄存器 /// private async Task WriteSingleRegisterWithOutUI( ushort registerAddress, Func successMessage) { if (!IsModbusConnected()) { ShowError("Modbus TCP 未连接"); return; } try { await _modbusMaster.WriteSingleCoilAsync(0x01, registerAddress, true); await Task.Delay(100); // 等待PLC处理 await _modbusMaster.WriteSingleCoilAsync(0x01, registerAddress, false); await Task.Delay(100); // 等待PLC处理 //var data = _modbusMaster?.ReadHoldingRegisters(0x01, registerAddress, 1); //if (data != null && data.Length > 0 && data[0] == 1) //{ // ShowSuccess("写入成功,读取验证值为 1"); //} //else //{ // ShowSuccess("写入成功,但读取验证值异常,建议检查"); //} } catch (Exception ex) { ShowError($"设置失败: {ex.Message}"); } finally { } } /// /// 检查Modbus连接状态(统一判断逻辑) /// private bool IsModbusConnected() { return _modbusMaster != null && _tcpClient?.Connected == true; } // 消息提示封装(统一风格) private void ShowSuccess(string message) => MessageBox.Show(message, "成功", MessageBoxButton.OK, MessageBoxImage.Information); private void ShowWarning(string message) => MessageBox.Show(message, "提示", MessageBoxButton.OK, MessageBoxImage.Warning); private void ShowError(string message) => MessageBox.Show(message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); private void Button_Click_2(object sender, RoutedEventArgs e) { var mainWindow = MainWindow.Instance; // 检查窗口状态,只在窗口未显示时调用ShowDialog if (!mainWindow.IsVisible) { mainWindow.ShowDialog(); } else { // 如果窗口已显示,可将其激活到前台 mainWindow.Activate(); } Close(); } private void Button_Click_3(object sender, RoutedEventArgs e) { new ReportWindow5().ShowDialog(); Close(); } private async void Button_Click_4(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _OutBreathUpAddress, successMessage: value => $"呼上: {value}"); } private async void Button_Click_5(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _OutBreathDownAddress, successMessage: value => $"呼下: {value}"); } private async void Button_Click_6(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _InBreathUpAddress, successMessage: value => $"吸上: {value}"); } private async void Button_Click_7(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _InBreathDownAddress, successMessage: value => $"吸下: {value}"); } private async void Button_Click_8(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _HandInBreathUpAddress, successMessage: value => $"手动吸: {value}"); } private async void Button_Click_9(object sender, RoutedEventArgs e) { await WriteSingleRegisterWithOutUI( registerAddress: _HandInBreathDownAddress, successMessage: value => $"手动呼: {value}"); } private async void Button_Click_10(object sender, RoutedEventArgs e) { if (!IsModbusConnected()) { UpdateResetButtonStatus("连接断开", Brushes.Red); ShowError("Modbus TCP 未连接"); return; } try { UpdateResetButtonStatus("正在复位...", Brushes.LightGreen); // 写入复位线圈 await Task.Run(() => _modbusMaster.WriteSingleCoil(0x01, _resetAddress, true) ); fc.BtnClickFunctionForNew(Function.ButtonType.复位型, _resetAddress); await Task.Delay(100); // 写入复位线圈 await Task.Run(() => _modbusMaster.WriteSingleCoil(0x01, _resetAddress, false) ); fc.BtnClickFunctionForNew(Function.ButtonType.复位型, _resetAddress); UpdateResetButtonStatus("复位成功", Brushes.LightGreen); } catch (Exception ex) { Console.WriteLine($"复位异常: {ex.Message}"); UpdateResetButtonStatus("复位失败", Brushes.Red); ShowError($"操作异常: {ex.Message}"); } } /// /// 更新复位按钮状态UI /// private void UpdateResetButtonStatus(string text, Brush color) { UpdateUiSafely(() => { ResetBtn.Content = text; ResetBtn.Foreground = color; }); } private async void Button_Click_11(object sender, RoutedEventArgs e) { await WriteCoilWithCheck( coilAddress: _BreathUpAddress, value: true, successMsg: "校准指令已被设备接收并执行(二次验证通过)", failMsg: "校准执行超时,状态异常", logMsg: "校准指令执行成功"); } private async void Button_Click_12(object sender, RoutedEventArgs e) { await WriteCoilWithCheck( coilAddress: _BreathDownAddress, value: true, successMsg: "校准指令已被设备接收并执行(二次验证通过)", failMsg: "校准执行超时,状态异常", logMsg: "校准指令执行成功" ); } private async void Button_Click_13(object sender, RoutedEventArgs e) { await WriteCoilWithCheck( coilAddress: _PressCheckAddress, value: true, successMsg: "校准指令已被设备接收并执行(二次验证通过)", failMsg: "校准执行超时,状态异常", logMsg: "校准指令执行成功" ); } /// /// 写入线圈并验证状态 /// private async Task WriteCoilWithCheck( ushort coilAddress, bool value, string successMsg, string failMsg, string logMsg) { if (!IsModbusConnected()) { ShowError("Modbus TCP 未连接"); return; } try { // 写入线圈 await Task.Run(() => _modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, value) ); Thread.Sleep(200); if (failMsg != null && (failMsg.Contains("停止") || failMsg.Contains("校准"))) { // 写入线圈 await Task.Run(() => _modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, false) ); } Thread.Sleep(100); // 等待并验证 await Task.Delay(500); bool[] status = await _modbusMaster?.ReadCoilsAsync(0x01, coilAddress, 1); if (failMsg != null && !failMsg.Contains("停止") && !failMsg.Contains("校准")) { if (status[0] == value) { // 写入日志 WriteLog($"{logMsg} - 地址:{coilAddress},状态:{value}"); if (!string.IsNullOrEmpty(successMsg)) { ShowSuccess(successMsg); } } else { ShowError(failMsg); } } } catch (Exception ex) { ShowError($"通信错误: {ex.Message}"); } } /// /// 日志路径 /// private string logPath => System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modbus_log.txt"); /// /// 写入操作日志 /// private void WriteLog(string content) { try { string log = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {content}\r\n"; System.IO.File.AppendAllText(logPath, log); } catch (Exception ex) { Console.WriteLine($"写入日志失败: {ex.Message}"); } } //public void Hertbean() //{ // while (true) // { // try // { // if (!IsModbusConnected()) // { // 断线检测 // string plcIp = ConfigurationManager.AppSettings["PLC2_IP"]; // int plcPort = int.Parse(ConfigurationManager.AppSettings["PLC2_Port"]); // _tcpClient = new TcpClient(plcIp, plcPort); // _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient); // } // // 执行读写操作(如 master.ReadHoldingRegisters ) // Thread.Sleep(100); // 控制采集频率 // } // catch (Exception ex) // { // Console.WriteLine($"断线/异常: {ex.Message},尝试重连..."); // _tcpClient.Close(); // 清理旧连接 // Thread.Sleep(1000); // 间隔重连 // } // } //} private async void Button_Click_14(object sender, RoutedEventArgs e) { try { await WriteRegisterWithValidation( inputControl: handmovementTxt, registerAddress: _handSpeedAddress, // 手动速度寄存器地址(根据实际修改) minValue: 1, // 手动速度最小值 maxValue: 1000 // 手动速度最大值 ); } finally { } } private async void Button_Click_15(object sender, RoutedEventArgs e) { try { await WriteRegisterWithValidation( inputControl: moistureTxt, registerAddress: _moistureAddress, // 手动速度寄存器地址(根据实际修改) minValue: 1, // 手动速度最小值 maxValue: 1000 // 手动速度最大值 ); } finally { } } private async void Button_Click_16(object sender, RoutedEventArgs e) { try { await WriteRegisterWithValidation( inputControl: OutFowRateTxt, registerAddress: _OutFowRateAddress, // 手动速度寄存器地址(根据实际修改) minValue: 1, // 手动速度最小值 maxValue: 1000 // 手动速度最大值 ); } finally { } } private async void Button_Click_17(object sender, RoutedEventArgs e) { try { await WriteRegisterWithValidation( inputControl: InFowRateTxt, registerAddress: _InFowRateAddress, // 手动速度寄存器地址(根据实际修改) minValue: 1, // 手动速度最小值 maxValue: 1000 // 手动速度最大值 ); } finally { } } private async void Button_Click_18(object sender, RoutedEventArgs e) { try { await WriteRegisterWithValidation( inputControl: PressRateTxt, registerAddress: _PressRateAddress, // 手动速度寄存器地址(根据实际修改) minValue: 1, // 手动速度最小值 maxValue: 1000 // 手动速度最大值 ); } finally { } } } }