Files
FullAutoWaterCheck/全自动水压检测仪/Coeffiicientsetting.cs
2026-02-05 16:13:18 +08:00

550 lines
20 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Modbus.Device;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
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();
// 只创建定时器,不在构造器中启动,避免在 Load 前访问未初始化的资源(如 c / _modbusMaster
_readTimer = InitTimer(); // 初始化定时器并保存引用
}
private System.Windows.Forms.Timer InitTimer()
{
var timer = new System.Windows.Forms.Timer()
{
Interval = 1000
};
timer.Tick += async (s, e) =>
{
// 检查窗体状态
if (this.IsDisposed || !this.IsHandleCreated)
{
return;
}
if (!_isManualInput && _modbusMaster != null)
{
try
{
await ReadLeakTestParametersAsync();
}
catch (Exception ex)
{
Debug.WriteLine($"定时器读取参数异常: {ex.Message}");
}
}
};
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()
{
// 前置校验:连接状态检查
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) return;
// 确保 UI 已可用
if (!this.IsHandleCreated || this.IsDisposed) return;
try
{
var registerConfigs = new List<RegisterConfig>
{
CreateRegisterConfig(2394, uiTextBox1, "F2",false), // 控制压力系数
CreateRegisterConfig(3134, uiTextBox3, "F2",false), // 压力保护输入
//CreateRegisterConfig(2376, uiTextBox2, "F2",false), // 压力上限
//CreateRegisterConfig(2374, uiTextBox4, "F2",false), // 压力下限
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), // 转速
CreateRegisterConfig(2402, uiTextBox16, "F2",false), // 温度
//CreateRegisterConfig(3484, uiTextBox4, "F2",false), // 温度保护
//CreateRegisterConfig(3134, uiTextBox18, "F2",false), // 压力保护
CreateRegisterConfig(2408, uiTextBox14, "0",true), // 稳压时间
CreateRegisterConfig(2406, uiTextBox15, "0",true), // 通水时间
CreateRegisterConfig(2410, uiTextBox13, "0",true), // 排空时间
CreateRegisterConfig(2414, uiTextBox2, "0",true), // 延迟记录初始值时间
};
// 批量处理所有寄存器读取和UI更新
foreach (var config in registerConfigs)
{
await ReadRegisterAndUpdateUIAsync(config);
}
await ReadButtonStatusAsync();
}
catch (Exception ex)
{
_readTimer?.Stop();
UIMessageBox.ShowError($"读取系数失败:{ex.Message}");
}
}
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);
}
}));
}
}
private async Task ReadButtonStatusAsync()
{
try
{
// 读取水循环状态 - 地址0
bool[] waterStatus = await Task.Run(() =>
_modbusMaster?.ReadCoils(1, 10000, 1));
// 读取恒压启动状态 - 地址110
bool[] pressureStatus = await Task.Run(() =>
_modbusMaster?.ReadCoils(1, 10110, 1));
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 ? "恒压启动中" : "恒压启动";
}
}));
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 更新按钮状态失败: {ex.Message}");
}
}
private void Coeffiicientsetting_Load(object sender, EventArgs e)
{
string plcIp = "192.168.1.10";
///string plcIp = "127.0.0.1";
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();
// 在 Load 完成 Modbus 初始化与 DataChange 初始化后再启动读定时器
//_readTimer?.Start();
}
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)
{
MessageBox.Show($"重新连接失败:{ex.Message}");
}
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)
{
//尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 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)
{
try
{
// 取消异步操作
if (_cts != null && !_cts.IsCancellationRequested)
{
_cts.Cancel();
_cts.Dispose();
_cts = null;
}
// 停止定时器
if (_readTimer != null)
{
_readTimer.Stop();
_readTimer.Tick -= null;
_readTimer.Dispose();
_readTimer = null;
}
// 仅用户主动关闭时退出应用
if (e.CloseReason == CloseReason.UserClosing)
{
try
{
ModbusResourceManager.Instance?.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine($"释放Modbus资源失败: {ex.Message}");
}
Application.Exit();
}
}
catch (Exception ex)
{
Debug.WriteLine($"窗体关闭异常: {ex.Message}");
// 确保应用能够退出
if (e.CloseReason == CloseReason.UserClosing)
{
Application.Exit();
}
}
}
private void Coeffiicientsetting_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
_normalTemperatureMode?.Dispose();
}
catch (Exception ex)
{
Debug.WriteLine($"释放主窗体资源失败: {ex.Message}");
}
}
//控制压力系数
private void uiTextBox1_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 2394, Function.DataType.);
}
//压力保护输入
private void uiTextBox3_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox3.Text.Trim(), 3134, Function.DataType.);
}
//压力上限
//private void uiTextBox2_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 2376, Function.DataType.浮点型);
//}
//压力下限
//private void uiTextBox4_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 2374, Function.DataType.浮点型);
//}
//温度系数
private void uiTextBox8_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox8.Text.Trim(), 3482, Function.DataType.);
}
//出口温度系数
private void uiTextBox6_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox6.Text.Trim(), 3176, Function.DataType.);
}
//常温液位系数
private void uiTextBox7_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox7.Text.Trim(), 3076, Function.DataType.);
}
//常温液位上限
private void uiTextBox9_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 3086, Function.DataType.);
}
//常温液位下限
private void uiTextBox10_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox10.Text.Trim(), 3084, Function.DataType.);
}
//高温液位系数
private void uiTextBox12_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox12.Text.Trim(), 3026, Function.DataType.);
}
//高温液位上限
private void uiTextBox11_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox11.Text.Trim(), 3036, Function.DataType.);
}
//高温液位下限
private void uiTextBox5_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 3034, Function.DataType.);
}
//返回
private void uiButton1_Click(object sender, EventArgs e)
{
SwitchWindow(ref _normalTemperatureMode, () => new NormalTemperatureMode());
//this.Close();
}
//稳压时间
private void uiTextBox14_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox14.Text.Trim(), 2408, Function.DataType.);
}
//通水时间
private void uiTextBox15_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox15.Text.Trim(), 2406, Function.DataType.);
}
//排空时间
private void uiTextBox13_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox13.Text.Trim(), 2410, Function.DataType.);
}
//温度
private void uiTextBox16_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox16.Text.Trim(), 2402, Function.DataType.);
}
//转速设置
private void uiTextBox17_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox17.Text.Trim(), 2300, Function.DataType.);
}
//水循环
private void uiButton2_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10000);
}
//恒压启动
private void uiButton3_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10110);
}
//延迟记录初始值时间
private void uiTextBox2_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 2414, Function.DataType.);
}
#region
//常温抽水
private void uiButton4_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10006);
}
//高温抽水
private void uiButton13_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10005);
}
//常温加水
private void uiButton5_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10013);
}
//高温加水
private void uiButton11_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10012);
}
//高压进阀
private void uiButton12_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10008);
}
//高压出阀
private void uiButton7_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10001);
}
//空气抽气
private void uiButton10_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10007);
}
//常温回水
private void uiButton8_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10010);
}
//高温回水
private void uiButton9_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10009);
}
#endregion
private void Coeffiicientsetting_Shown(object sender, EventArgs e)
{
if (_modbusMaster != null)
{
//_readtimer = InitTimer();
_readTimer.Start();
}
}
////温度保护
//private void uiTextBox4_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 3484, Function.DataType.浮点型);
//}
////压力保护
//private void uiTextBox18_Click(object sender, EventArgs e)
//{
// ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 3134, Function.DataType.浮点型);
//}
}
}