425 lines
15 KiB
C#
425 lines
15 KiB
C#
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 全自动水压检测仪.Data;
|
||
using 全自动水压检测仪.DATA;
|
||
|
||
namespace 全自动水压检测仪
|
||
{
|
||
public partial class HighTemperatureMode : 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 HighTemperatureMode()
|
||
{
|
||
InitializeComponent();
|
||
_cts = new CancellationTokenSource();
|
||
InitTimer(); // 初始化定时器
|
||
InitTimerForSecond(); // 初始化定时器
|
||
|
||
}
|
||
|
||
private System.Windows.Forms.Timer InitTimer()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 500
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (!_isManualInput && _modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadLeakTestParametersAsync();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
timer.Start();
|
||
return timer;
|
||
}
|
||
|
||
|
||
private System.Windows.Forms.Timer InitTimerForSecond()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 500
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (!_isManualInput && _modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadLeakTestParametersAsyncForSecond();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
timer.Start();
|
||
return timer;
|
||
}
|
||
|
||
private async Task ReadLeakTestParametersAsync()
|
||
{
|
||
// 前置校验:连接状态检查
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
uiLabel5.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
uiLabel3.Text = ReadModbusInt(80).ToString();//测试步
|
||
uiLabel28.Text = ReadModbusFloat(1130).ToString("F2");//实时压力
|
||
uiLabel12.Text = ReadModbusFloat(1030).ToString("F2");//高温实时液位
|
||
uiLabel25.Text = ReadModbusInt(82).ToString();//计时s
|
||
uiLabel9.Text = ReadModbusInt(84).ToString();//计时min
|
||
uiLabel31.Text = ReadModbusInt(86).ToString();//计时h
|
||
uiLabel14.Text = ReadModbusFloat(100).ToString("F2");//初始压力
|
||
uiLabel19.Text = ReadModbusFloat(102).ToString("F2");//结束压力
|
||
uiLabel22.Text = ReadModbusFloat(104).ToString("F2");//压差
|
||
uiLabel34.Text = ReadModbusFloat(1480).ToString("F2");//箱体温度
|
||
uiLabel38.Text = ReadModbusFloat(1180).ToString("F2");//出口温度
|
||
|
||
|
||
//await UpdateUiWithModbusFloatAsync(400, val => uiTextBox1.Text = val.ToString("F2"));//读取压力设置
|
||
//await UpdateUiWithModbusIntAsync(406, val => uiTextBox2.Text = val.ToString());//读取通水时间设置
|
||
//await UpdateUiWithModbusIntAsync(408, val => uiTextBox3.Text = val.ToString());//读取稳压时间设置
|
||
//await UpdateUiWithModbusIntAsync(410, val => uiTextBox4.Text = val.ToString());//读取排空时间设置
|
||
//await UpdateUiWithModbusIntAsync(404, val => uiTextBox5.Text = val.ToString());//读取测试保压时间设置
|
||
//await UpdateUiWithModbusIntAsync(402, val => uiTextBox6.Text = val.ToString());//读取温度设置
|
||
|
||
//常温指示
|
||
bool[] conditionStatus = _modbusMaster?.ReadCoils(1, 32, 1);
|
||
if (conditionStatus[0])
|
||
{
|
||
uiLight1.State = UILightState.Off;
|
||
}
|
||
else
|
||
{
|
||
uiLight1.State = UILightState.On;
|
||
}
|
||
|
||
//启动测试
|
||
bool[] testStatus = _modbusMaster?.ReadCoils(1, 80, 1);
|
||
if (testStatus[0])
|
||
{
|
||
uiButton2.Text = "测试中";
|
||
uiButton2.ForeColor = System.Drawing.Color.Black;
|
||
}
|
||
else
|
||
{
|
||
uiButton2.Text = "启动测试";
|
||
uiButton2.ForeColor = System.Drawing.Color.White;
|
||
}
|
||
}
|
||
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
UIMessageBox.ShowError($"读取系数失败:{ex.Message}");
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
private async Task ReadLeakTestParametersAsyncForSecond()
|
||
{
|
||
// 前置校验:连接状态检查
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
await UpdateUiWithModbusFloatAsync(400, val => uiTextBox1.Text = val.ToString("F2"));//读取压力设置
|
||
await UpdateUiWithModbusIntAsync(406, val => uiTextBox2.Text = val.ToString());//读取通水时间设置
|
||
await UpdateUiWithModbusIntAsync(408, val => uiTextBox3.Text = val.ToString());//读取稳压时间设置
|
||
await UpdateUiWithModbusIntAsync(410, val => uiTextBox4.Text = val.ToString());//读取排空时间设置
|
||
await UpdateUiWithModbusIntAsync(404, val => uiTextBox5.Text = val.ToString());//读取测试保压时间设置
|
||
await UpdateUiWithModbusIntAsync(402, val => uiTextBox6.Text = val.ToString());//读取温度设置
|
||
|
||
}
|
||
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
UIMessageBox.ShowError($"读取系数失败:{ex.Message}");
|
||
|
||
}));
|
||
}
|
||
}
|
||
|
||
private float ReadModbusFloat(ushort startAddress)
|
||
{
|
||
var registers = _modbusMaster?.ReadHoldingRegisters(1, startAddress, 2);
|
||
return registers?.Length >= 2 ? c.UshortToFloat(registers[1], registers[0]) : 0;
|
||
}
|
||
|
||
private int ReadModbusInt(ushort startAddress)
|
||
{
|
||
var registers = _modbusMaster?.ReadHoldingRegisters(1, startAddress, 2);
|
||
if (registers?.Length >= 2)
|
||
{
|
||
// 根据实际整数拼接规则调整(这里默认用两个ushort拼接为int,可根据实际协议修改)
|
||
return (int)((registers[1] << 16) | registers[0]);
|
||
}
|
||
return 0; // 读取失败返回默认值
|
||
}
|
||
|
||
private async Task UpdateUiWithModbusFloatAsync(ushort startAddress, Action<float> updateAction)
|
||
{
|
||
var registers = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, startAddress, 2));
|
||
if (registers?.Length >= 2)
|
||
{
|
||
float value = c.UshortToFloat(registers[1], registers[0]);
|
||
Invoke(new Action(() => updateAction.Invoke(value)));
|
||
}
|
||
}
|
||
|
||
private async Task UpdateUiWithModbusIntAsync(ushort startAddress, Action<int> updateAction)
|
||
{
|
||
var registers = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, startAddress, 2));
|
||
if (registers?.Length >= 2)
|
||
{
|
||
int value = (int)((registers[1] << 16) | registers[0]);
|
||
Invoke(new Action(() => updateAction.Invoke(value)));
|
||
}
|
||
}
|
||
|
||
//常温模式
|
||
private void uiButton11_Click(object sender, EventArgs e)
|
||
{
|
||
//FormManager.Instance.SwitchTo<NormalTemperatureMode>();
|
||
bool result = UIMessageBox.ShowAsk("确认是否切换常温模式", true, UIMessageDialogButtons.Ok);
|
||
if (result)
|
||
{
|
||
//_modbusMaster?.WriteSingleCoil(1, 30, false);
|
||
SwitchWindow(ref _normalTemperatureMode, () => new NormalTemperatureMode());
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
//系数页
|
||
private void uiButton14_Click(object sender, EventArgs e)
|
||
{
|
||
//FormManager.Instance.SwitchTo<Coeffiicientsetting>();
|
||
SwitchWindow(ref _coeffiicientsetting, () => new Coeffiicientsetting());
|
||
}
|
||
|
||
private void HighTemperatureMode_Load(object sender, EventArgs 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;
|
||
}
|
||
_modbusMaster?.WriteSingleCoil(1, 30, true);
|
||
Thread.Sleep(50);
|
||
ma = new Function(_modbusMaster);
|
||
c = new DataChange();
|
||
}
|
||
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 HighTemperatureMode_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
|
||
// 停止定时器
|
||
_readTimer?.Stop();
|
||
_readTimer?.Dispose();
|
||
|
||
// 仅用户主动关闭时退出应用
|
||
if (e.CloseReason == CloseReason.UserClosing)
|
||
{
|
||
ModbusResourceManager.Instance?.Dispose();
|
||
Application.Exit();
|
||
}
|
||
}
|
||
|
||
|
||
private void HighTemperatureMode_FormClosed(object sender, FormClosedEventArgs e)
|
||
{
|
||
_coeffiicientsetting?.Dispose();
|
||
_normalTemperatureMode?.Dispose();
|
||
}
|
||
|
||
//进气阀
|
||
private void uiButton5_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 14);
|
||
}
|
||
//测试高压阀
|
||
private void uiButton6_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 8);
|
||
}
|
||
//空气抽气阀
|
||
private void uiButton8_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 7);
|
||
}
|
||
//高温水箱加水阀
|
||
private void uiButton9_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 12);
|
||
}
|
||
//高温抽水阀
|
||
private void uiButton7_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 5);
|
||
}
|
||
//高温回水阀
|
||
private void uiButton10_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10);
|
||
}
|
||
//系统排气
|
||
private void uiButton13_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 70);
|
||
}
|
||
//升温阀
|
||
private void uiButton12_Click(object sender, EventArgs e)
|
||
{
|
||
|
||
}
|
||
|
||
//压力设定
|
||
private void uiTextBox1_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 400, Function.DataType.浮点型);
|
||
}
|
||
//稳压时间设定
|
||
private void uiTextBox3_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox3.Text.Trim(), 408, Function.DataType.整形);
|
||
}
|
||
//测试保压时间设定
|
||
private void uiTextBox5_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 404, Function.DataType.整形);
|
||
}
|
||
//通水时间设定
|
||
private void uiTextBox2_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox2.Text.Trim(), 406, Function.DataType.整形);
|
||
}
|
||
//排空时间设定
|
||
private void uiTextBox4_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 410, Function.DataType.整形);
|
||
}
|
||
//温度设定
|
||
private void uiTextBox6_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox6.Text.Trim(), 402, Function.DataType.整形);
|
||
}
|
||
}
|
||
}
|