Files
FullAutoWaterCheck/全自动水压检测仪/Coeffiicientsetting.cs
2026-01-14 20:46:30 +08:00

419 lines
15 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.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 Coeffiicientsetting _coeffiicientsetting;
private HighTemperatureMode _highTemperatureMode;
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();
InitTimer(); // 初始化定时器
}
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 { }
}
};
timer.Start();
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;
}
try
{
var registerConfigs = new List<RegisterConfig>
{
CreateRegisterConfig(394, uiTextBox1, "F2",false), // 控制压力系数
CreateRegisterConfig(1134, uiTextBox3, "F2",false), // 压力保护输入
CreateRegisterConfig(376, uiTextBox2, "F2",false), // 压力上限
CreateRegisterConfig(374, uiTextBox4, "F2",false), // 压力下限
CreateRegisterConfig(1482, uiTextBox8, "F2",false), // 温度系数
CreateRegisterConfig(1176, uiTextBox6, "F2",false), // 出口温度系数
CreateRegisterConfig(1076, uiTextBox7, "F2",false), // 常温液位系数
CreateRegisterConfig(1086, uiTextBox9, "F2",false), // 常温液位上限
CreateRegisterConfig(1084, uiTextBox10, "F2",false), // 常温液位下限
CreateRegisterConfig(1026, uiTextBox12, "F2",false), // 高温液位系数
CreateRegisterConfig(1036, uiTextBox11, "F2",false), // 高温液位上限
CreateRegisterConfig(1034, uiTextBox5, "F2",false), // 高温液位下限
CreateRegisterConfig(300, uiTextBox17, "F2",false), // 高温液位下限
CreateRegisterConfig(408, uiTextBox14, "0",true), // 稳压时间
CreateRegisterConfig(406, uiTextBox15, "0",true), // 通水时间
CreateRegisterConfig(410, uiTextBox13, "0",true), // 排空时间
CreateRegisterConfig(402, uiTextBox16, "0",true) // 温度
};
// 批量处理所有寄存器读取和UI更新
foreach (var config in registerConfigs)
{
await ReadRegisterAndUpdateUIAsync(config);
}
}
catch (Exception ex)
{
this.Invoke(new Action(() =>
{
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 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();
}
private void ShowErrorMsg(string msg)
{
// 判断当前线程是否是UI线程避免跨线程访问控件异常
if (this.InvokeRequired)
{
// 跨线程时通过Invoke切换到UI线程执行
this.Invoke(new Action<string>(ShowErrorMsg), msg);
return;
}
// UI线程直接显示错误提示框
MessageBox.Show(msg, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
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 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)
{
_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)
{
_highTemperatureMode?.Dispose();
_normalTemperatureMode?.Dispose();
}
//控制压力系数
private void uiTextBox1_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 394, Function.DataType.);
}
//压力保护输入
private void uiTextBox3_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox3.Text.Trim(), 1134, Function.DataType.);
}
//压力上限
private void uiTextBox2_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 376, Function.DataType.);
}
//压力下限
private void uiTextBox4_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 374, Function.DataType.);
}
//温度系数
private void uiTextBox8_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox8.Text.Trim(), 1482, Function.DataType.);
}
//出口温度系数
private void uiTextBox6_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox6.Text.Trim(), 1176, Function.DataType.);
}
//常温液位系数
private void uiTextBox7_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox7.Text.Trim(), 1076, Function.DataType.);
}
//常温液位上限
private void uiTextBox9_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 1086, Function.DataType.);
}
//常温液位下限
private void uiTextBox10_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox10.Text.Trim(), 1084, Function.DataType.);
}
//高温液位系数
private void uiTextBox12_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox12.Text.Trim(), 1026, Function.DataType.);
}
//高温液位上限
private void uiTextBox11_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox11.Text.Trim(), 1036, Function.DataType.);
}
//高温液位下限
private void uiTextBox5_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 1034, Function.DataType.);
}
//返回
private void uiButton1_Click(object sender, EventArgs e)
{
SwitchWindow(ref _normalTemperatureMode, () => new NormalTemperatureMode());
}
//稳压时间
private void uiTextBox14_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox14.Text.Trim(), 408, Function.DataType.);
}
//通水时间
private void uiTextBox15_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox15.Text.Trim(), 406, Function.DataType.);
}
//排空时间
private void uiTextBox13_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox13.Text.Trim(), 410, Function.DataType.);
}
//温度
private void uiTextBox16_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox16.Text.Trim(), 402, Function.DataType.);
}
//转速设置
private void uiTextBox17_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox17.Text.Trim(), 300, Function.DataType.);
}
private bool _isWaterCycleOn = false;
private bool _isConstantPressureOn = false;
private void uiButton2_Click(object sender, EventArgs e)
{
_isWaterCycleOn = !_isWaterCycleOn; // 切换状态
if (_isWaterCycleOn)
{
uiButton2.ForeColor = Color.Red;
uiButton2.Text = "水循环中";
}
else
{
uiButton2.ForeColor = Color.White;
uiButton2.Text = "水循环";
}
ma?.BtnClickFunctionForNew(Function.ButtonType., 0);//水循环
}
private void uiButton3_Click(object sender, EventArgs e)
{
_isConstantPressureOn = !_isConstantPressureOn; // 切换状态
if (_isConstantPressureOn)
{
uiButton3.ForeColor = Color.Red;
uiButton3.Text = "恒压启动中";
}
else
{
uiButton3.ForeColor = Color.White;
uiButton3.Text = "恒压启动";
}
ma?.BtnClickFunctionForNew(Function.ButtonType., 110);//恒压启动
}
}
}