Files

576 lines
20 KiB
C#
Raw Permalink Normal View History

2026-02-07 10:58:56 +08:00
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.Tasks;
using System.Windows.Forms;
using .Data;
using static .EasyassemblyTest;
namespace
{
public partial class LeakageTest : UIForm
{
private TestScreen _TestScreen;
private WeepingTest _WeepingTest;
private LeakageTest _LeakageTest;
private LeakageReport _LeakageReport;
private SeparatTest _SeparartTest;
private UnsrewtorqueTest _UnsrewtorqueTest;
private EasyassemblyTest _EasyassembleTest;
private OverloadresTest _OverloadresTest;
private StresscrackTest _StresscrackTest;
private UncrewseptorqueTest _UncrewseptorqueTest;
protected List<LeakageReportRecord> leakageReports = new List<LeakageReportRecord>();
Timer Timer;
private Timer _longPressTimer;
private int _currentButtonId = -1;
// 记录触摸按下的起始时间,用于区分单击和长按(可选)
private DateTime _touchDownTime;
// 长按判定阈值(毫秒),可调整
private const int LongPressThreshold = 200;
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
Function ma;
DataChange c;
public LeakageTest()
{
InitializeComponent();
Timer = new Timer();
Timer.Tick += Timer_Tick;
Timer.Interval = 300;
Timer.Start();
_longPressTimer = new Timer();
_longPressTimer.Interval = 100; // 长按持续触发间隔
_longPressTimer.Tick += LongPressTimer_Tick;
// 绑定适配触摸的按钮事件
BindTouchCompatibleEvents(uiButton11, 10);
BindTouchCompatibleEvents(uiButton12, 11);
BindTouchCompatibleEvents(uiButton13, 12);
BindTouchCompatibleEvents(uiButton14, 13);
}
private void BindTouchCompatibleEvents(UIButton button, int buttonId)
{
// 核心:使用 MouseDown/MouseUp触摸会自动触发并优化触摸体验
button.MouseDown += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
{
_touchDownTime = DateTime.Now;
_currentButtonId = buttonId;
// 触摸/鼠标按下时,先启动一个短延迟再触发定时器(避免单击误触发长按)
var delayTimer = new Timer { Interval = LongPressThreshold };
delayTimer.Tick += (s, args) =>
{
delayTimer.Stop();
delayTimer.Dispose();
// 判定为长按,启动持续触发
_longPressTimer.Start();
};
delayTimer.Start();
}
};
// 触摸抬起/离开均停止触发
button.MouseUp += (sender, e) => StopLongPress();
button.MouseLeave += (sender, e) => StopLongPress();
// 额外屏蔽默认的Click事件重复触发触摸可能导致Click和MouseDown双重触发
button.Click += (sender, e) =>
{
// 只有按下时间短于长按阈值才执行Click避免重复
var pressDuration = (DateTime.Now - _touchDownTime).TotalMilliseconds;
if (pressDuration < LongPressThreshold)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10);
}
};
}
/// <summary>
/// 停止长按触发的统一方法
/// </summary>
private void StopLongPress()
{
if (_currentButtonId == 10)
{
_modbusMaster.WriteSingleCoil(1, 10, false);
}
if (_currentButtonId == 11)
{
_modbusMaster.WriteSingleCoil(1, 11, false);
}
if (_currentButtonId == 12)
{
_modbusMaster.WriteSingleCoil(1, 12, false);
}
if (_currentButtonId == 13)
{
_modbusMaster.WriteSingleCoil(1, 13, false);
}
_longPressTimer.Stop();
_currentButtonId = -1;
}
private void LongPressTimer_Tick(object sender, EventArgs e)
{
if (_currentButtonId != -1)
{
if (_currentButtonId == 10)
_modbusMaster.WriteSingleCoil(1, 10, true);
if (_currentButtonId == 11)
_modbusMaster.WriteSingleCoil(1, 11, true);
if (_currentButtonId == 12)
_modbusMaster.WriteSingleCoil(1, 12, true);
if (_currentButtonId == 13)
_modbusMaster.WriteSingleCoil(1, 13, true);
}
}
private void Timer_Tick(object sender, EventArgs e)
{
//时间显示
Lab_time.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//装夹轴向力D
ushort[] force = _modbusMaster?.ReadHoldingRegisters(1, 1130, 2);
var value = c.UshortToFloat(force[1], force[0]);
lb_axclampforce.Text = value.ToString("F2");
//装配扭矩D
ushort[] torque = _modbusMaster?.ReadHoldingRegisters(1, 1180, 2);
var value1 = c.UshortToFloat(torque[1], torque[0]);
lb_assemblytorque.Text = value1.ToString("F3");
//气体压力D
ushort[] gaspressure = _modbusMaster?.ReadHoldingRegisters(1, 1230, 2);
var value2 = c.UshortToFloat(gaspressure[1], gaspressure[0]);
lb_gaspressure.Text = value2.ToString("F1");
//漏气持续时间D
ushort[] airleakagetime = _modbusMaster?.ReadHoldingRegisters(1, 112, 1);
float value3 = airleakagetime[0];
lb_airleagelengthtime.Text = value3.ToString("F0");
//泄漏率D
ushort[] leakrate = _modbusMaster?.ReadHoldingRegisters(1, 118, 2);
var value4 = c.UshortToFloat(leakrate[1], leakrate[0]);
lb_leakagerate.Text = value4.ToString("F6");
//初始压力
ushort[] startpressure = _modbusMaster?.ReadHoldingRegisters(1, 114, 2);
var value7 = c.UshortToFloat(startpressure[1], startpressure[0]);
lb_startpressure.Text = value7.ToString("F1");
//结束压力
ushort[] endpressure = _modbusMaster?.ReadHoldingRegisters(1, 116, 2);
var value8 = c.UshortToFloat(endpressure[1], endpressure[0]);
lb_endpressure.Text = value8.ToString("F1");
//角度D
ushort[] angle = _modbusMaster?.ReadHoldingRegisters(1, 42, 2);
var value9 = c.UshortToFloat(angle[1], angle[0]);
lb_angle.Text = value9.ToString("F1");
//滑台D
ushort[] slipway = _modbusMaster?.ReadHoldingRegisters(1, 46, 2);
var value10 = c.UshortToFloat(slipway[1], slipway[0]);
lb_slip.Text = value10.ToString("F1");
//正负压切换
bool[] buttonStatus = _modbusMaster?.ReadCoils(1, 62, 1);
if (buttonStatus[0])
{
btn_dsqh.Active = true;
}
else
{
btn_dsqh.Active = false;
}
//测试按钮
bool[] testStatus = _modbusMaster?.ReadCoils(1, 110, 1);
if (testStatus[0])
{
uiButton18.Text = "测试中";
uiButton18.ForeColor = System.Drawing.Color.Green;
}
else
{
uiButton18.Text = "测试";
uiButton18.ForeColor = System.Drawing.Color.Black;
}
//计时按钮
bool[] timeStatus = _modbusMaster?.ReadCoils(1, 114, 1);
if (timeStatus[0])
{
uiButton16.Text = "计时中";
uiButton16.ForeColor = System.Drawing.Color.Green;
}
else
{
uiButton16.Text = "计时";
uiButton16.ForeColor = System.Drawing.Color.Black;
}
//是否合格
bool[] isOk = _modbusMaster?.ReadCoils(1, 116, 2);
if (isOk[0])
{
lb_ok.Visible = true;
_modbusMaster?.ReadCoils(1, 116, 1);
lb_ok.Text = "合格";
lb_ok.ForeColor = System.Drawing.Color.Green;
}
else
{
lb_ok.Visible = false;
}
if (isOk[1])
{
lb_notok.Visible = true;
lb_notok.Text = "不合格";
lb_notok.ForeColor = System.Drawing.Color.Green;
}
else
{
lb_notok.Visible = false;
}
//复位灯
bool[] resetStatus = _modbusMaster?.ReadCoils(1, 92, 1);
if (resetStatus[0])
{
uiLight2.OnColor = System.Drawing.Color.Green;
}
else
{
uiLight2.OnColor = System.Drawing.Color.Red;
}
//实验灯
bool[] conditionStatus = _modbusMaster?.ReadCoils(1, 82, 1);
if (conditionStatus[0])
{
uiLight1.OnColor = System.Drawing.Color.Green;
}
else
{
uiLight1.OnColor = System.Drawing.Color.Red;
}
bool[] result = _modbusMaster.ReadCoils(1, 112, 1);
{
if (result[0])
{
ushort[] location = _modbusMaster.ReadHoldingRegisters(1, 1080, 12);
float leakageforce = c.UshortToFloat(location[1], location[0]);//f
float leakagetorque = c.UshortToFloat(location[3], location[2]);//f
int leakagekeepingtime = location[4];
float leakagestartpressure = c.UshortToFloat(location[7], location[6]);//f
float leakageendpressure = c.UshortToFloat(location[9], location[8]);//f
float leakagerate = c.UshortToFloat(location[11], location[10]);//f
LeakageReportRecord r = new LeakageReportRecord()
{
Num = leakageReports.Count + 1,
Createtime = DateTime.Now,
Force = leakageforce,
Torque = leakagetorque,
Keeppressuretime = leakagekeepingtime,
Startpressure = leakagestartpressure,
Endpressure = leakageendpressure,
Leakrate = leakagerate,
};
AddLeakage(r);
}
}
}
//返回
private void Btn_return_Click(object sender, EventArgs e)
{
SwitchWindow(ref _TestScreen, () => new TestScreen());
}
private void AddLeakage(LeakageReportRecord report)
{
leakageReports.Add(report);
}
private void LeakageTest_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;
}
ma = new Function(_modbusMaster);
c = new DataChange();
//_readTimer.Start();
MessageBox.Show(
"此界面包含三项实验\n分别为:GB/T1962.2标准要求测漏气实验\nYY0916.7标准要求正压衰减实验、负压衰减实验\nISO080369-7标准要求测正、负压衰减\n请通过选择测试项目选择页面选择测试标准。",
"提示",
MessageBoxButtons.OK,
MessageBoxIcon.Information
);
}
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
{
// 1. 停止当前窗口的定时器(不释放资源)
Timer?.Stop();
// 2. 检查资源是否可用(添加重连机制)
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
// 尝试重新连接
bool reconnectSuccess = TryReconnect();
if (!reconnectSuccess)
{
MessageBox.Show("TCP连接已断开请重新连接", "提示");
return;
}
}
// 3. 复用窗口实例:不存在则创建,存在则激活
if (windowInstance == null)
{
windowInstance = createFunc();
// 添加窗口关闭事件处理
windowInstance.Closed += (s, args) =>
{
// 窗口关闭时重新启动定时器并显示当前窗口
//_readTimer?.Start();
//this.Show();
this.Activate();
};
}
else
{
// 激活已存在的窗口(前置显示)
windowInstance.Activate();
return;
}
// 4. 切换窗口:隐藏当前窗口,显示目标窗口(非模态)
this.Hide();
windowInstance.Show(); // 使用 Show() 而不是 ShowDialog()
}
private void LeakageTest_FormClosed(object sender, FormClosedEventArgs e)
{
_WeepingTest?.Close(); //关闭漏液实验窗口
//_LeakageTest?.Close(); // 若主窗口无需关闭自身,保持注释
_SeparartTest?.Close(); // 关闭分离力实验窗口
_UnsrewtorqueTest?.Close(); // 关闭旋开扭矩实验窗口
_EasyassembleTest?.Close(); // 关闭易装配性实验窗口
_OverloadresTest?.Close();// 关闭抗过载性实验窗口
_StresscrackTest?.Close();// 关闭应力开裂实验窗口
_UncrewseptorqueTest?.Close();// 关闭旋开分离扭力实验窗口
}
private void LeakageTest_FormClosing(object sender, FormClosingEventArgs e)
{
// 停止定时器
Timer?.Stop();
Timer?.Dispose(); // 释放主定时器
_longPressTimer?.Stop();
_longPressTimer?.Dispose(); // 释放长按定时器
// 释放Modbus资源
ModbusResourceManager.Instance?.Dispose();
// 确保应用程序完全退出
Application.Exit();
}
//窗口转换
private void uiButton2_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 30, true);
SwitchWindow(ref _WeepingTest, () => new WeepingTest());
}
private void uiButton3_Click(object sender, EventArgs e)
{
//SwitchWindow(ref _LeakageTest, () => new LeakageTest(testScreen));
}
private void uiButton6_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 32, true);
SwitchWindow(ref _SeparartTest, () => new SeparatTest());
}
private void uiButton7_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 33, true);
SwitchWindow(ref _UnsrewtorqueTest, () => new UnsrewtorqueTest());
}
private void uiButton8_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 34, true);
SwitchWindow(ref _EasyassembleTest, () => new EasyassemblyTest());
}
private void uiButton9_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 35, true);
SwitchWindow(ref _OverloadresTest, () => new OverloadresTest());
}
private void uiButton10_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 36, true);
SwitchWindow(ref _StresscrackTest, () => new StresscrackTest());
}
private void uiButton1_Click(object sender, EventArgs e)
{
_modbusMaster.WriteSingleCoil(1, 37, true);
SwitchWindow(ref _UncrewseptorqueTest, () => new UncrewseptorqueTest());
}
//复位按钮
private void uiButton15_Click(object sender, EventArgs e)
{
ma.BtnClickFunctionForNew(Function.ButtonType., 95);
bool result = UIMessageBox.ShowAsk("确保夹具已松开!", true, UIMessageDialogButtons.Ok);
if (result)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 90);
}
else
{
ma.BtnClickFunctionForNew(Function.ButtonType., 95);
}
}
//停止按钮
private void uiButton19_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 113);
}
//打印按钮
private void uiButton17_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 15);
}
//记录按钮
private void uiButton20_Click(object sender, EventArgs e)
{
SwitchWindow<LeakageReport>(ref _LeakageReport, () => new LeakageReport(leakageReports));
}
//正转按钮
private void uiButton11_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 10);
}
//反转按钮
private void uiButton12_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 11);
}
//前进按钮
private void uiButton13_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 12);
}
//后退按钮
private void uiButton14_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 13);
}
public class LeakageReportRecord
{
public int? Num { get; set; }//编号
public DateTime? Createtime { get; set; }//日期时间
public float? Force { get; set; } //轴向力
public float? Torque { get; set; }//扭矩力
public int? Keeppressuretime { get; set; }//保压计时
public float? Startpressure { get; set; }//初始压力
public float? Endpressure { get; set; }//结束压力
public float? Leakrate { get; set; }//泄漏率
}
//正负压
private void btn_dsqh_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 62);
}
//测试
private void uiButton18_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 110);
}
//计时
private void uiButton16_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 114);
}
}
}