496 lines
16 KiB
C#
496 lines
16 KiB
C#
using Modbus.Device;
|
||
using P_RTU_TEST_WinForm;
|
||
using System.Configuration;
|
||
using System.Net.Http;
|
||
using System.Net.Sockets;
|
||
using System.Text;
|
||
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.Navigation;
|
||
using System.Windows.Shapes;
|
||
using System.Windows.Threading;
|
||
using 医用刨削器特征新版8;
|
||
using 软胶囊弹性硬度测试仪;
|
||
using 软胶囊弹性硬度测试仪.Data;
|
||
|
||
|
||
namespace EmptyLoadTest
|
||
{
|
||
/// <summary>
|
||
/// Interaction logic for MainWindow.xaml
|
||
/// </summary>
|
||
public partial class MainWindow : Window
|
||
{
|
||
|
||
#region 私有字段
|
||
|
||
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
||
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
||
|
||
|
||
|
||
private readonly DispatcherTimer _readTimer;
|
||
|
||
#endregion
|
||
|
||
软胶囊弹性硬度测试仪.Function ma;
|
||
DataChange c = new DataChange();
|
||
public MainWindow()
|
||
{
|
||
InitializeComponent();
|
||
InitializeModbusTcp();
|
||
_readTimer = InitDispatcherTimer();
|
||
}
|
||
|
||
private static MainWindow _instance;
|
||
public static MainWindow Instance
|
||
{
|
||
get
|
||
{
|
||
if (_instance == null || !_instance.IsLoaded)
|
||
{
|
||
_instance = new MainWindow();
|
||
}
|
||
return _instance;
|
||
}
|
||
}
|
||
|
||
private void InitializeModbusTcp()
|
||
{
|
||
try
|
||
{
|
||
|
||
//string plcIp = "192.168.1.10";
|
||
string plcIp = "127.0.0.1";
|
||
bool initSuccess = 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);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ShowError($"Modbus初始化失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
|
||
|
||
private DispatcherTimer InitDispatcherTimer()
|
||
{
|
||
var timer = new DispatcherTimer
|
||
{
|
||
Interval = TimeSpan.FromMilliseconds(50)
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (_modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadAddr262DataAsync();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
return timer;
|
||
}
|
||
|
||
private async System.Threading.Tasks.Task ReadAddr262DataAsync()
|
||
{
|
||
try
|
||
{
|
||
// 增强的空值检查和连接测试
|
||
if (_modbusMaster == null || _tcpClient == null)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine("Modbus客户端为空");
|
||
return;
|
||
}
|
||
|
||
// 测试连接是否真的可用
|
||
if (!_tcpClient.Connected)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine("TCP连接已断开");
|
||
// 尝试重新初始化
|
||
await Dispatcher.BeginInvoke(() => InitializeModbusTcp());
|
||
return;
|
||
}
|
||
|
||
// 创建任务列表
|
||
var tasks = new List<Task>
|
||
{
|
||
ReadAndUpdateFloatAsync(18, 1, intrval2, "F0", " "),
|
||
};
|
||
|
||
await Task.WhenAll(tasks);
|
||
}
|
||
catch (SocketException sockEx)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine($"Socket异常: {sockEx.Message}");
|
||
// 网络异常,尝试重新连接
|
||
await Dispatcher.BeginInvoke(() =>
|
||
{
|
||
MessageBox.Show("网络连接异常,尝试重新连接...", "提示",
|
||
MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
InitializeModbusTcp();
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
ShowError($"读取数据失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private async Task ReadAndUpdateFloatAsync(int address, int length, System.Windows.Controls.TextBox control, string format, string unit)
|
||
{
|
||
try
|
||
{
|
||
// 添加空值检查
|
||
if (_modbusMaster == null || _tcpClient == null || !_tcpClient.Connected)
|
||
{
|
||
return;
|
||
}
|
||
ushort[] registers = await Task.Run(async () =>
|
||
await _modbusMaster?.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
||
);
|
||
|
||
if (registers != null && registers.Length >= 2)
|
||
{
|
||
float value = c.UshortToFloat(registers[1], registers[0]);
|
||
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
||
}
|
||
else if (registers != null && registers.Length >= 1)
|
||
{
|
||
int value = registers[0];
|
||
Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private void settingspeed_GotFocus(object sender, RoutedEventArgs e)
|
||
{
|
||
string dd = settingspeed.Text.Trim();
|
||
//ma.WriteToPLCForNew(settingspeed.Text.Trim(), 1334, Function.DataType.浮点型);
|
||
//System.Threading.Tasks.Task.Delay(50);
|
||
//_isManualInput = false; // 写入后恢复读取
|
||
//t0.Focus();
|
||
}
|
||
|
||
int i = 1;
|
||
private void Button_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
|
||
try
|
||
{
|
||
|
||
// 1. 获取文本框值(去除首尾空格,避免空值)
|
||
string speed = settingspeed.Text?.Trim() ?? string.Empty;
|
||
string speed2 = actualspeed.Text?.Trim() ?? string.Empty;
|
||
string interval2 = interval.Text?.Trim() ?? string.Empty;
|
||
// 校验值(可选,根据业务需求调整)
|
||
if (string.IsNullOrEmpty(speed) || string.IsNullOrEmpty(speed2))
|
||
{
|
||
MessageBox.Show("速度值不能为空!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
return;
|
||
}
|
||
|
||
if (i > 3)
|
||
i = 1;
|
||
// 2. 读取配置文件(App.config)
|
||
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||
|
||
// 3. 写入/更新配置项
|
||
// 配置项1:设置速度(键名可自定义,如 "SettingSpeed")
|
||
if (config.AppSettings.Settings["SettingSpeed"] == null)
|
||
{
|
||
// 配置项不存在则新增
|
||
config.AppSettings.Settings.Add("SettingSpeed", speed);
|
||
}
|
||
else
|
||
{
|
||
// 配置项已存在则更新值
|
||
config.AppSettings.Settings["SettingSpeed"].Value = speed;
|
||
}
|
||
|
||
|
||
// 配置项2:实际速度(键名:"ActualSpeed")
|
||
if (config.AppSettings.Settings["interval"] == null)
|
||
{
|
||
config.AppSettings.Settings.Add("interval", interval2);
|
||
}
|
||
else
|
||
{
|
||
config.AppSettings.Settings["interval"].Value = interval2;
|
||
}
|
||
|
||
if (i == 1)
|
||
{
|
||
config.AppSettings.Settings["ActualSpeed1"].Value = speed2;
|
||
}
|
||
else if (i == 2)
|
||
{
|
||
config.AppSettings.Settings["ActualSpeed2"].Value = speed2;
|
||
}
|
||
else if (i == 3)
|
||
{
|
||
config.AppSettings.Settings["ActualSpeed3"].Value = speed2;
|
||
}
|
||
|
||
status.Text = i.ToString();
|
||
// 4. 保存配置更改(关键:不调用Save则修改不生效)
|
||
config.Save(ConfigurationSaveMode.Modified);
|
||
// 刷新配置管理器,让后续读取能获取最新值
|
||
ConfigurationManager.RefreshSection("appSettings");
|
||
if (i == 3)
|
||
{
|
||
MessageBox.Show("3次记录已保存");
|
||
}
|
||
i++;
|
||
}
|
||
catch (ConfigurationErrorsException ex)
|
||
{
|
||
// 捕获配置文件操作异常(如权限不足、文件损坏)
|
||
MessageBox.Show($"配置文件写入失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 捕获其他异常
|
||
MessageBox.Show($"保存失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void intrval2_GotFocus(object sender, RoutedEventArgs e)
|
||
{
|
||
ma.WriteToPLCForNew(intrval2.Text.Trim(), 18, 软胶囊弹性硬度测试仪.Function.DataType.整形);
|
||
System.Threading.Tasks.Task.Delay(50);
|
||
t0.Focus();
|
||
}
|
||
|
||
private void Button_Click_1(object sender, RoutedEventArgs e)
|
||
{
|
||
ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 200);
|
||
}
|
||
|
||
private void Button_Click_2(object sender, RoutedEventArgs e)
|
||
{
|
||
ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 200);
|
||
}
|
||
|
||
|
||
|
||
int j = 1;
|
||
private void Button_Click_4(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
|
||
|
||
string interval_ = interval.Text?.Trim() ?? string.Empty;
|
||
|
||
string interval2_ = intrval2.Text?.Trim() ?? string.Empty;
|
||
|
||
if (j > 3)
|
||
j = 1;
|
||
// 2. 读取配置文件(App.config)
|
||
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||
|
||
|
||
|
||
// 配置项2:实际速度(键名:"ActualSpeed")
|
||
if (config.AppSettings.Settings["interval"] == null)
|
||
{
|
||
config.AppSettings.Settings.Add("interval", interval_);
|
||
}
|
||
else
|
||
{
|
||
config.AppSettings.Settings["interval"].Value = interval_;
|
||
}
|
||
|
||
|
||
|
||
if (j == 1)
|
||
{
|
||
config.AppSettings.Settings["interval1"].Value = interval2_;
|
||
}
|
||
else if (j == 2)
|
||
{
|
||
config.AppSettings.Settings["interval2"].Value = interval2_;
|
||
}
|
||
else if (j == 3)
|
||
{
|
||
config.AppSettings.Settings["interval3"].Value = interval2_;
|
||
}
|
||
status.Text = j.ToString();
|
||
// 4. 保存配置更改(关键:不调用Save则修改不生效)
|
||
config.Save(ConfigurationSaveMode.Modified);
|
||
// 刷新配置管理器,让后续读取能获取最新值
|
||
ConfigurationManager.RefreshSection("appSettings");
|
||
if (j == 3)
|
||
{
|
||
MessageBox.Show("3次记录已保存");
|
||
}
|
||
j++;
|
||
|
||
}
|
||
catch (ConfigurationErrorsException ex)
|
||
{
|
||
// 捕获配置文件操作异常(如权限不足、文件损坏)
|
||
MessageBox.Show($"配置文件写入失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 捕获其他异常
|
||
MessageBox.Show($"保存失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
|
||
private void LoadTestMenuItem_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
var mainWindow = EmergencyStopWindow.Instance;
|
||
|
||
// 检查窗口状态,只在窗口未显示时调用ShowDialog
|
||
if (!mainWindow.IsVisible)
|
||
{
|
||
mainWindow.Show();
|
||
}
|
||
else
|
||
{
|
||
// 如果窗口已显示,可将其激活到前台
|
||
mainWindow.Activate();
|
||
}
|
||
|
||
Close();
|
||
}
|
||
|
||
private void ReportMenuItem_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
|
||
var mainWindow = ExperimentReportWindow.Instance;
|
||
|
||
// 检查窗口状态,只在窗口未显示时调用ShowDialog
|
||
if (!mainWindow.IsVisible)
|
||
{
|
||
mainWindow.Show();
|
||
}
|
||
else
|
||
{
|
||
// 如果窗口已显示,可将其激活到前台
|
||
mainWindow.Activate();
|
||
}
|
||
|
||
Close();
|
||
|
||
}
|
||
|
||
private void MenuItem_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 停止所有定时器
|
||
_readTimer?.Stop();
|
||
|
||
|
||
// 关闭Modbus连接
|
||
if (_modbusMaster != null)
|
||
{
|
||
_modbusMaster.Dispose();
|
||
}
|
||
|
||
// 关闭TCP连接
|
||
if (_tcpClient != null && _tcpClient.Connected)
|
||
{
|
||
_tcpClient.Close();
|
||
}
|
||
|
||
// 如果是主窗口,退出程序
|
||
Application.Current.Shutdown();
|
||
|
||
// 或者关闭当前窗口
|
||
// this.Close();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"退出程序时出错:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||
{
|
||
_readTimer?.Start();
|
||
|
||
|
||
|
||
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||
|
||
settingspeed.Text = config.AppSettings.Settings["SettingSpeed"].Value;
|
||
|
||
actualspeed.Text = config.AppSettings.Settings["ActualSpeed1"].Value;
|
||
|
||
interval.Text = config.AppSettings.Settings["ActualSpeed1"].Value;
|
||
}
|
||
|
||
private void Button_Click_3(object sender, RoutedEventArgs e)
|
||
{
|
||
var mainWindow = TorqueParameterWindow.Instance;
|
||
|
||
// 检查窗口状态,只在窗口未显示时调用ShowDialog
|
||
if (!mainWindow.IsVisible)
|
||
{
|
||
mainWindow.Show();
|
||
}
|
||
else
|
||
{
|
||
// 如果窗口已显示,可将其激活到前台
|
||
mainWindow.Activate();
|
||
}
|
||
|
||
Close();
|
||
}
|
||
|
||
private void JumpingTest_Click(object sender, RoutedEventArgs e)
|
||
{
|
||
|
||
|
||
|
||
// WPF 跳转到 WinForm 窗口
|
||
var mainWindow = MainForm.Instance;
|
||
|
||
// WinForm 用:IsHandleCreated 替代 IsVisible
|
||
if (!mainWindow.IsHandleCreated)
|
||
{
|
||
// 关键:WinForm 窗口必须用 Show() 不能用 ShowDialog()
|
||
mainWindow.Show();
|
||
}
|
||
else
|
||
{
|
||
mainWindow.Activate();
|
||
}
|
||
|
||
// this.Close();
|
||
}
|
||
}
|
||
} |