Files
FullAutoWaterCheck/全自动水压检测仪/NormalTemperatureMode.cs
2026-01-23 20:29:18 +08:00

862 lines
31 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 Microsoft.Win32;
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.Timers;
using System.Windows.Forms;
using .Data;
using .DATA;
using ;
namespace
{
public partial class NormalTemperatureMode : UIForm
{
BoolSignal boolSignal1 = new BoolSignal();
private Coeffiicientsetting _coeffiicientsetting;
public List<ConductivityTestData> CurrentReport;
private Report _report;
private Stopwatch pressStopwatch;
private const int LONG_PRESS_THRESHOLD = 1000; // 1000毫秒=1秒
#region
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
#endregion
Function ma;
DataChange c;
private System.Windows.Forms.Timer _readTimer;
private System.Windows.Forms.Timer _readTimerTwo; // 第二个定时器引用
private bool _isManualInput = false; // 手动输入标记
private bool _isSwitchingWindow = false; // 窗口切换标记,避免并发
private ConductivityRepository _repository;
public NormalTemperatureMode()
{
InitializeComponent();
pressStopwatch = new Stopwatch();
// 只创建定时器,不在构造器中启动,避免在 Load 前访问未初始化的资源
_readTimer = InitTimer(); // 保存引用
_readTimerTwo = InitTimerTwo(); // 保存第二个定时器引用
_repository = new ConductivityRepository();
CurrentReport = new List<ConductivityTestData>();
}
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 { }
}
};
// 不在此处 Start
return timer;
}
private System.Windows.Forms.Timer InitTimerTwo()
{
var timer = new System.Windows.Forms.Timer()
{
Interval = 1000
};
timer.Tick += async (s, e) =>
{
if (!_isManualInput && _modbusMaster != null)
{
try
{
await ReadLeakTestParametersAsyncTwo();
}
catch { }
}
};
// 不在此处 Start
return timer;
}
private async System.Threading.Tasks.Task ReadLeakTestParametersAsync()
{
// 检查连接状态
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
MessageBox.Show("TCP未连接或ModbusMaster未初始化", "提示");
return;
}
// 检查UI控件是否可用避免在窗体释放前调用
if (!this.IsHandleCreated || this.IsDisposed)
{
return;
}
try
{
var modbusData = await Task.Run(() =>
{
try
{
return new
{
//读取所需要的寄存器(同步操作,但在后台线程)
Real1 = SafelyReadRegisters(1, 3130, 2),// 实时压力
Real2 = SafelyReadRegisters(1, 3080, 2),// 常温实时液位
Real3 = SafelyReadRegisters(1, 2100, 2),// 初始化压力
Real4 = SafelyReadRegisters(1, 2102, 2),// 结束压力
Real5 = SafelyReadRegisters(1, 2104, 2),// 压差
Real6 = SafelyReadRegisters(1, 2082, 2),// 计时s
Real7 = SafelyReadRegisters(1, 2084, 2),// 计时min
Real8 = SafelyReadRegisters(1, 2086, 2),// 计时h
Real9 = SafelyReadRegisters(1, 3030, 2),// 高温实时液位
Real10 = SafelyReadRegisters(1, 3480, 2),// 箱体温度
Real11 = SafelyReadRegisters(1, 3180, 2),// 出口温度
CurrentTime = DateTime.Now
};
}
catch
{
return null; // 读取失败返回 null
}
});
// 检查是否成功读取
if (modbusData == null)
{
throw new InvalidOperationException("Modbus数据读取失败");
}
// 检查数据转换工具是否可用
if (c == null)
{
throw new InvalidOperationException("数据转换工具未初始化");
}
// 检查控件是否存在
if (this.IsDisposed || !this.IsHandleCreated)
{
return;
}
// 使用 BeginInvoke 确保在 UI 线程执行
this.BeginInvoke(new Action(() =>
{
try
{
// 时间显示
if (uiLabel5 != null && !uiLabel5.IsDisposed)
uiLabel5.Text = modbusData.CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
// 实时压力
if (uiLabel28 != null && !uiLabel28.IsDisposed &&
modbusData.Real1 != null && modbusData.Real1.Length >= 2)
{
var value0 = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]);
uiLabel28.Text = value0.ToString("F2");
}
// 常温实时液位
if (uiLabel12 != null && !uiLabel12.IsDisposed &&
modbusData.Real2 != null && modbusData.Real2.Length >= 2)
{
var value1 = c.UshortToFloat(modbusData.Real2[1], modbusData.Real2[0]);
uiLabel12.Text = value1.ToString("F2");
}
// 初始压力
if (uiLabel14 != null && !uiLabel14.IsDisposed &&
modbusData.Real3 != null && modbusData.Real3.Length >= 2)
{
var value2 = c.UshortToFloat(modbusData.Real3[1], modbusData.Real3[0]);
uiLabel14.Text = value2.ToString("F2");
}
// 结束压力
if (uiLabel19 != null && !uiLabel19.IsDisposed &&
modbusData.Real4 != null && modbusData.Real4.Length >= 2)
{
var value3 = c.UshortToFloat(modbusData.Real4[1], modbusData.Real4[0]);
uiLabel19.Text = value3.ToString("F2");
}
// 压差
if (uiLabel22 != null && !uiLabel22.IsDisposed &&
modbusData.Real5 != null && modbusData.Real5.Length >= 2)
{
var value4 = c.UshortToFloat(modbusData.Real5[1], modbusData.Real5[0]);
uiLabel22.Text = value4.ToString("F2");
}
// 计时s
if (uiLabel25 != null && !uiLabel25.IsDisposed &&
modbusData.Real6 != null && modbusData.Real6.Length >= 1)
{
int value5 = modbusData.Real6[0];
uiLabel25.Text = value5.ToString();
}
// 计时min
if (uiLabel9 != null && !uiLabel9.IsDisposed &&
modbusData.Real7 != null && modbusData.Real7.Length >= 1)
{
int value6 = modbusData.Real7[0];
uiLabel9.Text = value6.ToString();
}
// 计时h
if (uiLabel31 != null && !uiLabel31.IsDisposed &&
modbusData.Real8 != null && modbusData.Real8.Length >= 1)
{
int value7 = modbusData.Real8[0];
uiLabel31.Text = value7.ToString();
}
// 高温实时液位
if (uiLabel7 != null && !uiLabel7.IsDisposed &&
modbusData.Real9 != null && modbusData.Real9.Length >= 2)
{
var value8 = c.UshortToFloat(modbusData.Real9[1], modbusData.Real9[0]);
uiLabel7.Text = value8.ToString("F2");
}
// 箱体温度
if (uiLabel42 != null && !uiLabel42.IsDisposed &&
modbusData.Real10 != null && modbusData.Real10.Length >= 2)
{
var value9 = c.UshortToFloat(modbusData.Real10[1], modbusData.Real10[0]);
uiLabel42.Text = value9.ToString("F1");
}
// 出口温度
if (uiLabel38 != null && !uiLabel38.IsDisposed &&
modbusData.Real11 != null && modbusData.Real11.Length >= 2)
{
var value10 = c.UshortToFloat(modbusData.Real11[1], modbusData.Real11[0]);
uiLabel38.Text = value10.ToString("F1");
}
}
catch (Exception uiEx)
{
Debug.WriteLine($"UI更新异常: {uiEx.Message}");
}
}));
}
catch (Exception ex)
{
// 安全地停止定时器
try
{
_readTimer?.Stop();
}
catch { }
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
bool isAddTag = false;
// 辅助方法:安全读取寄存器
private ushort[] SafelyReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
{
try
{
if (_modbusMaster != null)
{
return _modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
}
}
catch
{
// 读取失败返回空数组
}
return new ushort[numberOfPoints]; // 返回默认值数组
}
private async System.Threading.Tasks.Task ReadLeakTestParametersAsyncTwo()
{
//是否连接
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) return;
//测试步骤
try
{
ushort[] testslip = _modbusMaster?.ReadHoldingRegisters(1, 2080, 2);
if (testslip == null || testslip.Length == 0) return;
int testvalue = testslip[0];
uiLabel3.Text = testvalue.ToString();
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取测试步(地址80)失败: {ex.Message}");
}
//压力设定
try
{
ushort[] registers = await Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 2400, 2)
);
if (registers == null || registers.Length == 0) return;
float pressureValue = c.UshortToFloat(registers[1], registers[0]);
this.Invoke(new Action(() =>
{
uiTextBox1.Text = pressureValue.ToString("F2");
}));
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取压力设定(地址400)失败: {ex.Message}");
}
//箱体温度
try
{
ushort[] registers = await Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 2402, 2)
);
if (registers == null || registers.Length == 0) return;
float registerValue = c.UshortToFloat(registers[1], registers[0]);
this.Invoke(new Action(() =>
{
uiTextBox4.Text = registerValue.ToString("F2");
}));
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取箱体温度(地址402)失败: {ex.Message}");
}
//保压时间
try
{
ushort[] registers = await Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 2404, 2)
);
if (registers == null || registers.Length == 0) return;
int pressureValue = registers[0];
this.Invoke(new Action(() =>
{
uiTextBox5.Text = pressureValue.ToString();
}));
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取保压时间设置(地址404)失败: {ex.Message}");
}
//出口温度设置
try
{
ushort[] registers = await Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 2412, 2)
);
if (registers == null || registers.Length == 0) return;
float temperatureValue = c.UshortToFloat(registers[1], registers[0]);
this.Invoke(new Action(() =>
{
uiTextBox9.Text = temperatureValue.ToString("F2");
}));
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取出口温度设置(地址412)失败: {ex.Message}");
}
try
{
//测试按键
bool[] testStatus = _modbusMaster?.ReadCoils(1, 10081, 1);
if (testStatus != null && testStatus.Length > 0 && testStatus[0])
{
uiButton2.Text = "测试中";
uiButton2.ForeColor = System.Drawing.Color.Red;
boolSignal1.Value = true;
boolSignal1.CheckRisingEdge();
}
else
{
uiButton2.Text = "启动测试";
uiButton2.ForeColor = System.Drawing.Color.White;
boolSignal1.CheckRisingEdge();
boolSignal1.Value = false;
}
//高低温切换
bool[] buttonStatus = _modbusMaster?.ReadCoils(1, 10030, 1);
if (buttonStatus != null && buttonStatus.Length > 0 && buttonStatus[0])
{
uiSwitch1.Active = true;
}
else
{
uiSwitch1.Active = false;
}
//低温指示
bool[] lowStatus = _modbusMaster?.ReadCoils(1, 10031, 1);
if (lowStatus != null && lowStatus.Length > 0 && lowStatus[0])
{
uiLight1.State = UILightState.On;
}
else
{
uiLight1.State = UILightState.Off;
}
//高温指示
bool[] highStatus = _modbusMaster?.ReadCoils(1, 10032, 1);
if (highStatus != null && highStatus.Length > 0 && highStatus[0])
{
uiLight2.State = UILightState.On;
}
else
{
uiLight2.State = UILightState.Off;
}
//高压进阀指示
bool[] valve2 = _modbusMaster?.ReadCoils(1, 10008, 1);
if (valve2 != null && valve2.Length > 0 && valve2[0])
{
uiLight4.State = UILightState.On;
}
else
{
uiLight4.State = UILightState.Off;
}
//高压出阀
bool[] valve13 = _modbusMaster?.ReadCoils(1, 10001, 1);
if (valve13 != null && valve13.Length > 0 && valve13[0])
{
uiLight3.State = UILightState.On;
}
else
{
uiLight3.State = UILightState.Off;
}
//常温抽水阀指示
bool[] valve3 = _modbusMaster?.ReadCoils(1, 10006, 1);
if (valve3 != null && valve3.Length > 0 && valve3[0])
{
uiLight5.State = UILightState.On;
}
else
{
uiLight5.State = UILightState.Off;
}
//常温水箱加水指示
bool[] valve4 = _modbusMaster?.ReadCoils(1, 10013, 1);
if (valve4 != null && valve4.Length > 0 && valve4[0])
{
uiLight6.State = UILightState.On;
uiButton13.ForeColor = Color.Red;
uiButton13.Text = "常温加水中";
}
else
{
uiLight6.State = UILightState.Off;
uiButton13.ForeColor = Color.White;
uiButton13.Text = "常温加水";
}
//高温抽水阀指示
bool[] valve5 = _modbusMaster?.ReadCoils(1, 10005, 1);
if (valve5 != null && valve5.Length > 0 && valve5[0])
{
uiLight7.State = UILightState.On;
}
else
{
uiLight7.State = UILightState.Off;
}
//空气抽气阀指示
bool[] valve6 = _modbusMaster?.ReadCoils(1, 10007, 1);
if (valve6 != null && valve6.Length > 0 && valve6[0])
{
uiLight8.State = UILightState.On;
}
else
{
uiLight8.State = UILightState.Off;
}
//加热状态指示
bool[] valve7 = _modbusMaster?.ReadCoils(1, 10004, 1);
if (valve7 != null && valve7.Length > 0 && valve7[0])
{
uiLight9.State = UILightState.On;
}
else
{
uiLight9.State = UILightState.Off;
}
//常温回水阀指示
bool[] valve8 = _modbusMaster?.ReadCoils(1, 10010, 1);
if (valve8 != null && valve8.Length > 0 && valve8[0])
{
uiLight10.State = UILightState.On;
}
else
{
uiLight10.State = UILightState.Off;
}
//高温水箱加水指示
bool[] valve9 = _modbusMaster?.ReadCoils(1, 10012, 1);
if (valve9 != null && valve9.Length > 0 && valve9[0])
{
uiLight11.State = UILightState.On;
uiButton5.ForeColor = Color.Red;
uiButton5.Text = "高温加水中";
}
else
{
uiLight11.State = UILightState.Off;
uiButton5.ForeColor = Color.White;
uiButton5.Text = "高温加水";
}
//高温回水阀指示
bool[] valve10 = _modbusMaster?.ReadCoils(1, 10009, 1);
if (valve10 != null && valve10.Length > 0 && valve10[0])
{
uiLight12.State = UILightState.On;
}
else
{
uiLight12.State = UILightState.Off;
}
//水箱加热指示
bool[] valve12 = _modbusMaster?.ReadCoils(1, 10004, 1);
if (valve12 != null && valve12.Length > 0 && valve12[0])
{
uiButton4.ForeColor = Color.Red;
uiButton4.Text = "加热中";
}
else
{
uiButton4.ForeColor = Color.White;
uiButton4.Text = "水箱加热";
}
}
catch (Exception ex)
{
Debug.WriteLine($"[错误] 读取阀门状态失败: {ex.Message}");
}
}
//切换数页
//private void uiButton14_Click(object sender, EventArgs e)
//{
// SwitchWindow(ref _coeffiicientsetting, () => new Coeffiicientsetting());
//}
private void NormalTemperatureMode_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();
_modbusMaster?.WriteSingleCoil(1, 30, true);
boolSignal1.OnRisingEdge += BoolSignal1_OnRisingEdge;
// 在 Load 完成初始化后再启动定时器,避免定时器在 c / ma 未就绪时触发访问导致异常
//_readTimer?.Start();
//_readTimerTwo?.Start();
}
void BoolSignal1_OnRisingEdge()
{
if (isAddTag) return;
uiTextBox3.Text = uiLabel14.Text;//初始压力
uiTextBox8.Text = uiTextBox5.Text;//保压时间
uiTextBox6.Text = uiLabel22.Text;//压差
uiTextBox7.Text = uiLabel19.Text;//结束压力
CurrentReport.Add(new ConductivityTestData
{
barcode = uiTextBox2.Text,
CreateTime = DateTime.Now,
diffpressure = uiTextBox6.Text.ToDouble(),
dwelltime = uiTextBox8.Text.ToDouble(),
temperature = uiTextBox4.Text.ToDouble(),
endpressure = uiTextBox7.Text.ToDouble(),
startpressure = uiTextBox3.Text.ToDouble(),
Type = uiLight1.State == UILightState.On ? 1 : 0
});
_repository.InsertReportItems(new ConductivityTestData
{
barcode = uiTextBox2.Text,
CreateTime = DateTime.Now,
diffpressure = uiTextBox6.Text.ToDouble(),
dwelltime = uiTextBox8.Text.ToDouble(),
temperature = uiTextBox4.Text.ToDouble(),
endpressure = uiTextBox7.Text.ToDouble(),
startpressure = uiTextBox3.Text.ToDouble(),
Type = uiLight1.State == UILightState.On ? 1 : 0
});
uiTextBox2.Text = string.Empty;
isAddTag = true;
}
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)
{
Debug.WriteLine($"[错误] 重连失败: {ex.Message}");
}
return false;
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : UIForm
{
_isSwitchingWindow = true;
_readTimer?.Stop();
_readTimerTwo?.Stop(); // 停止第二个定时器
// 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;
_readTimer?.Start();
_readTimerTwo?.Start(); // 恢复第二个定时器
this.Show();
this.Activate();
}));
};
}
else
{
windowInstance.Activate();
return;
}
this.Hide();
windowInstance.Show();
}
private void NormalTemperatureMode_FormClosing(object sender, FormClosingEventArgs e)
{
// 停止定时器
_readTimer?.Stop();
_readTimer?.Dispose();
_readTimerTwo?.Stop();
_readTimerTwo?.Dispose();
// 仅用户主动关闭时退出应用
if (e.CloseReason == CloseReason.UserClosing)
{
ModbusResourceManager.Instance?.Dispose();
Application.Exit();
}
}
private void NormalTemperatureMode_FormClosed_1(object sender, FormClosedEventArgs e)
{
_coeffiicientsetting?.Dispose();
}
//压力设置
private void uiTextBox1_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 2400, Function.DataType.);
}
//测试保压时间设置
private void uiTextBox5_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 2404, Function.DataType.);
}
#region
//常温加水
private void uiButton13_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10013);
}
//隐藏
private void uiButton14_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
pressStopwatch.Restart();
}
}
private void uiButton14_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
pressStopwatch.Stop();
if (pressStopwatch.ElapsedMilliseconds >= LONG_PRESS_THRESHOLD)
{
// 执行长按操作
EnterFunction();
}
//else
//{
// // 执行点击操作(可选)
// ClickFunction();
//}
}
}
private void EnterFunction()
{
// 长按后进入的功能
SwitchWindow(ref _coeffiicientsetting, () => new Coeffiicientsetting());
}
//切换报告界面
private void uiButton1_Click(object sender, EventArgs e)
{
SwitchWindow(ref _report, () => new Report(CurrentReport));
}
//箱体温度设置
private void uiTextBox4_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 2402, Function.DataType.);
}
//启动测试
private void uiButton2_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10080);
isAddTag = false;
}
//停止测试
private void uiButton3_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10082);
}
//切换实验模式
private void uiSwitch1_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10030);
}
//出口温度设置
private void uiTextBox9_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 2412, Function.DataType.);
}
//高温加水
private void uiButton5_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10012);
}
//高温加热
private void uiButton4_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10004);
}
//清除报警
private void uiButton6_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10025);
}
#endregion
private void NormalTemperatureMode_Shown(object sender, EventArgs e)
{
if (_modbusMaster != null)
{
_readTimer.Start();
_readTimerTwo.Start();
}
}
}
}