Files
FullAutoWaterCheck/全自动水压检测仪/Coeffiicientsetting.cs

435 lines
16 KiB
C#
Raw Normal View History

2026-01-07 13:42:17 +08:00
using Modbus.Device;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
2026-01-16 12:00:20 +08:00
using System.Diagnostics;
2026-01-07 13:42:17 +08:00
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ;
using .Data;
using .DATA;
namespace
{
public partial class Coeffiicientsetting : UIForm
{
private NormalTemperatureMode _normalTemperatureMode;
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
Function ma;
DataChange c;
private System.Windows.Forms.Timer _readTimer;
private bool _isManualInput = false; // 手动输入标记
private bool _isSwitchingWindow = false; // 窗口切换标记,避免并发
private CancellationTokenSource _cts; // 取消令牌,用于异步操作终止
public Coeffiicientsetting()
{
InitializeComponent();
_cts = new CancellationTokenSource();
2026-01-16 16:56:03 +08:00
// 只创建定时器,不在构造器中启动,避免在 Load 前访问未初始化的资源(如 c / _modbusMaster
_readTimer = InitTimer(); // 初始化定时器并保存引用
2026-01-07 13:42:17 +08:00
}
private System.Windows.Forms.Timer InitTimer()
{
var timer = new System.Windows.Forms.Timer()
{
Interval = 1000
};
timer.Tick += async (s, e) =>
{
if (!_isManualInput && _modbusMaster != null)
{
try
{
await ReadLeakTestParametersAsync();
}
catch { }
}
};
2026-01-16 16:56:03 +08:00
// 不在此处 Start等待 Load 完成后再 Start()
2026-01-07 13:42:17 +08:00
return timer;
}
private class RegisterConfig
{
public ushort Address { get; set; } // Modbus寄存器地址ushort类型匹配方法参数
public UITextBox TextBox { get; set; } // 适配SunnyUI的UITextBox控件
public string Format { get; set; } // 数值格式化字符串
public bool IsInteger { get; set; } // 是否为整数类型(新增)
}
private async Task ReadLeakTestParametersAsync()
{
// 前置校验:连接状态检查
2026-01-16 15:11:12 +08:00
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) return;
2026-01-16 16:56:03 +08:00
// 确保 UI 已可用
if (!this.IsHandleCreated || this.IsDisposed) return;
2026-01-07 13:42:17 +08:00
try
{
var registerConfigs = new List<RegisterConfig>
{
2026-01-16 15:11:12 +08:00
CreateRegisterConfig(2394, uiTextBox1, "F2",false), // 控制压力系数
CreateRegisterConfig(3134, uiTextBox3, "F2",false), // 压力保护输入
2026-01-16 16:52:10 +08:00
//CreateRegisterConfig(2376, uiTextBox2, "F2",false), // 压力上限
//CreateRegisterConfig(2374, uiTextBox4, "F2",false), // 压力下限
2026-01-16 15:11:12 +08:00
CreateRegisterConfig(3482, uiTextBox8, "F2",false), // 温度系数
CreateRegisterConfig(3176, uiTextBox6, "F2",false), // 出口温度系数
CreateRegisterConfig(3076, uiTextBox7, "F2",false), // 常温液位系数
CreateRegisterConfig(3086, uiTextBox9, "F2",false), // 常温液位上限
CreateRegisterConfig(3084, uiTextBox10, "F2",false), // 常温液位下限
CreateRegisterConfig(3026, uiTextBox12, "F2",false), // 高温液位系数
CreateRegisterConfig(3036, uiTextBox11, "F2",false), // 高温液位上限
CreateRegisterConfig(3034, uiTextBox5, "F2",false), // 高温液位下限
CreateRegisterConfig(2300, uiTextBox17, "F2",false), // 转速
2026-01-16 18:46:24 +08:00
CreateRegisterConfig(2402, uiTextBox16, "F2",false), // 温度
2026-01-16 15:11:12 +08:00
CreateRegisterConfig(2408, uiTextBox14, "0",true), // 稳压时间
CreateRegisterConfig(2406, uiTextBox15, "0",true), // 通水时间
CreateRegisterConfig(2410, uiTextBox13, "0",true), // 排空时间
2026-01-16 16:52:10 +08:00
CreateRegisterConfig(2414, uiTextBox2, "0",true), // 延迟记录初始值时间
2026-01-16 18:46:24 +08:00
2026-01-07 13:42:17 +08:00
};
// 批量处理所有寄存器读取和UI更新
foreach (var config in registerConfigs)
{
await ReadRegisterAndUpdateUIAsync(config);
}
2026-01-16 12:00:20 +08:00
await ReadButtonStatusAsync();
2026-01-07 13:42:17 +08:00
}
catch (Exception ex)
{
2026-01-16 16:56:03 +08:00
_readTimer?.Stop();
UIMessageBox.ShowError($"读取系数失败:{ex.Message}");
2026-01-07 13:42:17 +08:00
}
}
private RegisterConfig CreateRegisterConfig(int address, UITextBox textBox, string format, bool isInteger)
{
var config = new RegisterConfig();
config.Address = (ushort)address; // 显式转换为ushort解决类型不匹配
config.TextBox = textBox;
config.Format = format;
config.IsInteger = isInteger; // 赋值整数类型标识
return config;
}
/// <summary>
/// 通用方法读取寄存器并更新SunnyUI文本框核心逻辑复用
/// </summary>
/// <param name="config">寄存器配置</param>
private async Task ReadRegisterAndUpdateUIAsync(RegisterConfig config)
{
ushort[] registers = await Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, config.Address, 2));
if (registers != null && registers.Length >= 2)
{
this.Invoke(new Action(() =>
{
if (config.IsInteger)
{
int intValue = (registers[1] << 16) | registers[0];
config.TextBox.Text = intValue.ToString(config.Format);
}
else
{
float floatValue = c.UshortToFloat(registers[1], registers[0]);
config.TextBox.Text = floatValue.ToString(config.Format);
}
}));
}
}
2026-01-16 12:00:20 +08:00
private async Task ReadButtonStatusAsync()
{
try
{
// 读取水循环状态 - 地址0
bool[] waterStatus = await Task.Run(() =>
2026-01-16 15:11:12 +08:00
_modbusMaster?.ReadCoils(1, 10000, 1));
2026-01-16 12:00:20 +08:00
// 读取恒压启动状态 - 地址110
bool[] pressureStatus = await Task.Run(() =>
2026-01-16 15:11:12 +08:00
_modbusMaster?.ReadCoils(1, 10110, 1));
2026-01-16 12:00:20 +08:00
this.Invoke(new Action(() =>
{
// 更新水循环按钮
if (waterStatus != null && waterStatus.Length > 0)
{
bool isWaterOn = waterStatus[0];
uiButton2.ForeColor = isWaterOn ? Color.Red : Color.White;
uiButton2.Text = isWaterOn ? "水循环中" : "水循环";
}
// 更新恒压启动按钮
if (pressureStatus != null && pressureStatus.Length > 0)
{
bool isPressureOn = pressureStatus[0];
uiButton3.ForeColor = isPressureOn ? Color.Red : Color.White;
uiButton3.Text = isPressureOn ? "恒压启动中" : "恒压启动";
}
}));
}
2026-01-16 16:56:03 +08:00
catch (Exception ex)
2026-01-16 12:00:20 +08:00
{
Debug.WriteLine($"[错误] 更新按钮状态失败: {ex.Message}");
}
}
2026-01-07 13:42:17 +08:00
private void Coeffiicientsetting_Load(object sender, EventArgs e)
{
2026-01-16 18:46:24 +08:00
string plcIp = "192.168.1.10";
//string plcIp = "127.0.0.1";
2026-01-07 13:42:17 +08:00
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);
c = new DataChange();
2026-01-16 16:56:03 +08:00
// 在 Load 完成 Modbus 初始化与 DataChange 初始化后再启动读定时器
_readTimer?.Start();
2026-01-07 13:42:17 +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)
{
2026-01-16 12:00:20 +08:00
MessageBox.Show($"重新连接失败:{ex.Message}");
2026-01-07 13:42:17 +08:00
}
return false;
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : UIForm
{
_isSwitchingWindow = true;
_readTimer?.Stop();
_cts.Cancel();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
2026-01-16 12:00:20 +08:00
//尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
2026-01-07 13:42:17 +08:00
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null || windowInstance.IsDisposed)
{
windowInstance = createFunc();
windowInstance.FormClosed += (s, e) =>
{
this.Invoke(new Action(() =>
{
_isSwitchingWindow = false;
_cts = new CancellationTokenSource();
_readTimer?.Start();
this.Show();
this.Activate();
}));
};
}
else
{
windowInstance.Activate();
return;
}
this.Hide();
windowInstance.Show();
}
private void Coeffiicientsetting_FormClosing(object sender, FormClosingEventArgs e)
{
_cts.Cancel();
_cts.Dispose();
// 停止定时器
_readTimer?.Stop();
_readTimer?.Dispose();
// 仅用户主动关闭时退出应用
if (e.CloseReason == CloseReason.UserClosing)
{
ModbusResourceManager.Instance?.Dispose();
Application.Exit();
}
}
private void Coeffiicientsetting_FormClosed(object sender, FormClosedEventArgs e)
{
_normalTemperatureMode?.Dispose();
}
//控制压力系数
private void uiTextBox1_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 2394, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//压力保护输入
private void uiTextBox3_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox3.Text.Trim(), 3134, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
2026-01-16 16:52:10 +08:00
2026-01-07 13:42:17 +08:00
//压力上限
2026-01-16 16:52:10 +08:00
//private void uiTextBox2_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 2376, Function.DataType.浮点型);
//}
2026-01-07 13:42:17 +08:00
//压力下限
2026-01-16 16:52:10 +08:00
//private void uiTextBox4_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 2374, Function.DataType.浮点型);
//}
2026-01-07 13:42:17 +08:00
//温度系数
private void uiTextBox8_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox8.Text.Trim(), 3482, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
2026-01-16 16:52:10 +08:00
2026-01-07 13:42:17 +08:00
//出口温度系数
private void uiTextBox6_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox6.Text.Trim(), 3176, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//常温液位系数
private void uiTextBox7_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox7.Text.Trim(), 3076, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//常温液位上限
private void uiTextBox9_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 3086, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//常温液位下限
private void uiTextBox10_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox10.Text.Trim(), 3084, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//高温液位系数
private void uiTextBox12_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox12.Text.Trim(), 3026, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//高温液位上限
private void uiTextBox11_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox11.Text.Trim(), 3036, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//高温液位下限
private void uiTextBox5_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 3034, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//返回
private void uiButton1_Click(object sender, EventArgs e)
{
SwitchWindow(ref _normalTemperatureMode, () => new NormalTemperatureMode());
2026-01-16 15:11:12 +08:00
//this.Close();
2026-01-07 13:42:17 +08:00
}
//稳压时间
private void uiTextBox14_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox14.Text.Trim(), 2408, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//通水时间
private void uiTextBox15_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox15.Text.Trim(), 2406, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//排空时间
private void uiTextBox13_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox13.Text.Trim(), 2410, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
//温度
private void uiTextBox16_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox16.Text.Trim(), 2402, Function.DataType.);
2026-01-07 13:42:17 +08:00
}
2026-01-16 18:46:24 +08:00
2026-01-14 20:46:30 +08:00
//转速设置
private void uiTextBox17_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.WriteToPLCForNew(uiTextBox17.Text.Trim(), 2300, Function.DataType.);
2026-01-14 20:46:30 +08:00
}
2026-01-16 12:00:20 +08:00
//水循环
2026-01-14 20:46:30 +08:00
private void uiButton2_Click(object sender, EventArgs e)
2026-01-16 16:56:03 +08:00
{
2026-01-14 20:46:30 +08:00
2026-01-16 15:11:12 +08:00
ma?.BtnClickFunctionForNew(Function.ButtonType., 10000);
2026-01-14 20:46:30 +08:00
}
2026-01-16 12:00:20 +08:00
//恒压启动
2026-01-14 20:46:30 +08:00
private void uiButton3_Click(object sender, EventArgs e)
{
2026-01-16 15:11:12 +08:00
ma?.BtnClickFunctionForNew(Function.ButtonType., 10110);
2026-01-14 20:46:30 +08:00
}
2026-01-16 16:52:10 +08:00
//延迟记录初始值时间
private void uiTextBox2_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 2414, Function.DataType.);
}
2026-01-07 13:42:17 +08:00
}
2026-01-16 16:56:03 +08:00
}