618 lines
21 KiB
C#
618 lines
21 KiB
C#
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 全自动水压检测仪.Data;
|
||
using 全自动水压检测仪.DATA;
|
||
using 材料热传导系数;
|
||
|
||
namespace 全自动水压检测仪
|
||
{
|
||
public partial class NormalTemperatureMode : UIForm
|
||
{
|
||
BoolSignal boolSignal1 = new BoolSignal();
|
||
private Coeffiicientsetting _coeffiicientsetting;
|
||
private HighTemperatureMode _highTemperatureMode;
|
||
public List<ConductivityTestData> CurrentReport;
|
||
private Report _report;
|
||
private Stopwatch pressStopwatch;
|
||
private const int LONG_PRESS_THRESHOLD = 1000; // 1000毫秒=1秒
|
||
|
||
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 ConductivityRepository _repository;
|
||
|
||
public NormalTemperatureMode()
|
||
{
|
||
InitializeComponent();
|
||
pressStopwatch = new Stopwatch();
|
||
InitTimer(); // 初始化定时器
|
||
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 { }
|
||
}
|
||
};
|
||
timer.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 { }
|
||
}
|
||
};
|
||
timer.Start();
|
||
return timer;
|
||
}
|
||
|
||
private async System.Threading.Tasks.Task ReadLeakTestParametersAsync()
|
||
{
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
// 核心:将CPU/IO密集的Modbus读取操作放到后台线程执行
|
||
// 避免阻塞UI线程,await等待执行完成
|
||
var modbusData = await Task.Run(() =>
|
||
{
|
||
// 此匿名方法在后台线程执行,不能访问UI控件
|
||
return new
|
||
{
|
||
// 读取所有需要的寄存器(同步操作,但是在后台线程)
|
||
Real1 = _modbusMaster.ReadHoldingRegisters(1, 1130, 2),
|
||
Real2 = _modbusMaster.ReadHoldingRegisters(1, 1080, 2),
|
||
Real3 = _modbusMaster.ReadHoldingRegisters(1, 100, 2),
|
||
Real4 = _modbusMaster.ReadHoldingRegisters(1, 102, 2),
|
||
Real5 = _modbusMaster.ReadHoldingRegisters(1, 104, 2),
|
||
Real6 = _modbusMaster.ReadHoldingRegisters(1, 82, 2),
|
||
Real7 = _modbusMaster.ReadHoldingRegisters(1, 84, 2),
|
||
Real8 = _modbusMaster.ReadHoldingRegisters(1, 86, 2),
|
||
Real9 = _modbusMaster.ReadHoldingRegisters(1, 1030, 2),
|
||
Real10 = _modbusMaster.ReadHoldingRegisters(1, 1480, 2),
|
||
Real11 = _modbusMaster.ReadHoldingRegisters(1, 1180, 2),
|
||
Real12 = _modbusMaster.ReadHoldingRegisters(1, 402, 2),
|
||
|
||
CurrentTime = DateTime.Now // 后台线程获取时间不影响
|
||
};
|
||
});
|
||
|
||
// 数据读取完成后,回到UI线程更新控件(await会自动捕获上下文,此处已是UI线程)
|
||
// 时间显示
|
||
uiLabel5.Text = modbusData.CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 实时压力
|
||
var value0 = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]);
|
||
uiLabel28.Text = value0.ToString("F2");
|
||
|
||
// 常温实时液位
|
||
var value1 = c.UshortToFloat(modbusData.Real2[1], modbusData.Real2[0]);
|
||
uiLabel12.Text = value1.ToString("F2");
|
||
|
||
// 初始压力
|
||
var value2 = c.UshortToFloat(modbusData.Real3[1], modbusData.Real3[0]);
|
||
uiLabel14.Text = value2.ToString("F2");
|
||
|
||
// 结束压力
|
||
var value3 = c.UshortToFloat(modbusData.Real4[1], modbusData.Real4[0]);
|
||
uiLabel19.Text = value3.ToString("F2");
|
||
|
||
// 压差
|
||
var value4 = c.UshortToFloat(modbusData.Real5[1], modbusData.Real5[0]);
|
||
uiLabel22.Text = value4.ToString("F2");
|
||
|
||
// 计时s
|
||
int value5 = modbusData.Real6[0];
|
||
uiLabel25.Text = value5.ToString();
|
||
|
||
// 计时min
|
||
int value6 = modbusData.Real7[0];
|
||
uiLabel9.Text = value6.ToString();
|
||
|
||
// 计时h
|
||
int value7 = modbusData.Real8[0];
|
||
uiLabel31.Text = value7.ToString();
|
||
|
||
// 高温实时液位
|
||
var value8 = c.UshortToFloat(modbusData.Real9[1], modbusData.Real9[0]);
|
||
uiLabel7.Text = value8.ToString("F2");
|
||
|
||
// 箱体温度
|
||
var value9 = c.UshortToFloat(modbusData.Real10[1], modbusData.Real10[0]);
|
||
uiLabel42.Text = value9.ToString("F1");
|
||
|
||
// 出口温度
|
||
var value10 = c.UshortToFloat(modbusData.Real11[1], modbusData.Real11[0]);
|
||
uiLabel38.Text = value10.ToString("F1");
|
||
|
||
|
||
// 出口温度
|
||
var value12 = c.UshortToFloat(modbusData.Real12[1], modbusData.Real12[0]);
|
||
uiLabel4.Text = value12.ToString("F1");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
}
|
||
}
|
||
|
||
private async System.Threading.Tasks.Task ReadLeakTestParametersAsyncTwo()
|
||
{
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
//测试步
|
||
ushort[] testslip = _modbusMaster?.ReadHoldingRegisters(1, 80, 2);
|
||
int testvalue = testslip[0];
|
||
uiLabel3.Text = testvalue.ToString();
|
||
|
||
// 读取压力设置 (D-400)
|
||
ushort[] set1 = await System.Threading.Tasks.Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 400, 2)
|
||
);
|
||
if (set1 != null && set1.Length >= 2)
|
||
{
|
||
float Value0 = c.UshortToFloat(set1[1], set1[0]);
|
||
this.Invoke(new Action(() => uiTextBox1.Text = Value0.ToString("F2")));
|
||
}
|
||
|
||
|
||
// 读取压力设置 (D-402)
|
||
ushort[] set11 = await System.Threading.Tasks.Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 402, 1)
|
||
);
|
||
if (set11 != null && set11.Length >= 1)
|
||
{
|
||
float Value0 = set11[0];
|
||
this.Invoke(new Action(() => uiTextBox4.Text = Value0.ToString("F2")));
|
||
}
|
||
|
||
|
||
// 读取测试保压时间 (D-404)
|
||
ushort[] set2 = await System.Threading.Tasks.Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 404, 2)
|
||
);
|
||
if (set2 != null && set2.Length >= 2)
|
||
{
|
||
float Value1 = c.UshortToFloat(set2[1], set2[0]);
|
||
this.Invoke(new Action(() => uiTextBox5.Text = Value1.ToString("F2")));
|
||
}
|
||
|
||
//测试按钮
|
||
bool[] testStatus = _modbusMaster?.ReadCoils(1, 81, 1);
|
||
if (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.Value = false;
|
||
}
|
||
//高低温切换
|
||
bool[] buttonStatus = _modbusMaster?.ReadCoils(1, 30, 1);
|
||
if (buttonStatus[0])
|
||
{
|
||
uiSwitch1.Active = false;
|
||
}
|
||
else
|
||
{
|
||
uiSwitch1.Active = true;
|
||
}
|
||
//低温指示
|
||
bool[] lowStatus = _modbusMaster?.ReadCoils(1, 31, 1);
|
||
if (lowStatus[0])
|
||
{
|
||
uiLight1.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight1.State = UILightState.Off;
|
||
}
|
||
//高温指示
|
||
bool[] highStatus = _modbusMaster?.ReadCoils(1, 32, 1);
|
||
if (highStatus[0])
|
||
{
|
||
uiLight2.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight2.State = UILightState.Off;
|
||
}
|
||
//进气阀指示
|
||
bool[] valve1 = _modbusMaster?.ReadCoils(1, 14, 1);
|
||
if (valve1[0])
|
||
{
|
||
uiLight3.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight3.State = UILightState.Off;
|
||
}
|
||
//测试高压阀指示
|
||
bool[] valve2 = _modbusMaster?.ReadCoils(1, 8, 1);
|
||
if (valve2[0])
|
||
{
|
||
uiLight4.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight4.State = UILightState.Off;
|
||
}
|
||
//常温抽水阀指示
|
||
bool[] valve3 = _modbusMaster?.ReadCoils(1, 6, 1);
|
||
if (valve3[0])
|
||
{
|
||
uiLight5.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight5.State = UILightState.Off;
|
||
}
|
||
//常温水箱加水阀指示
|
||
bool[] valve4 = _modbusMaster?.ReadCoils(1, 13, 1);
|
||
if (valve4[0])
|
||
{
|
||
uiLight6.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight6.State = UILightState.Off;
|
||
}
|
||
//高温抽水阀指示
|
||
bool[] valve5 = _modbusMaster?.ReadCoils(1, 5, 1);
|
||
if (valve5[0])
|
||
{
|
||
uiLight7.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight7.State = UILightState.Off;
|
||
}
|
||
//空气抽气阀指示
|
||
bool[] valve6 = _modbusMaster?.ReadCoils(1, 7, 1);
|
||
if (valve6[0])
|
||
{
|
||
uiLight8.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight8.State = UILightState.Off;
|
||
}
|
||
//升温阀
|
||
|
||
//常温回水阀指示
|
||
bool[] valve8 = _modbusMaster?.ReadCoils(1, 10, 1);
|
||
if (valve8[0])
|
||
{
|
||
uiLight10.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight10.State = UILightState.Off;
|
||
}
|
||
//高温水箱加水阀指示
|
||
bool[] valve9 = _modbusMaster?.ReadCoils(1, 12, 1);
|
||
if (valve9[0])
|
||
{
|
||
uiLight11.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight11.State = UILightState.Off;
|
||
}
|
||
//高温回水阀指示
|
||
bool[] valve10 = _modbusMaster?.ReadCoils(1, 9, 1);
|
||
if (valve10[0])
|
||
{
|
||
uiLight12.State = UILightState.On;
|
||
}
|
||
else
|
||
{
|
||
uiLight12.State = UILightState.Off;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
this.Invoke(new Action(() =>
|
||
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)));
|
||
}
|
||
}
|
||
|
||
|
||
//系数页
|
||
private void uiButton14_Click(object sender, EventArgs e)
|
||
{
|
||
//FormManager.Instance.SwitchTo<Coeffiicientsetting>();
|
||
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;
|
||
}
|
||
|
||
void BoolSignal1_OnRisingEdge()
|
||
{
|
||
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
|
||
});
|
||
}
|
||
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();
|
||
|
||
// 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();
|
||
this.Show();
|
||
this.Activate();
|
||
}));
|
||
};
|
||
}
|
||
else
|
||
{
|
||
windowInstance.Activate();
|
||
return;
|
||
}
|
||
|
||
this.Hide();
|
||
windowInstance.Show();
|
||
}
|
||
|
||
private void NormalTemperatureMode_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
// 停止定时器
|
||
_readTimer?.Stop();
|
||
_readTimer?.Dispose();
|
||
|
||
// 仅用户主动关闭时退出应用
|
||
if (e.CloseReason == CloseReason.UserClosing)
|
||
{
|
||
ModbusResourceManager.Instance?.Dispose();
|
||
Application.Exit();
|
||
}
|
||
}
|
||
|
||
private void NormalTemperatureMode_FormClosed_1(object sender, FormClosedEventArgs e)
|
||
{
|
||
_coeffiicientsetting?.Dispose();
|
||
_highTemperatureMode?.Dispose();
|
||
}
|
||
|
||
//压力设置
|
||
private void uiTextBox1_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 400, Function.DataType.浮点型);
|
||
}
|
||
|
||
//测试保压时间设置
|
||
private void uiTextBox5_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 404, Function.DataType.整形);
|
||
}
|
||
//系统排气
|
||
private void uiButton11_Click_1(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 70);
|
||
}
|
||
//系统加水
|
||
private void uiButton13_Click(object sender, EventArgs e)
|
||
{
|
||
//ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 11);
|
||
}
|
||
//高温模式
|
||
private void uiSwitch1_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 30);
|
||
}
|
||
//测试按钮
|
||
private void uiButton2_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 80);
|
||
}
|
||
//停止按钮
|
||
private void uiButton3_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 82);
|
||
}
|
||
|
||
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(), 402, Function.DataType.整形);
|
||
}
|
||
}
|
||
}
|