2026-03-11 15:21:27 +08:00
|
|
|
|
using Modbus.Device;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Configuration;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
|
|
|
|
|
using System.Windows.Input;
|
|
|
|
|
|
using System.Windows.Threading;
|
2026-03-16 11:17:49 +08:00
|
|
|
|
using System.Windows.Media.Animation;
|
2026-03-11 15:21:27 +08:00
|
|
|
|
using 自救器呼吸器综合检验仪.Data;
|
|
|
|
|
|
|
|
|
|
|
|
namespace 自救器呼吸器综合检验仪
|
|
|
|
|
|
{
|
|
|
|
|
|
public partial class ParameterSettingsWindow : Window
|
|
|
|
|
|
{
|
|
|
|
|
|
private MainWindow _mainWindow;
|
|
|
|
|
|
private MainWindow2 _mainWindow2;
|
|
|
|
|
|
private MainWindow3 _mainWindow3;
|
|
|
|
|
|
private MainWindow4 _mainWindow4;
|
|
|
|
|
|
private readonly DispatcherTimer _readTimer;
|
|
|
|
|
|
private bool _isManualInput = false; // 手动输入标记:true=输入中(暂停读取),false=正常读取
|
|
|
|
|
|
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
|
|
|
|
|
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
|
|
|
|
|
Function ma;
|
|
|
|
|
|
DataChange c = new DataChange();
|
|
|
|
|
|
public ParameterSettingsWindow()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
LoadCurrentSettings();
|
|
|
|
|
|
_readTimer = InitDispatcherTimer();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private DispatcherTimer InitDispatcherTimer()
|
|
|
|
|
|
{
|
|
|
|
|
|
var timer = new DispatcherTimer
|
|
|
|
|
|
{
|
|
|
|
|
|
Interval = TimeSpan.FromMilliseconds(500)
|
|
|
|
|
|
};
|
|
|
|
|
|
timer.Tick += async (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!_isManualInput && _modbusMaster != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await ReadAllPlcDataAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
return timer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async System.Threading.Tasks.Task ReadAllPlcDataAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 仅在非手动输入时读取设置地址(避免覆盖输入)
|
|
|
|
|
|
if (!_isManualInput)
|
|
|
|
|
|
{
|
|
|
|
|
|
await ReadAddr262DataAsync();
|
|
|
|
|
|
//await System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
|
|
|
|
|
|
//await ReadAddr404DataAsync();
|
|
|
|
|
|
//await System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
|
|
|
|
|
|
//await ReadAddr406DataAsync();
|
|
|
|
|
|
//await System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
//await ReadAddr130DataAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载当前设置
|
|
|
|
|
|
private void LoadCurrentSettings()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 这里可以连接实际的数据源来加载当前设置
|
|
|
|
|
|
// 目前使用默认值
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存按钮点击事件
|
|
|
|
|
|
//private void SaveButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// try
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 验证并保存所有参数
|
|
|
|
|
|
// if (ValidateParameters())
|
|
|
|
|
|
// {
|
|
|
|
|
|
// SaveParameters();
|
|
|
|
|
|
// MessageBox.Show("参数保存成功!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// catch (Exception ex)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// MessageBox.Show($"保存参数时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
// 重置按钮点击事件
|
|
|
|
|
|
private void ResetButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var result = MessageBox.Show("确定要重置所有参数吗?", "确认重置",
|
|
|
|
|
|
MessageBoxButton.YesNo, MessageBoxImage.Question);
|
|
|
|
|
|
|
|
|
|
|
|
if (result == MessageBoxResult.Yes)
|
|
|
|
|
|
{
|
|
|
|
|
|
ResetToDefaults();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 返回按钮点击事件
|
|
|
|
|
|
private void ReturnButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
SwitchWindow(ref _mainWindow, () => new MainWindow());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
|
|
|
|
|
|
{
|
2026-03-16 11:17:49 +08:00
|
|
|
|
// 停止当前窗口的定时器(不释放资源)
|
2026-03-11 15:21:27 +08:00
|
|
|
|
_readTimer?.Stop();
|
|
|
|
|
|
|
|
|
|
|
|
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
|
|
|
|
|
{
|
2026-03-16 11:17:49 +08:00
|
|
|
|
if (!TryReconnect())
|
2026-03-11 15:21:27 +08:00
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("TCP连接已断开,请重新连接!", "提示");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-16 11:17:49 +08:00
|
|
|
|
void ShowTargetWindow(T target)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (target.IsVisible)
|
|
|
|
|
|
{
|
|
|
|
|
|
target.Activate();
|
|
|
|
|
|
this.Hide();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
target.Opacity = 0;
|
|
|
|
|
|
void OnContentRendered(object s, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
target.ContentRendered -= OnContentRendered;
|
|
|
|
|
|
var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
|
|
|
|
|
|
target.BeginAnimation(Window.OpacityProperty, anim);
|
|
|
|
|
|
this.Hide();
|
|
|
|
|
|
target.Activate();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
target.ContentRendered += OnContentRendered;
|
|
|
|
|
|
target.Show();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-11 15:21:27 +08:00
|
|
|
|
if (windowInstance == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
windowInstance = createFunc();
|
|
|
|
|
|
windowInstance.Closed += (s, args) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
_readTimer?.Start();
|
|
|
|
|
|
this.Show();
|
|
|
|
|
|
this.Activate();
|
|
|
|
|
|
};
|
2026-03-16 11:17:49 +08:00
|
|
|
|
|
|
|
|
|
|
ShowTargetWindow(windowInstance);
|
2026-03-11 15:21:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-03-16 11:17:49 +08:00
|
|
|
|
ShowTargetWindow(windowInstance);
|
2026-03-11 15:21:27 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加重连方法
|
|
|
|
|
|
private bool TryReconnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
string plcIp = "192.168.1.10";
|
|
|
|
|
|
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
|
|
|
|
|
|
if (initSuccess)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma = new Function(_modbusMaster);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowErrorMsg($"重新连接失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
ushort[] registers3 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 1428, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers3 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers3[1], registers3[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtPressureDiffCoefficient.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers4 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 484, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers4 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers4[1], registers4[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtUpperLimit.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers5 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 482, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers5 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers5[1], registers5[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtLowerLimit.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers6 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 490, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers6 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers6[1], registers6[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtLargeFlowCoefficient2.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers7 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 492, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers7 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers7[1], registers7[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtSmallFlowCoefficient2.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers8 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 1328, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers8 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers8[1], registers8[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtLargeFlowCoefficient.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers9 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 1378, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers9 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers9[1], registers9[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtSmallFlowCoefficient.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers10 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 308, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers10 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers10[1], registers10[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtQualityThreshold.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers11 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 330, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers11 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int addr406Value = registers11[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtExhaustTime.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers12 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 326, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers12 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//float addr406Value = c.UshortToFloat(registers12[1], registers12[0]);
|
|
|
|
|
|
int addr406Value = registers12[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtPositiveError.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers13 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 316, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers13 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
//float addr406Value = c.UshortToFloat(registers13[1], registers13[0]);
|
|
|
|
|
|
float addr406Value = registers13[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtNegativeError.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers14 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 324, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers14 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int addr406Value = registers14[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtPositivePIDTime.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers15 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 314, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers15 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int addr406Value = registers15[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtNegativePIDTime.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers16 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 328, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers16 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int addr406Value = registers16[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtPositiveDelay.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers17 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 318, 1)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers17 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
int addr406Value = registers17[0];
|
|
|
|
|
|
Dispatcher.Invoke(() => txtNegativeDelay.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers18 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 292, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers18 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers18[1], registers18[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtPositivePIDPressure.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers19 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 290, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers19 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers19[1], registers19[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => txtNegativePIDPressure.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers20 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 1430, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers20 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers20[1], registers20[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => pressureDiff.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ushort[] registers21 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
_modbusMaster?.ReadHoldingRegisters(1, 1330, 2)
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (registers21 != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float addr406Value = c.UshortToFloat(registers21[1], registers21[0]);
|
|
|
|
|
|
Dispatcher.Invoke(() => flow.Text = addr406Value.ToString("F2"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ushort[] registers22 = await System.Threading.Tasks.Task.Run(() =>
|
|
|
|
|
|
//_modbusMaster?.ReadHoldingRegisters(1, 390, 2)
|
|
|
|
|
|
//);
|
|
|
|
|
|
|
|
|
|
|
|
// if (registers22 != null)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// int addr406Value = registers22[0];
|
|
|
|
|
|
// Dispatcher.Invoke(() => setsound.Text = addr406Value.ToString("F0"));
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
//ShowErrorMsg($"读取地址406失败:{ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowErrorMsg(string msg)
|
|
|
|
|
|
{
|
|
|
|
|
|
Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
string plcIp = "192.168.1.10";
|
|
|
|
|
|
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
|
|
|
|
|
|
if (!initSuccess)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("连接Modbus服务器失败!", "错误");
|
|
|
|
|
|
this.Close();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查连接状态
|
|
|
|
|
|
if (_tcpClient == null || !_tcpClient.Connected)
|
|
|
|
|
|
{
|
|
|
|
|
|
MessageBox.Show("Modbus连接异常!", "错误");
|
|
|
|
|
|
this.Close();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ma = new Function(_modbusMaster);
|
|
|
|
|
|
//ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 64);
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_readTimer.Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 停止定时器
|
|
|
|
|
|
_readTimer?.Stop();
|
|
|
|
|
|
|
|
|
|
|
|
// 停止ViewModel的定时器
|
|
|
|
|
|
if (DataContext is MainViewModel viewModel)
|
|
|
|
|
|
{
|
|
|
|
|
|
viewModel.StopTimer();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 释放Modbus资源
|
|
|
|
|
|
ModbusResourceManager.Instance?.Dispose();
|
|
|
|
|
|
|
|
|
|
|
|
// 确保应用程序完全退出
|
|
|
|
|
|
Application.Current.Shutdown();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void Window_Closed(object sender, EventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 清理其他窗口实例
|
|
|
|
|
|
_mainWindow?.Close();
|
|
|
|
|
|
_mainWindow2?.Close();
|
|
|
|
|
|
_mainWindow3?.Close();
|
|
|
|
|
|
//_mainWindow4?.Close();
|
|
|
|
|
|
|
|
|
|
|
|
_mainWindow4?.Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 重置为默认值
|
|
|
|
|
|
private void ResetToDefaults()
|
|
|
|
|
|
{
|
|
|
|
|
|
txtPressureDiffCoefficient.Text = "0.00";
|
|
|
|
|
|
txtUpperLimit.Text = "0.0";
|
|
|
|
|
|
txtLowerLimit.Text = "0.0";
|
|
|
|
|
|
txtLargeFlowCoefficient.Text = "0.00";
|
|
|
|
|
|
txtSmallFlowCoefficient.Text = "0.00";
|
|
|
|
|
|
//txtYear.Text = "0";
|
|
|
|
|
|
//txtMonth.Text = "0";
|
|
|
|
|
|
//txtDay.Text = "0";
|
|
|
|
|
|
//txtHour.Text = "0";
|
|
|
|
|
|
//txtMinute.Text = "0";
|
|
|
|
|
|
//txtSecond.Text = "0";
|
|
|
|
|
|
txtQualityThreshold.Text = "0.00";
|
|
|
|
|
|
txtExhaustTime.Text = "0";
|
|
|
|
|
|
txtPositiveError.Text = "0";
|
|
|
|
|
|
txtNegativeError.Text = "0";
|
|
|
|
|
|
txtPositivePIDTime.Text = "0";
|
|
|
|
|
|
txtNegativePIDTime.Text = "0";
|
|
|
|
|
|
txtPositiveDelay.Text = "0";
|
|
|
|
|
|
txtNegativeDelay.Text = "0";
|
|
|
|
|
|
txtPositivePIDPressure.Text = "0.00";
|
|
|
|
|
|
txtNegativePIDPressure.Text = "0.00";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPressureDiffCoefficient_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPressureDiffCoefficient.Text.Trim(), 1428, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 1301);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtLargeFlowCoefficient2_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtLargeFlowCoefficient2.Text.Trim(), 490, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtSmallFlowCoefficient2_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtSmallFlowCoefficient2.Text.Trim(), 492, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPressureDiffCoefficient_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPressureDiffCoefficient.Text.Trim(), 1428, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtUpperLimit_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtUpperLimit.Text.Trim(), 484, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtLowerLimit_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtLowerLimit.Text.Trim(), 482, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtLargeFlowCoefficient_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtLargeFlowCoefficient.Text.Trim(), 1328, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtSmallFlowCoefficient_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtSmallFlowCoefficient.Text.Trim(), 1378, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click_1(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 1300);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtQualityThreshold_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtQualityThreshold.Text.Trim(), 308, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtExhaustTime_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtExhaustTime.Text.Trim(), 330, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPositiveError_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPositiveError.Text.Trim(), 326, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//private async void Button_Click_2(object sender, RoutedEventArgs e)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 24);
|
|
|
|
|
|
// bool[] b = await _modbusMaster.ReadCoilsAsync(1, 24, 1);
|
|
|
|
|
|
// if (b != null && b.Length > 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (!b[0])
|
|
|
|
|
|
// {
|
|
|
|
|
|
// closesound.Content = "关闭语音";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// closesound.Content = "开启语音";
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
private void Button_Click_3(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 25);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//private void setsound_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// ma.WriteToPLCForNew(setsound.Text.Trim(), 390, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
// System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
// _isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
// t0.Focus();
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void txtNegativeError_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtNegativeError.Text.Trim(), 316, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPositivePIDTime_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPositivePIDTime.Text.Trim(), 324, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtNegativePIDTime_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtNegativePIDTime.Text.Trim(), 314, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPositiveDelay_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPositiveDelay.Text.Trim(), 328, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtNegativeDelay_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtNegativeDelay.Text.Trim(), 318, Function.DataType.整形);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtPositivePIDPressure_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtPositivePIDPressure.Text.Trim(), 292, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void txtNegativePIDPressure_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
ma.WriteToPLCForNew(txtNegativePIDPressure.Text.Trim(), 290, Function.DataType.浮点型);
|
|
|
|
|
|
|
|
|
|
|
|
System.Threading.Tasks.Task.Delay(50);
|
|
|
|
|
|
_isManualInput = false; // 写入后恢复读取
|
|
|
|
|
|
t0.Focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//private void pressureDiff2_GotFocus(object sender, RoutedEventArgs e)
|
|
|
|
|
|
//{
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 保存 AppSettings 配置到配置文件
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="key">配置键名</param>
|
|
|
|
|
|
/// <param name="value">配置值</param>
|
|
|
|
|
|
/// <returns>是否保存成功</returns>
|
|
|
|
|
|
public bool SaveAppSetting(string key, string value)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. 获取当前程序的配置文件路径(编译后的 exe.config)
|
|
|
|
|
|
string configPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 加载配置文件(ExeConfigurationFileMap 指定配置路径)
|
|
|
|
|
|
ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap { ExeConfigFilename = configPath };
|
|
|
|
|
|
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 处理 appSettings 节点
|
|
|
|
|
|
if (config.AppSettings.Settings[key] == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 键不存在 → 新增配置
|
|
|
|
|
|
config.AppSettings.Settings.Add(key, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// 键已存在 → 更新配置
|
|
|
|
|
|
config.AppSettings.Settings[key].Value = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 保存配置(重要!否则修改不生效)
|
|
|
|
|
|
config.Save(ConfigurationSaveMode.Modified);
|
|
|
|
|
|
|
|
|
|
|
|
// 5. 刷新 ConfigurationManager 缓存(可选,让后续读取能立即获取新值)
|
|
|
|
|
|
ConfigurationManager.RefreshSection("appSettings");
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 捕获异常(如权限不足、文件被占用等)
|
|
|
|
|
|
MessageBox.Show($"保存配置失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|