using HslCommunication.Profinet.Melsec; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Excel = Microsoft.Office.Interop.Excel; using EasyModbus; using DocumentFormat.OpenXml.Bibliography; using DocumentFormat.OpenXml.EMMA; using Guna.UI2.WinForms.Suite; using System.IO.Ports; using DocumentFormat.OpenXml.Drawing; using Sunny.UI; using WindowsFormsApp1; using Spire.Xls.Core; using Newtonsoft.Json.Linq; using static System.Windows.Forms.VisualStyles.VisualStyleElement; using C_Windows_1; using static C_Windows_1.MES; using System.Reflection.Emit; using static SLC1_N.DataUp; using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header; using DocumentFormat.OpenXml.Office2016.Excel; using System.Web.Services.Description; using Microsoft.VisualBasic.Logging; namespace SLC1_N { public partial class Form1 : Form { public static Form1 f1; private readonly WindowAutoResizer resizer; // readonly 只能在 声明时初始化或在类的构造函数中赋值,之后不能被修改(不可重新赋值) private CancellationTokenSource cts; // 用于协调任务的取消操作 public string User; // 记录当前用户 public ModbusTCP_28 LL28CH1client; // 28客户端线程类 public ModbusTCP_28 LL28CH2client; public ModbusTCP_28 LL28CH3client; // 28客户端线程类 public ModbusTCP_28 LL28CH4client; public SaomaClient saomaClient1; // 扫码枪客户端 public SaomaClient saomaClient2; public string localipaddress; // 本机IP public string ch1ipaddress; // 记录仪器CH1的IP地址 public string ch2ipaddress; // 记录仪器CH2的IP地址 public string ch3ipaddress; // 记录仪器CH3的IP地址 public string ch4ipaddress; // 记录仪器CH4的IP地址 ProductionRecord m_production = new ProductionRecord(); // 产能记录 public FileSave filesave; // 保存文件设置 public static bool m_MESswitch = false; // MES开关 public bool m_ContinueTest; // 连续测试 public int m_ContinueTestCount; // 连续次数 public delegate void MySignalHandler(int msg, bool mode); // 声明信号 public event MySignalHandler Signal_SaomaStart; // 定义信号 public event MySignalHandler Signal_PLCStatus; // 定义信号 // PLC客户端初始化 // ModbusClient modbusClient = new ModbusClient("192.168.1.88", 502); // ModbusClient modbusClient = new ModbusClient("127.0.0.1", 502); //ModbusClient modbusClient; public ModbusClient HCPLC_client = new ModbusClient(); // 主界面 public Form1() { Control.CheckForIllegalCrossThreadCalls = false; // 禁用跨线程访问控件的异常检查 InitializeComponent(); resizer = new WindowAutoResizer(this); f1 = this; InitializeAfterLoadAsync(); } // 主窗口初始化 private void Form1_Load(object sender, EventArgs e) { // 启用线程检查 //Control.CheckForIllegalCrossThreadCalls = true; // 界面初始化 tb_CH1Code.Text = ""; tb_CH2Code.Text = ""; lb_CH1_Result.Text = " "; lb_CH2_Result.Text = " "; tb_CH3Code.Text = ""; tb_CH4Code.Text = ""; lb_CH3_Result.Text = " "; lb_CH4_Result.Text = " "; // DataGridView 行自动调整高度 DataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; DataGridView2.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; User = "操作员"; lb_User.Text = "操作员"; // 清理log文件 保留近30天 Task.Run(() => { mxlLog.Instance.ClearOldLogs(30); }); // 显示时间 timer_nowTime.Start(); // 定时清理垃圾 timer1.Interval = 50000; timer1.Start(); // 用户重置 UserClear.Interval = 600000; UserClear.Start(); // 发送扫码启动 timer_SaomaStart.Interval = 500; //timer_SaomaStart.Start(); // 间隔8S清除消息框 if (lb_User.Text == "操作员") { tb_CH1codeLeng.Enabled = false; tb_CH2codeLeng.Enabled = false; tb_CH3codeLeng.Enabled = false; tb_CH4codeLeng.Enabled = false; } // 产能初始化 Production_Init(); // 标志位初始化 Flag_Init(); // 仪器客户端初始化 CHXclient_Init(); // 仪器参数初始 yiqiParamInit(); // 初始化CancellationTokenSource cts = new CancellationTokenSource(); // 创建了取消令牌源 cts Task.Run(() => RunMachine(cts.Token), cts.Token); // 将令牌传递给后台任务 第二个cts.Token 确保任务异常时能自动取消 Task.Run(() => RunMachine2(cts.Token), cts.Token); Task.Run(() => RunMachine3(cts.Token), cts.Token); Task.Run(() => RunMachine4(cts.Token), cts.Token); // 扫码枪初始化 var jsconfig = new JsonConfig("config.json"); string saoma = jsconfig.GetValue("CodeScanner", "SerialPort"); if(saoma == "SerialPort") { // 串口扫码枪初始化 SerialPort_Saoma_Init(); } else if (saoma == "TCP") { // TCP扫码枪初始化 TCPSaoma_Init(); } // MES初始化 MES_Init(); // PLC客户端初始化 PLCclient_Init(); PLC_Alarm(); if (Environment.MachineName.Trim() == "PC-20230419CFZS") // 计算机名 { lb_User.Text = "厂商"; User = "厂商"; bt_test.Visible = true; bt_test2.Visible = true; } tb_CH1Code.Focus(); timer2.Interval = 4000; timer2.Start(); } bool[] coil1100 = new bool[14]; bool[] coil1032 = new bool[8]; public bool[] coilSaoma = new bool[4]; // PLC警报 void PLC_Alarm() { Task.Run(() => { while (true) { Thread.Sleep(1000); for (int i = 0; i < coil1100.Length; i++) { string address = $"M{1100 + i}"; AlarmManager.UpdateAlarm(address, coil1100[i]); } for (int i = 0; i < coil1032.Length; i++) { if(i < 4) { //Console.WriteLine($"{i}-{coil1032[i]}"); string address = $"M{1032 + i}"; AlarmManager.UpdateAlarm(address, coil1032[i]); //Console.WriteLine($"{i}-弹窗 {AlarmManager.isShow} - {AlarmManager.nowAlarmMessage}"); } } } }); } private async void InitializeAfterLoadAsync() { // 等待窗口完全初始化 await Task.Delay(100); InitializeAfterLoad(); } private void InitializeAfterLoad() { } // 显示槽 private void Slot_MainShow(bool mode) { this.Show(); this.Enabled = mode; if(!mode) { this.Close(); } } // 产能初始化 private void Production_Init() { UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 更新产能 } // MES数据 public string mes_partno; // 料号 public string mes_station; // 工站名称 public string mes_workorder; // 工单 public string mes_equipmentno; // 设备编号 public string mes_fixturecode; // 夹具编号 public string mes_plan; // 工厂 // MES初始化 private void MES_Init() { var jsconfig = new JsonConfig("config.json"); m_LINE = jsconfig.GetValue("LINE", "1"); m_ActionName = jsconfig.GetValue("ActionName", " "); m_Tools = jsconfig.GetValue("Tools", " "); // MES开关 m_MESswitch = jsconfig.GetValue("MESswitch", false); if (m_MESswitch && HQMES_Init()) { lb_MESswitch.Text = "MES在线"; pb_MESswitch.BackColor = Color.Green; } else { m_MESswitch = false; lb_MESswitch.Text = "MES离线"; pb_MESswitch.BackColor = Color.Red; } } // 标志位初始化 private void Flag_Init() { var jsconfig = new JsonConfig("config.json"); //Console.WriteLine($"实际加载的JSON内容: {jsconfig.ShowAllValues()}"); // 条码长度 tb_CH1codeLeng.Text = jsconfig.GetValue("CodeLength1", "9"); tb_CH2codeLeng.Text = jsconfig.GetValue("CodeLength2", "9"); tb_CH3codeLeng.Text = jsconfig.GetValue("CodeLength3", "9"); tb_CH4codeLeng.Text = jsconfig.GetValue("CodeLength4", "9"); // 连续测试/次数 m_ContinueTest = jsconfig.GetValue("chk_ContinueTest", true); m_ContinueTestCount = jsconfig.GetValue("tb_ContinueTestCount", 1); // 日志使能 mxlLog.Instance.IsDebugEnabled = jsconfig.GetValue("IsDebugEnabled", false); mxlLog.Instance.IsErrorEnabled = jsconfig.GetValue("IsErrorEnabled", false); mxlLog.Instance.IsInfoEnabled = jsconfig.GetValue("IsInfoEnabled", false); mxlLog.Instance.IsWarningEnabled = jsconfig.GetValue("IsWarningEnabled", false); mxlLog.Instance.IsXXXEnabled = jsconfig.GetValue("IsXXXEnabled", false); // MES开关 m_MESswitch = jsconfig.GetValue("MESswitch", false); if (m_MESswitch) { lb_MESswitch.Text = "MES在线"; pb_MESswitch.BackColor = Color.Green; } else { lb_MESswitch.Text = "MES离线"; pb_MESswitch.BackColor = Color.Red; } // 仪器ip if (string.IsNullOrEmpty(ch1ipaddress)) { ch1ipaddress = jsconfig.GetValue("ch1ipaddress", "192.168.1.131"); } if (string.IsNullOrEmpty(ch2ipaddress)) { ch2ipaddress = jsconfig.GetValue("ch2ipaddress", "192.168.1.130"); } if (string.IsNullOrEmpty(ch3ipaddress)) { ch3ipaddress = jsconfig.GetValue("ch3ipaddress", "192.168.1.129"); } if (string.IsNullOrEmpty(ch4ipaddress)) { ch4ipaddress = jsconfig.GetValue("ch4ipaddress", "192.168.1.128"); } ch1AutoConnect = jsconfig.GetValue("ch1AutoConnect", true); ch2AutoConnect = jsconfig.GetValue("ch2AutoConnect", true); ch3AutoConnect = jsconfig.GetValue("ch3AutoConnect", true); ch4AutoConnect = jsconfig.GetValue("ch4AutoConnect", true); // 写入文件 标志位 filesave = new FileSave(); filesave.TXT = jsconfig.GetValue("TXT", false); filesave.Excel = jsconfig.GetValue("Excel", false); filesave.CSV = jsconfig.GetValue("CSV", false); filesave.Path = jsconfig.GetValue("FilePath", ""); } // 仪器客户端初始化 private void CHXclient_Init() { // 线程客户端初始化 // 通道1 if (LL28CH1client == null) { LL28CH1client = new ModbusTCP_28(1); LL28CH1client.Connect(ch1ipaddress); LL28CH1client.Start(); } // 通道2 if (LL28CH2client == null) { LL28CH2client = new ModbusTCP_28(2); LL28CH2client.Connect(ch2ipaddress); LL28CH2client.Start(); } // 通道3 if (LL28CH3client == null) { LL28CH3client = new ModbusTCP_28(3); LL28CH3client.Connect(ch3ipaddress); LL28CH3client.Start(); } // 通道4 if (LL28CH4client == null) { LL28CH4client = new ModbusTCP_28(4); LL28CH4client.Connect(ch4ipaddress); LL28CH4client.Start(); } timer_yiqiRun.Interval = 500; timer_yiqiRun.Start(); // 定时器 监控仪器通讯状态 } public readonly object plcLock = new object(); // PLC客户端初始化 private void PLCclient_Init() { var jsconfig = new JsonConfig("config.json"); // PLC地址 string plcip = jsconfig.GetValue("PLC_IP", "192.168.1.88"); int plcport = jsconfig.GetValue("PLC_Port", 502); HCPLC_client = new ModbusClient(plcip, plcport); // 绑定PLC状态信号 Signal_PLCStatus += Slot_PLCStatus; // PLC io监控 Task.Run(() => { while (true) { Thread.Sleep(500); try { if (HCPLC_client.Connected == false) { Signal_PLCStatus?.Invoke(0, false); // 更新PLC连接状态UI HCPLC_client.Connect(); } else { HCPLC_client.ReadHoldingRegisters(1, 1); // 如果失败,会抛异常 Thread.Sleep(10); Signal_PLCStatus?.Invoke(0, true); // 更新PLC连接状态UI coilSaoma = HCPLC_client.ReadCoils(1012, 4); // CHx正在复位 bool[] coil1016 = HCPLC_client.ReadCoils(1016, 4); if (coil1016.Length >= 4) { if (coil1016[0]) // 通道1 { // CH1正在复位 } if (coil1016[1]) // 通道3 { } if (coil1016[2]) // 通道3 { } if (coil1016[3]) // 通道4 { } } Thread.Sleep(10); coil1032 = HCPLC_client.ReadCoils(1032, 8); //if (coil1032.Length >= 8) //{ // AlarmManager.UpdateAlarm("M1032", coil1032[0]); // CHx通道异常 // AlarmManager.UpdateAlarm("M1033", coil1032[1]); // AlarmManager.UpdateAlarm("M1034", coil1032[2]); // AlarmManager.UpdateAlarm("M1035", coil1032[3]); // // CHx仪器阀门控制点 // if (coil1032[4]) // 通道1 // { // } // if (coil1032[5]) // 通道3 // { // } // if (coil1032[6]) // 通道3 // { // } // if (coil1032[7]) // 通道4 // { // } //} Thread.Sleep(10); // 警报弹窗提示 coil1100 = HCPLC_client.ReadCoils(1100, 14); } } catch (Exception ex) { Signal_PLCStatus?.Invoke(0, false); // 更新PLC连接状态UI Thread.Sleep(1000); } } }); } // 串口扫码使能 public bool serialport_saoma_Enabled = false; // 串口扫码枪初始化 private void SerialPort_Saoma_Init() { try { serialport_saoma_Enabled = true; var jsconfig = new JsonConfig("config.json"); int SerialPort_CH1BaudRate = jsconfig.GetValue("SerialPort_CH1BaudRate", 9600); string SerialPort_CH1PortName = jsconfig.GetValue("SerialPort_CH1PortName", "COM21"); int SerialPort_CH2BaudRate = jsconfig.GetValue("SerialPort_CH2BaudRate", 9600); string SerialPort_CH2PortName = jsconfig.GetValue("SerialPort_CH2PortName", "COM11"); int SerialPort_CH3BaudRate = jsconfig.GetValue("SerialPort_CH3BaudRate", 9600); string SerialPort_CH3PortName = jsconfig.GetValue("SerialPort_CH3PortName", "COM11"); int SerialPort_CH4BaudRate = jsconfig.GetValue("SerialPort_CH4BaudRate", 9600); string SerialPort_CH4PortName = jsconfig.GetValue("SerialPort_CH4PortName", "COM11"); //设置端口的参数,包括波特率等 // 扫码枪1 SerialPort_CH1Saoma.BaudRate = SerialPort_CH1BaudRate; SerialPort_CH1Saoma.PortName = SerialPort_CH1PortName; SerialPort_CH1Saoma.DataBits = 8; SerialPort_CH1Saoma.StopBits = System.IO.Ports.StopBits.One; SerialPort_CH1Saoma.Parity = System.IO.Ports.Parity.None; SerialPort_CH1Saoma.Open(); if (SerialPort_CH1Saoma.IsOpen) { Console.WriteLine($"SerialPort_CH1Saoma: T"); } else { Console.WriteLine($"SerialPort_CH1Saoma: F"); SetUITextBox(tb_CH1MainMessage, $"CH1串口扫码枪打开失败"); } // 扫码枪2 SerialPort_CH2Saoma.BaudRate = SerialPort_CH2BaudRate; SerialPort_CH2Saoma.PortName = SerialPort_CH2PortName; SerialPort_CH2Saoma.DataBits = 8; SerialPort_CH2Saoma.StopBits = System.IO.Ports.StopBits.One; SerialPort_CH2Saoma.Parity = System.IO.Ports.Parity.None; SerialPort_CH2Saoma.Open(); if (SerialPort_CH2Saoma.IsOpen) { Console.WriteLine($"SerialPort_CH2Saoma: T"); } else { Console.WriteLine($"SerialPort_CH2Saoma: F"); SetUITextBox(tb_CH2MainMessage, $"CH2串口扫码枪打开失败"); } // 扫码枪3 SerialPort_CH3Saoma.BaudRate = SerialPort_CH3BaudRate; SerialPort_CH3Saoma.PortName = SerialPort_CH3PortName; SerialPort_CH3Saoma.DataBits = 8; SerialPort_CH3Saoma.StopBits = System.IO.Ports.StopBits.One; SerialPort_CH3Saoma.Parity = System.IO.Ports.Parity.None; SerialPort_CH3Saoma.Open(); if (SerialPort_CH3Saoma.IsOpen) { Console.WriteLine($"SerialPort_CH3Saoma: T"); } else { Console.WriteLine($"SerialPort_CH3Saoma: F"); SetUITextBox(tb_CH1MainMessage, $"CH3串口扫码枪打开失败"); } // 扫码枪4 SerialPort_CH4Saoma.BaudRate = SerialPort_CH4BaudRate; SerialPort_CH4Saoma.PortName = SerialPort_CH4PortName; SerialPort_CH4Saoma.DataBits = 8; SerialPort_CH4Saoma.StopBits = System.IO.Ports.StopBits.One; SerialPort_CH4Saoma.Parity = System.IO.Ports.Parity.None; SerialPort_CH4Saoma.Open(); if (SerialPort_CH4Saoma.IsOpen) { Console.WriteLine($"SerialPort_CH4Saoma: T"); } else { Console.WriteLine($"SerialPort_CH4Saoma: F"); SetUITextBox(tb_CH2MainMessage, $"CH4串口扫码枪打开失败"); } } catch (Exception ex) { Console.WriteLine($"串口扫码枪初始化 异常,行号{ex.StackTrace},{ex.Message}"); mxlLog.Instance.Error($"串口扫码枪初始化 异常 ,行号{ex.StackTrace} ", ex); } } // 网口扫码使能 public bool tcpSaoma_Enabled = false; // TCP扫码枪初始化 private void TCPSaoma_Init() { tcpSaoma_Enabled = true; var jsconfig = new JsonConfig("config.json"); // 扫码枪客户端初始化 string smip1 = jsconfig.GetValue("Saoma_IP1", "127.0.0.1"); int smport1 = jsconfig.GetValue("Saoma_Port1", 51111); string smip2 = jsconfig.GetValue("Saoma_IP2", "127.0.0.1"); int smport2 = jsconfig.GetValue("Saoma_Port2", 52222); saomaClient1 = new SaomaClient( smip1, // IP地址 smport1, // 端口号 Convert.ToInt32(tb_CH1codeLeng.Text), // 条码长度 code => { TCPCode_DataReceived(1, code); }, error => { mxlLog.Instance.Error($"CH1 {error} "); }, status => { SetUITextBox(tb_CH1MainMessage, $"CH1 {status} "); }); saomaClient2 = new SaomaClient( smip2, // IP地址 smport2, // 端口号 Convert.ToInt32(tb_CH2codeLeng.Text), // 条码长度 code => { TCPCode_DataReceived(2, code); }, error => { mxlLog.Instance.Error($"CH2 {error} "); }, status => { SetUITextBox(tb_CH2MainMessage, $"CH2 {status} "); }); Task.Run(() => { saomaClient1.Connect(); saomaClient2.Connect(); }); } // PLC连接状态 private void Slot_PLCStatus(int msg, bool mode) { //Console.WriteLine($"PLC连接状态: {mode}"); if (mode) pb_PLC_CommunicationStatus.BackColor = Color.Green; else pb_PLC_CommunicationStatus.BackColor = Color.Red; } // PLC写入线圈槽函数 private async void Slot_PLC_WriteCoil(int msg, bool mode) { try { if (HCPLC_client?.Connected != true) return; // 使用Task超时控制, 防止10s太久死锁 var writeTask = Task.Run(() => { lock (plcLock) { HCPLC_client.WriteSingleCoil(msg, mode); // 写超时10s不可配置 } }); // 设置2秒超时 if (await Task.WhenAny(writeTask, Task.Delay(2000)) == writeTask) { await writeTask; // 确保任务完成 } else { mxlLog.Instance.Warning($"PLC写入超时,地址: {msg}, 模式: {mode}"); } } catch (Exception ex) { mxlLog.Instance.Error($"PLC写入槽函数异常, 地址: {msg}, 错误: {ex.Message}"); } } // 扫码启动槽 private void Slot_SaomaStart(int msg, bool mode = false) { //Console.WriteLine($"扫码启动槽: {msg}"); string data = "73 74 61 72 74"; // "start" byte[] byt = StrtoHexbyte(data); switch (msg) { case 1: // 扫码枪1启动 if (serialport_saoma_Enabled && SerialPort_CH1Saoma != null && SerialPort_CH1Saoma.IsOpen) { SerialPort_CH1Saoma.Write(byt, 0, byt.Length); } if(tcpSaoma_Enabled) saomaClient1?.SendStartCommand(); break; case 2: // 扫码枪2启动 if (serialport_saoma_Enabled && SerialPort_CH2Saoma != null && SerialPort_CH2Saoma.IsOpen) { SerialPort_CH2Saoma.Write(byt, 0, byt.Length); } if (tcpSaoma_Enabled) saomaClient2?.SendStartCommand(); break; case 3: // 扫码枪3启动 if (serialport_saoma_Enabled && SerialPort_CH3Saoma != null && SerialPort_CH3Saoma.IsOpen) { SerialPort_CH3Saoma.Write(byt, 0, byt.Length); } //if (tcpSaoma_Enabled) // saomaClient3?.SendStartCommand(); break; case 4: // 扫码枪4启动 if (serialport_saoma_Enabled && SerialPort_CH4Saoma != null && SerialPort_CH4Saoma.IsOpen) { SerialPort_CH4Saoma.Write(byt, 0, byt.Length); } //if (tcpSaoma_Enabled) // saomaClient4?.SendStartCommand(); break; } } string ch1_oldcode = ""; string ch2_oldcode = ""; // TCP收到条码 private void TCPCode_DataReceived(int CH, string code) { try { if (CH == 1) { string CODE = code.Replace("\r\n", ""); //Console.WriteLine("扫码枪1收到:" + code); if (!CODE.IsNullOrEmpty() && CODE.Length.ToString() == tb_CH1codeLeng.Text) { //SetUITextBox(tb_CH1MainMessage, "CH1 TCP扫码完成"); if(CODE == ch1_oldcode) { return; } ch1_oldcode = CODE; tb_CH1Code.Text = CODE; if (m_MESswitch) { SetLabelText(lb_CH1MES_OUTstatus, ""); var rdata = ruzhan(CODE, m_ActionName, m_Tools); if (rdata.result) { SetLabelText(lb_CH1MES_INstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH1MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH1MainMessage, $"CH1 入站NG:{rdata.msg}"); } SetLabelText(lb_CH1MES_OUTstatus, ""); } } else { SetUITextBox(tb_CH1MainMessage, "CH1 当前条形码长度为" + CODE.Length + "所设置的条码长度为" + tb_CH1codeLeng.Text); } } if (CH == 2) { string CODE = code.Replace("\r\n", ""); //Console.WriteLine("扫码枪2收到:" + code); if (!CODE.IsNullOrEmpty() && CODE.Length.ToString() == tb_CH2codeLeng.Text) { //SetUITextBox(tb_CH2MainMessage, "CH2 TCP扫码完成"); if (CODE == ch2_oldcode) { return; } ch2_oldcode = CODE; tb_CH2Code.Text = CODE; if (m_MESswitch) { SetLabelText(lb_CH2MES_OUTstatus, ""); var rdata = ruzhan(CODE, m_ActionName, m_Tools); if (rdata.result) { SetLabelText(lb_CH2MES_INstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH2MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH2MainMessage, $"CH2 入站NG:{rdata.msg}"); } SetLabelText(lb_CH2MES_OUTstatus, ""); } } else { SetUITextBox(tb_CH2MainMessage, "CH2 当前条形码长度为" + CODE.Length + "所设置的条码长度为" + tb_CH2codeLeng.Text); } } } catch (Exception ex) { // 处理MES上传异常 } } public struct RtValue { public bool result { get; set; } public string data { get; set; } public RtValue(bool Result, string Data) { result = Result; data =Data; } } public struct TestTime { public string startTime { get; set; } public string stopTime { get; set; } public TestTime(string startTime, string stopTime) { this.startTime = startTime; this.stopTime = stopTime; } } /* // MES 入站 private RtValue ruzhan(int CH, string code, string mode = null) { RtValue ruzhan_result = new RtValue(false, "##"); switch (CH) { case 1: { MES mes = new MES(urlip, urlport); var request = new MES_IN_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, fulltime = (LL28CH1client.ArrRegister[6] / 10.0).ToString(), // 充气时间 balantime = (LL28CH1client.ArrRegister[7] / 10.0).ToString(), // 平衡时间 testtime = (LL28CH1client.ArrRegister[8] / 10.0).ToString(), // 检测时间 exhausttime = (LL28CH1client.ArrRegister[9] / 10.0).ToString() // 排气时间 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 2: { MES mes = new MES(urlip, urlport); var request = new MES_IN_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, fulltime = (LL28CH2client.ArrRegister[6] / 10.0).ToString(), // 充气时间 balantime = (LL28CH2client.ArrRegister[7] / 10.0).ToString(), // 平衡时间 testtime = (LL28CH2client.ArrRegister[8] / 10.0).ToString(), // 检测时间 exhausttime = (LL28CH2client.ArrRegister[9] / 10.0).ToString() // 排气时间 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 3: { MES mes = new MES(urlip, urlport); var request = new MES_IN_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, fulltime = (LL28CH3client.ArrRegister[6] / 10.0).ToString(), // 充气时间 balantime = (LL28CH3client.ArrRegister[7] / 10.0).ToString(), // 平衡时间 testtime = (LL28CH3client.ArrRegister[8] / 10.0).ToString(), // 检测时间 exhausttime = (LL28CH3client.ArrRegister[9] / 10.0).ToString() // 排气时间 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 4: { MES mes = new MES(urlip, urlport); var request = new MES_IN_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, fulltime = (LL28CH4client.ArrRegister[6] / 10.0).ToString(), // 充气时间 balantime = (LL28CH4client.ArrRegister[7] / 10.0).ToString(), // 平衡时间 testtime = (LL28CH4client.ArrRegister[8] / 10.0).ToString(), // 检测时间 exhausttime = (LL28CH4client.ArrRegister[9] / 10.0).ToString() // 排气时间 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; } return ruzhan_result; } private RtValue chuzhan(int CH, string code, bool result, string mode = null) { RtValue ruzhan_result = new RtValue(false, "##"); switch (CH) { case 1: { MES mes = new MES(urlip, urlport); var request = new MES_OUT_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, result = result ? "OK" : "NG", TestPressure = LL28CH1client.readFloatF2(57).ToString(), // 测试压力 LeakValue = LL28CH1client.readFloatF2(38).ToString(), // 泄漏量 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 2: { MES mes = new MES(urlip, urlport); var request = new MES_OUT_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, result = result ? "OK":"NG", TestPressure = LL28CH2client.readFloatF2(57).ToString(), // 测试压力 LeakValue = LL28CH2client.readFloatF2(38).ToString(), // 泄漏量 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 3: { MES mes = new MES(urlip, urlport); var request = new MES_OUT_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, result = result ? "OK" : "NG", TestPressure = LL28CH3client.readFloatF2(57).ToString(), // 测试压力 LeakValue = LL28CH3client.readFloatF2(38).ToString(), // 泄漏量 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; case 4: { MES mes = new MES(urlip, urlport); var request = new MES_OUT_Data { time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), code = code, result = result ? "OK" : "NG", TestPressure = LL28CH4client.readFloatF2(57).ToString(), // 测试压力 LeakValue = LL28CH4client.readFloatF2(38).ToString(), // 泄漏量 }; string response = mes.UploadData(request); if (response.Contains("OK") || response.Contains("ok") || response.Contains("TRUE") || response.Contains("true") || response.Contains("PASS") || response.Contains("pass") || response.Contains("Success") || response.Contains("success")) { ruzhan_result.result = true; ruzhan_result.data = response; } else { ruzhan_result.result = false; ruzhan_result.data = response; } } break; } return ruzhan_result; } */ // 将令牌传递给后台任务 第二个cts.Token 确保任务异常时能自动取消 private void RunMachine(CancellationToken token) { ch1workstation = (int)yiqi.standby; while (!token.IsCancellationRequested) { try { Thread.Sleep(500); // 使用Thread.Sleep而不是Task.Delay,因为这是后台线程 if (!token.IsCancellationRequested) { CH1machine(); } } catch (OperationCanceledException) { break;// 任务被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"CH1状态机更新错误: {ex.Message} ,行号{ex.StackTrace}"); // 记录错误但继续运行 mxlLog.Instance.Error($"CH1状态机更新错误 ,行号{ex.StackTrace} ", ex); } } } private void RunMachine2(CancellationToken token) { ch2workstation = (int)yiqi.standby; while (!token.IsCancellationRequested) { try { Thread.Sleep(500); // 使用Thread.Sleep而不是Task.Delay,因为这是后台线程 if (!token.IsCancellationRequested) { CH2machine(); } } catch (OperationCanceledException) { break;// 任务被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"CH2状态机更新错误: {ex.Message} ,行号{ex.StackTrace}"); // 记录错误但继续运行 mxlLog.Instance.Error($"CH2状态机更新错误 ,行号{ex.StackTrace} ", ex); } } } private void RunMachine3(CancellationToken token) { ch3workstation = (int)yiqi.standby; while (!token.IsCancellationRequested) { try { Thread.Sleep(500); // 使用Thread.Sleep而不是Task.Delay,因为这是后台线程 if (!token.IsCancellationRequested) { CH3machine(); } } catch (OperationCanceledException) { break;// 任务被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"CH3状态机更新错误: {ex.Message} ,行号{ex.StackTrace}"); // 记录错误但继续运行 mxlLog.Instance.Error($"CH3状态机更新错误 ,行号{ex.StackTrace} ", ex); } } } private void RunMachine4(CancellationToken token) { ch4workstation = (int)yiqi.standby; while (!token.IsCancellationRequested) { try { Thread.Sleep(500); // 使用Thread.Sleep而不是Task.Delay,因为这是后台线程 if (!token.IsCancellationRequested) { CH4machine(); } } catch (OperationCanceledException) { break;// 任务被取消,正常退出 } catch (Exception ex) { Console.WriteLine($"CH4状态机更新错误: {ex.Message} ,行号{ex.StackTrace}"); // 记录错误但继续运行 mxlLog.Instance.Error($"CH4状态机更新错误 ,行号{ex.StackTrace} ", ex); } } } // 仪器参数初始化 private void yiqiParamInit() { var jsconfig = new JsonConfig("config.json"); int j = 1; for (int i=1; i<=4; i++) { // P 正压 GetYiqiParam(i, "P").fulltime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "fulltime" + j, "0")); GetYiqiParam(i, "P").balantime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "balantime" + j, "0")); GetYiqiParam(i, "P").testtime1 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "testtime1" + j, "0")); GetYiqiParam(i, "P").exhausttime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "exhausttime" + j, "0")); GetYiqiParam(i, "P").delaytime1 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "delaytime1" + j, "0")); GetYiqiParam(i, "P").delaytime2 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "delaytime2" + j, "0")); GetYiqiParam(i, "P").relievedelay = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "relievedelay" + j, "0")); GetYiqiParam(i, "P").evolume = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "evolume" + j, "0")); GetYiqiParam(i, "P").fptoplimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "fptoplimit" + j, "0")); GetYiqiParam(i, "P").fplowlimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "fplowlimit" + j, "0")); GetYiqiParam(i, "P").balanpremax = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "balanpremax" + j, "0")); GetYiqiParam(i, "P").balanpremin = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "balanpremin" + j, "0")); GetYiqiParam(i, "P").leaktoplimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "leaktoplimit" + j, "0")); GetYiqiParam(i, "P").leaklowlimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "P" + "leaklowlimit" + j, "0")); GetYiqiParam(i, "P").punit = jsconfig.GetValue($"{i}" + "P" + "punit" + j, 0); GetYiqiParam(i, "P").lunit = jsconfig.GetValue($"{i}" + "P" + "lunit" + j, 0); GetYiqiParam(i, "P").opmode = jsconfig.GetValue($"{i}" + "P" + "opmode" + j, false); // N 负压 GetYiqiParam(i, "N").fulltime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "fulltime" + j, "0")); GetYiqiParam(i, "N").balantime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "balantime" + j, "0")); GetYiqiParam(i, "N").testtime1 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "testtime1" + j, "0")); GetYiqiParam(i, "N").exhausttime = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "exhausttime" + j, "0")); GetYiqiParam(i, "N").delaytime1 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "delaytime1" + j, "0")); GetYiqiParam(i, "N").delaytime2 = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "delaytime2" + j, "0")); GetYiqiParam(i, "N").relievedelay = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "relievedelay" + j, "0")); GetYiqiParam(i, "N").evolume = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "evolume" + j, "0")); GetYiqiParam(i, "N").fptoplimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "fptoplimit" + j, "0")); GetYiqiParam(i, "N").fplowlimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "fplowlimit" + j, "0")); GetYiqiParam(i, "N").balanpremax = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "balanpremax" + j, "0")); GetYiqiParam(i, "N").balanpremin = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "balanpremin" + j, "0")); GetYiqiParam(i, "N").leaktoplimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "leaktoplimit" + j, "0")); GetYiqiParam(i, "N").leaklowlimit = Convert.ToInt32(jsconfig.GetValue($"{i}" + "N" + "leaklowlimit" + j, "0")); GetYiqiParam(i, "N").punit = jsconfig.GetValue($"{i}" + "N" + "punit" + j, 0); GetYiqiParam(i, "N").lunit = jsconfig.GetValue($"{i}" + "N" + "lunit" + j, 0); GetYiqiParam(i, "N").opmode = jsconfig.GetValue($"{i}" + "N" + "opmode" + j, false); } // 重置测试记录 CH1TestRecord.Reset(); CH2TestRecord.Reset(); CH3TestRecord.Reset(); CH4TestRecord.Reset(); } int ch1workstation; // 状态 public enum yiqi { start, //启动 rst, //复位 prepare,//准备 test, //测试 finish, //完成(导出数据) writedate,//写入数据 standby,//待机 }; // 记录测试启停时间 TestTime CH1TestTime = new TestTime(); TestTime CH2TestTime = new TestTime(); TestTime CH3TestTime = new TestTime(); TestTime CH4TestTime = new TestTime(); // 测试次数 private int CH1testCount = 0; private int CH2testCount = 0; private int CH3testCount = 0; private int CH4testCount = 0; // 记录正压 private string CH1NowMode = "正压"; private string CH2NowMode = "正压"; private string CH3NowMode = "正压"; private string CH4NowMode = "正压"; // 记录各个通道的正负压参数 public yiqiParam CH1yiqiParam_P = new yiqiParam(); public yiqiParam CH1yiqiParam_N = new yiqiParam(); public yiqiParam CH2yiqiParam_P = new yiqiParam(); public yiqiParam CH2yiqiParam_N = new yiqiParam(); public yiqiParam CH3yiqiParam_P = new yiqiParam(); public yiqiParam CH3yiqiParam_N = new yiqiParam(); public yiqiParam CH4yiqiParam_P = new yiqiParam(); public yiqiParam CH4yiqiParam_N = new yiqiParam(); // 测试记录 private TestRecord CH1TestRecord = new TestRecord(1); private TestRecord CH2TestRecord = new TestRecord(2); private TestRecord CH3TestRecord = new TestRecord(3); private TestRecord CH4TestRecord = new TestRecord(4); private Dictionary prepareOutTime_Dictionary = new Dictionary(); public yiqiParam GetYiqiParam(int ch, string PorN = "P") { switch (ch) { case 1: return PorN == "P" ? CH1yiqiParam_P : CH1yiqiParam_N; case 2: return PorN == "P" ? CH2yiqiParam_P : CH2yiqiParam_N; case 3: return PorN == "P" ? CH3yiqiParam_P : CH3yiqiParam_N; case 4: return PorN == "P" ? CH4yiqiParam_P : CH4yiqiParam_N; } return CH1yiqiParam_P; } // 通道1状态机 public void CH1machine() { switch (ch1workstation) { case (int)yiqi.start: { SetLabelText(lb_CH1_Status, "启动"); LL28CH1client.writeCoil("0", true); ch1workstation = (int)yiqi.prepare; } break; case (int)yiqi.rst: { LL28CH1client.writeCoil("1", true); SetProgressBar(pb_CH1progressBar, 0); // 复位进度条置为0 SetLabelText(lb_CH1_Status, "复位"); CH1testCount = 0; // 重置测试次数 CH1TestRecord.Reset(); // 模式切回正压 //CH1NowMode = "正压"; //LL28CH1client.writeRegisters(1006, GetYiqiParam(1, "P").GetArray()); // 记得给PLC也写入正负压信号 //Slot_PLC_WriteCoil(1008, false); //Slot_PLC_WriteCoil(1000, GetYiqiParam(1, "P").opmode); //Console.WriteLine("@@@@:" + GetYiqiParam(1, "P").opmode); Thread.Sleep(200); ch1workstation = (int)yiqi.standby; } break; case (int)yiqi.prepare: { // 准备超时处理 if (!prepareOutTime_Dictionary.ContainsKey(1)) { prepareOutTime_Dictionary[1] = DateTime.Now.AddSeconds(5); // 5s后还在准备就去启动 } else if (DateTime.Now > prepareOutTime_Dictionary[1]) { prepareOutTime_Dictionary.Remove(1); // 清除超时记录 ch1workstation = (int)yiqi.start; break; } CH1TestTime.startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); SetLabelText(lb_CH1_Result, ""); SetLabelText(lb_CH1_Status, "准备"); int CH1progressbar = Convert.ToInt32(LL28CH1client.ArrRegister[6] / 10.0) // 充气时间 + Convert.ToInt32(LL28CH1client.ArrRegister[7] / 10.0) // 平衡时间 + Convert.ToInt32(LL28CH1client.ArrRegister[8] / 10.0) // 检测时间 + Convert.ToInt32(LL28CH1client.ArrRegister[9] / 10.0); // 排气时间 // 配置进度条 SetProgressBar(pb_CH1progressBar, 0); SetProgressBarMax(pb_CH1progressBar, (CH1progressbar + 1) * 10); // 设备运行状态 if (LL28CH1client.ArrCoil[2]) { prepareOutTime_Dictionary.Remove(1); ch1workstation = (int)yiqi.test; } } break; case (int)yiqi.standby: { SetLabelText(lb_CH1_Status, "待机"); // 设备运行状态 if (LL28CH1client.ArrCoil[2]) { ch1workstation = (int)yiqi.prepare; } } break; case (int)yiqi.test: { int yiqirunning = Convert.ToInt32(LL28CH1client.ArrRegister[34]); switch(yiqirunning) { case 1: SetLabelText(lb_CH1_Status, "准备"); break; case 2: SetLabelText(lb_CH1_Status, "充气"); break; case 3: SetLabelText(lb_CH1_Status, "平衡"); break; case 4: SetLabelText(lb_CH1_Status, "检测"); break; case 5: SetLabelText(lb_CH1_Status, "排气"); break; } // 压力单位 int punit = Convert.ToInt32(LL28CH1client.ArrRegister[27]); SetPUnit(1, punit); // 泄漏量单位 int lunit = Convert.ToInt32(LL28CH1client.ArrRegister[28]); SetLUnit(1, lunit); // 当前压力 string fNowpressure = LL28CH1client.readFloatF2(48); SetLabelText(lb_CH1nowPressure, fNowpressure); // 充气压力(测试压力) string fTestpressure = LL28CH1client.readFloatF2(57); SetLabelText(lb_CH1_TestPressure, fTestpressure); // 大漏(平衡压差) string fBigLeak = LL28CH1client.readFloatF2(35); SetLabelText(lb_CH1BigLeak, fBigLeak); // 微漏(泄漏量) string fSmallLeak = LL28CH1client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH1_SmallLeak, fSmallLeak); // 进度条 int pb_value = pb_CH1progressBar.Value + 5; SetProgressBar(pb_CH1progressBar, pb_value); if (pb_value >= pb_CH1progressBar.Maximum) { pb_value = pb_CH1progressBar.Maximum; SetProgressBar(pb_CH1progressBar, pb_value); } // 设备运行状态 if (!LL28CH1client.ArrCoil[2]) { int testresult = Convert.ToInt32(LL28CH1client.ArrRegister[41]); string Overresult = ""; if (testresult == 1) { Overresult = "OK"; SetLabelText(lb_CH1_Result, "OK", Color.Green); } else if (testresult == 2) { Overresult = "NG"; SetLabelText(lb_CH1_Result, "NG", Color.Red); } else { Overresult = ""; SetLabelText(lb_CH1_Result, ""); } if (Overresult != "") // 有ok/ng结果 { ch1workstation = (int)yiqi.finish; } else { SetProgressBar(pb_CH1progressBar, 0); ch1workstation = (int)yiqi.standby; } } } break; case (int)yiqi.finish: { SetLabelText(lb_CH1_Status, "完成"); CH1TestTime.stopTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 当前压力 string fNowpressure = LL28CH1client.readFloatF2(48); SetLabelText(lb_CH1nowPressure, fNowpressure); // 充气压力 string fTestpressure = LL28CH1client.readFloatF2(57); SetLabelText(lb_CH1_TestPressure, fTestpressure); //大漏 string fBigLeak = LL28CH1client.readFloatF2(35); SetLabelText(lb_CH1BigLeak, fBigLeak); //微漏 string fSmallLeak = LL28CH1client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH1_SmallLeak, fSmallLeak); // 结果 int Coil41result = Convert.ToInt32(LL28CH1client.ArrRegister[41]); bool result = false; if (Coil41result == 1) { SetLabelText(lb_CH1_Result, "OK", Color.Green); result = true; } else if (Coil41result == 2) { SetLabelText(lb_CH1_Result, "NG", Color.Red); result = false; } else { SetLabelText(lb_CH1_Result, ""); } // 设备运行状态-停止 if (LL28CH1client.ArrCoil[2] == false) { // 进度条拉满 SetProgressBar(pb_CH1progressBar, pb_CH1progressBar.Maximum); CH1TestRecord.Code = tb_CH1Code.Text; bool PorNfinish = true; // 正负压完成标志位 bool testfinish = false; // 测试结束标志位 //string nowmode = CH1NowMode; //if (CH1NowMode == "正压" && result) // 如果当前是正压并且测试OK //{ // // 这里要切换负压、写入负压参数、PLC信号、开口/容积 // CH1NowMode = "负压"; // Slot_PLC_WriteCoil(1008, true); // Slot_PLC_WriteCoil(1000, GetYiqiParam(1, "N").opmode); // // 先更新参数 // LL28CH1client.writeRegisters(1006, GetYiqiParam(1, "N").GetArray()); // Thread.Sleep(300); // // 保存正压测试记录 // CH1TestRecord.IsPTested = true; // CH1TestRecord.yiqiP_Param = GetYiqiParam(1, "P").Copy(); // CH1TestRecord.Result = result; // CH1TestRecord.PTestPressure = fTestpressure; // CH1TestRecord.PLeak = fSmallLeak; //} //else if(result == false) // 测试NG //{ // PorNfinish = true; // 正负压都测试了 //} //else if (CH1NowMode == "负压") //{ // // 这里要切换正压、写入正压参数、PLC信号、开口/容积 // CH1NowMode = "正压"; // Slot_PLC_WriteCoil(1008, false); // Slot_PLC_WriteCoil(1000, GetYiqiParam(1, "P").opmode); // // 先更新参数 // LL28CH1client.writeRegisters(1006, GetYiqiParam(1, "P").GetArray()); // Thread.Sleep(300); // PorNfinish = true; // 正负压都测试了 // // 保存负压测试记录 // CH1TestRecord.IsNTested = true; // CH1TestRecord.yiqiN_Param = GetYiqiParam(1, "N").Copy(); // CH1TestRecord.Result = result; // CH1TestRecord.NTestPressure = fTestpressure; // CH1TestRecord.NLeak = fSmallLeak; //} // 连续测试 if (result == false) // NG直接视为本次测试结束 { testfinish = true; } else if(m_ContinueTest && PorNfinish) // 开了连续 { CH1testCount++; CH1TestRecord.AddRecord(); // 添加本次记录 if (CH1testCount >= m_ContinueTestCount) // 测试次数满足 { testfinish = true; } else { SetLabelText(lb_CH1_Status, "加气"); Thread.Sleep(5000); // 等5s ch1workstation = (int)yiqi.start; } } else if (m_ContinueTest == false) // 没开连续测试直接视为本次测试结束 { testfinish = true; } // 表格 DataGridView1.Invoke(new System.Action(Display), 1, result, tb_CH1Code.Text, ""); // 测试完成并且正负压都完成则视为结束 if (testfinish && PorNfinish) { if(result) { m_production.AddOK(); } else { m_production.AddNG(); } // 更新产能 UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 文件 CreateFile(1, result, tb_CH1Code.Text, CH1TestRecord.GetRecordList()); // MES if (m_MESswitch) { var rdata = chuzhan(1, tb_CH1Code.Text, m_ActionName, m_Tools, G_CHECKFLOWID, result); if (rdata.result) { SetLabelText(lb_CH1MES_OUTstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH1MES_OUTstatus, "NG", Color.Red); SetUITextBox(tb_CH1MainMessage, $"CH1 出站NG:{rdata.msg}"); } } if (HCPLC_client.Connected) { Slot_PLC_WriteCoil(1004, true); mxlLog.Instance.Info($"CH1 1004信号"); } CH1testCount = 0; // 重置测试次数 CH1TestRecord.Reset(); // 重置测试记录 SetUITextBox(tb_CH1Code, ""); ch1workstation = (int)yiqi.standby; } if(PorNfinish == false) // 正负压有个没测 { ch1workstation = (int)yiqi.start; } } } break; default: break; } } // ----------- 通道2 int ch2workstation; // 状态 // 通道2状态机 public void CH2machine() { switch (ch2workstation) { case (int)yiqi.start: { SetLabelText(lb_CH2_Status, "启动"); LL28CH2client.writeCoil("0", true); ch2workstation = (int)yiqi.prepare; } break; case (int)yiqi.rst: { LL28CH2client.writeCoil("1", true); SetProgressBar(pb_CH2progressBar, 0); // 复位进度条置为0 SetLabelText(lb_CH2_Status, "复位"); CH2testCount = 0; // 重置测试次数 CH2TestRecord.Reset(); // 模式切回正压 //CH2NowMode = "正压"; //LL28CH2client.writeRegisters(1006, GetYiqiParam(2, "P").GetArray()); //// 记得给PLC也写入正负压信号 //Slot_PLC_WriteCoil(1009, false); //Slot_PLC_WriteCoil(1001, GetYiqiParam(2, "P").opmode); Thread.Sleep(200); ch2workstation = (int)yiqi.standby; } break; case (int)yiqi.prepare: { // 准备超时处理 if (!prepareOutTime_Dictionary.ContainsKey(2)) { prepareOutTime_Dictionary[2] = DateTime.Now.AddSeconds(5); // 5s后还在准备就去启动 } else if (DateTime.Now > prepareOutTime_Dictionary[2]) { prepareOutTime_Dictionary.Remove(2); // 清除超时记录 ch2workstation = (int)yiqi.start; break; } CH2TestTime.startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); SetLabelText(lb_CH2_Result, ""); SetLabelText(lb_CH2_Status, "准备"); int CH2progressbar = Convert.ToInt32(LL28CH2client.ArrRegister[6] / 10.0) // 充气时间 + Convert.ToInt32(LL28CH2client.ArrRegister[7] / 10.0) // 平衡时间 + Convert.ToInt32(LL28CH2client.ArrRegister[8] / 10.0) // 检测时间 + Convert.ToInt32(LL28CH2client.ArrRegister[9] / 10.0); // 排气时间 // 配置进度条 SetProgressBar(pb_CH2progressBar, 0); SetProgressBarMax(pb_CH2progressBar, (CH2progressbar + 1) * 10); // 补偿1秒 // 设备运行状态 if (LL28CH2client.ArrCoil[2]) { prepareOutTime_Dictionary.Remove(2); ch2workstation = (int)yiqi.test; } } break; case (int)yiqi.standby: { SetLabelText(lb_CH2_Status, "待机"); // 设备运行状态 if (LL28CH2client.ArrCoil[2]) { ch2workstation = (int)yiqi.prepare; } } break; case (int)yiqi.test: { int yiqirunning = Convert.ToInt32(LL28CH2client.ArrRegister[34]); switch (yiqirunning) { case 1: SetLabelText(lb_CH2_Status, "准备"); break; case 2: SetLabelText(lb_CH2_Status, "充气"); break; case 3: SetLabelText(lb_CH2_Status, "平衡"); break; case 4: SetLabelText(lb_CH2_Status, "检测"); break; case 5: SetLabelText(lb_CH2_Status, "排气"); break; } // 压力单位 int punit = Convert.ToInt32(LL28CH2client.ArrRegister[27]); SetPUnit(2, punit); // 泄漏量单位 int lunit = Convert.ToInt32(LL28CH2client.ArrRegister[28]); SetLUnit(2, lunit); // 当前压力 string fNowpressure = LL28CH2client.readFloatF2(48); SetLabelText(lb_CH2nowPressure, fNowpressure); // 充气压力(测试压力) string fTestpressure = LL28CH2client.readFloatF2(57); SetLabelText(lb_CH2_TestPressure, fTestpressure); // 大漏(平衡压差) string fBigLeak = LL28CH2client.readFloatF2(35); SetLabelText(lb_CH2BigLeak, fBigLeak); // 微漏(泄漏量) string fSmallLeak = LL28CH2client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH2_SmallLeak, fSmallLeak); // 进度条 int pb_value = pb_CH2progressBar.Value + 5; SetProgressBar(pb_CH2progressBar, pb_value); if (pb_value >= pb_CH2progressBar.Maximum) { pb_value = pb_CH2progressBar.Maximum; SetProgressBar(pb_CH2progressBar, pb_value); } // 设备运行状态 if (!LL28CH2client.ArrCoil[2]) { int testresult = Convert.ToInt32(LL28CH2client.ArrRegister[41]); string Overresult = ""; if (testresult == 1) { Overresult = "OK"; SetLabelText(lb_CH2_Result, "OK", Color.Green); } else if (testresult == 2) { Overresult = "NG"; SetLabelText(lb_CH2_Result, "NG", Color.Red); } else { Overresult = ""; SetLabelText(lb_CH2_Result, ""); } if (Overresult != "") // 有ok/ng结果 { ch2workstation = (int)yiqi.finish; } else { SetProgressBar(pb_CH2progressBar, 0); ch2workstation = (int)yiqi.standby; } } } break; case (int)yiqi.finish: { SetLabelText(lb_CH2_Status, "完成"); CH2TestTime.stopTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 当前压力 string fNowpressure = LL28CH2client.readFloatF2(48); SetLabelText(lb_CH2nowPressure, fNowpressure); // 充气压力 string fTestpressure = LL28CH2client.readFloatF2(57); SetLabelText(lb_CH2_TestPressure, fTestpressure); //大漏 string fBigLeak = LL28CH2client.readFloatF2(35); SetLabelText(lb_CH2BigLeak, fBigLeak); //微漏 string fSmallLeak = LL28CH2client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH2_SmallLeak, fSmallLeak); // 结果 int Coil41result = Convert.ToInt32(LL28CH2client.ArrRegister[41]); bool result = false; if (Coil41result == 1) { SetLabelText(lb_CH2_Result, "OK", Color.Green); result = true; } else if (Coil41result == 2) { SetLabelText(lb_CH2_Result, "NG", Color.Red); result = false; } else { SetLabelText(lb_CH2_Result, ""); } // 设备运行状态-停止 if (LL28CH2client.ArrCoil[2] == false) { // 进度条拉满 SetProgressBar(pb_CH2progressBar, pb_CH2progressBar.Maximum); CH2TestRecord.Code = tb_CH2Code.Text; bool PorNfinish = true; // 正负压完成标志位 bool testfinish = false; // 测试结束标志位 //string nowmode = CH2NowMode; //if (CH2NowMode == "正压" && result) // 如果当前是正压并且测试OK //{ // // 这里要切换负压、写入负压参数、PLC信号 // CH2NowMode = "负压"; // Slot_PLC_WriteCoil(1009, true); // Slot_PLC_WriteCoil(1001, GetYiqiParam(2, "N").opmode); // // 先更新参数 // LL28CH2client.writeRegisters(1006, GetYiqiParam(2, "N").GetArray()); // Thread.Sleep(300); // // 保存正压测试记录 // CH2TestRecord.IsPTested = true; // CH2TestRecord.yiqiP_Param = GetYiqiParam(2, "P").Copy(); // CH2TestRecord.Result = result; // CH2TestRecord.PTestPressure = fTestpressure; // CH2TestRecord.PLeak = fSmallLeak; //} //else if (result == false) // 测试NG //{ // PorNfinish = true; // 正负压都测试了 //} //else if (CH2NowMode == "负压") //{ // // 这里要切换正压、写入正压参数、PLC信号 // CH2NowMode = "正压"; // Slot_PLC_WriteCoil(1009, false); // Slot_PLC_WriteCoil(1001, GetYiqiParam(2, "P").opmode); // // 先更新参数 // LL28CH2client.writeRegisters(1006, GetYiqiParam(2, "P").GetArray()); // Thread.Sleep(300); // PorNfinish = true; // 正负压都测试了 // // 保存负压测试记录 // CH2TestRecord.IsNTested = true; // CH2TestRecord.yiqiN_Param = GetYiqiParam(2, "N").Copy(); // CH2TestRecord.Result = result; // CH2TestRecord.NTestPressure = fTestpressure; // CH2TestRecord.NLeak = fSmallLeak; //} // 连续测试 if (result == false) // NG直接视为结束 { testfinish = true; } else if (m_ContinueTest && PorNfinish) // 开了连续并且正负压都测了 { CH2testCount++; CH2TestRecord.AddRecord(); if (CH2testCount >= m_ContinueTestCount) // 测试次数满足 { testfinish = true; } else { SetLabelText(lb_CH2_Status, "加气"); Thread.Sleep(5000); ch2workstation = (int)yiqi.start; } } else if (m_ContinueTest == false) // 没开连续测试直接视为本次测试结束 { testfinish = true; // 没开连续测试直接视为本次测试结束 } // 表格 DataGridView2.Invoke(new System.Action(Display), 2, result, tb_CH2Code.Text, ""); // 测试完成并且正负压都完成则视为结束 if (testfinish && PorNfinish) { if (result) { m_production.AddOK(); } else { m_production.AddNG(); } // 更新产能 UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 文件 CreateFile(2, result, tb_CH2Code.Text, CH2TestRecord.GetRecordList()); // MES if (m_MESswitch) { var rdata = chuzhan(2, tb_CH2Code.Text, m_ActionName, m_Tools, G_CHECKFLOWID, result); if (rdata.result) { SetLabelText(lb_CH2MES_OUTstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH2MES_OUTstatus, "NG", Color.Red); SetUITextBox(tb_CH2MainMessage, $"CH2 出站NG:{rdata.msg}"); } } if (HCPLC_client.Connected) { Slot_PLC_WriteCoil(1005, true); mxlLog.Instance.Info($"CH2 1005信号"); } CH2testCount = 0; // 重置测试次数 CH2TestRecord.Reset(); // 重置测试记录 SetUITextBox(tb_CH2Code, ""); ch2workstation = (int)yiqi.standby; } if (PorNfinish == false) // 正负压有个没测 { ch2workstation = (int)yiqi.start; } } } break; default: break; } } // ----------- 通道3 int ch3workstation; // 状态 // 通道3状态机 public void CH3machine() { switch (ch3workstation) { case (int)yiqi.start: { SetLabelText(lb_CH3_Status, "启动"); LL28CH3client.writeCoil("0", true); ch3workstation = (int)yiqi.prepare; } break; case (int)yiqi.rst: { LL28CH3client.writeCoil("1", true); SetProgressBar(pb_CH3progressBar, 0); // 复位进度条置为0 SetLabelText(lb_CH3_Status, "复位"); CH3testCount = 0; // 重置测试次数 CH2TestRecord.Reset(); // 模式切回正压 //CH3NowMode = "正压"; //LL28CH3client.writeRegisters(1006, GetYiqiParam(3, "P").GetArray()); //// 记得给PLC也写入正负压信号 //Slot_PLC_WriteCoil(1010, false); //Slot_PLC_WriteCoil(1002, GetYiqiParam(3, "P").opmode); Thread.Sleep(200); ch3workstation = (int)yiqi.standby; } break; case (int)yiqi.prepare: { // 准备超时处理 if (!prepareOutTime_Dictionary.ContainsKey(3)) { prepareOutTime_Dictionary[3] = DateTime.Now.AddSeconds(5); // 5s后还在准备就去启动 } else if (DateTime.Now > prepareOutTime_Dictionary[3]) { prepareOutTime_Dictionary.Remove(3); // 清除超时记录 ch3workstation = (int)yiqi.start; break; } CH3TestTime.startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); SetLabelText(lb_CH3_Result, ""); SetLabelText(lb_CH3_Status, "准备"); int CH3progressbar = Convert.ToInt32(LL28CH3client.ArrRegister[6] / 10.0) // 充气时间 + Convert.ToInt32(LL28CH3client.ArrRegister[7] / 10.0) // 平衡时间 + Convert.ToInt32(LL28CH3client.ArrRegister[8] / 10.0) // 检测时间 + Convert.ToInt32(LL28CH3client.ArrRegister[9] / 10.0); // 排气时间 // 配置进度条 SetProgressBar(pb_CH3progressBar, 0); SetProgressBarMax(pb_CH3progressBar, (CH3progressbar + 1) * 10); // 补偿1秒 // 设备运行状态 if (LL28CH3client.ArrCoil[2]) { prepareOutTime_Dictionary.Remove(3); ch3workstation = (int)yiqi.test; } } break; case (int)yiqi.standby: { SetLabelText(lb_CH3_Status, "待机"); // 设备运行状态 if (LL28CH3client.ArrCoil[2]) { ch3workstation = (int)yiqi.prepare; } } break; case (int)yiqi.test: { int yiqirunning = Convert.ToInt32(LL28CH3client.ArrRegister[34]); switch (yiqirunning) { case 1: SetLabelText(lb_CH3_Status, "准备"); break; case 2: SetLabelText(lb_CH3_Status, "充气"); break; case 3: SetLabelText(lb_CH3_Status, "平衡"); break; case 4: SetLabelText(lb_CH3_Status, "检测"); break; case 5: SetLabelText(lb_CH3_Status, "排气"); break; } // 压力单位 int punit = Convert.ToInt32(LL28CH3client.ArrRegister[27]); SetPUnit(3,punit); // 泄漏量单位 int lunit = Convert.ToInt32(LL28CH3client.ArrRegister[28]); SetLUnit(3, lunit); // 当前压力 string fNowpressure = LL28CH3client.readFloatF2(48); SetLabelText(lb_CH3nowPressure, fNowpressure); // 充气压力(测试压力) string fTestpressure = LL28CH3client.readFloatF2(57); SetLabelText(lb_CH3_TestPressure, fTestpressure); // 大漏(平衡压差) string fBigLeak = LL28CH3client.readFloatF2(35); SetLabelText(lb_CH3BigLeak, fBigLeak); // 微漏(泄漏量) string fSmallLeak = LL28CH3client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH3_SmallLeak, fSmallLeak); // 进度条 int pb_value = pb_CH3progressBar.Value + 5; SetProgressBar(pb_CH3progressBar, pb_value); if (pb_value >= pb_CH3progressBar.Maximum) { pb_value = pb_CH3progressBar.Maximum; SetProgressBar(pb_CH3progressBar, pb_value); } // 设备运行状态 if (!LL28CH3client.ArrCoil[2]) { int testresult = Convert.ToInt32(LL28CH3client.ArrRegister[41]); string Overresult = ""; if (testresult == 1) { Overresult = "OK"; SetLabelText(lb_CH3_Result, "OK", Color.Green); } else if (testresult == 2) { Overresult = "NG"; SetLabelText(lb_CH3_Result, "NG", Color.Red); } else { Overresult = ""; SetLabelText(lb_CH3_Result, ""); } if (Overresult != "") // 有ok/ng结果 { ch3workstation = (int)yiqi.finish; } else { SetProgressBar(pb_CH3progressBar, 0); ch3workstation = (int)yiqi.standby; } } } break; case (int)yiqi.finish: { SetLabelText(lb_CH3_Status, "完成"); CH3TestTime.stopTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 当前压力 string fNowpressure = LL28CH3client.readFloatF2(48); SetLabelText(lb_CH3nowPressure, fNowpressure); // 充气压力 string fTestpressure = LL28CH3client.readFloatF2(57); SetLabelText(lb_CH3_TestPressure, fTestpressure); //大漏 string fBigLeak = LL28CH3client.readFloatF2(35); SetLabelText(lb_CH3BigLeak, fBigLeak); //微漏 string fSmallLeak = LL28CH3client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH3_SmallLeak, fSmallLeak); // 结果 int Coil41result = Convert.ToInt32(LL28CH3client.ArrRegister[41]); bool result = false; if (Coil41result == 1) { SetLabelText(lb_CH3_Result, "OK", Color.Green); result = true; } else if (Coil41result == 2) { SetLabelText(lb_CH3_Result, "NG", Color.Red); result = false; } else { SetLabelText(lb_CH3_Result, ""); } //Console.WriteLine($"finish-结果: {testresult}"); // 设备运行状态-停止 if (LL28CH3client.ArrCoil[2] == false) { SetProgressBar(pb_CH3progressBar, pb_CH3progressBar.Maximum); CH3TestRecord.Code = tb_CH3Code.Text; bool PorNfinish = true; // 正负压完成标志位 bool testfinish = false; // 测试结束标志位 //string nowmode = CH3NowMode; //if (CH3NowMode == "正压" && result) // 如果当前是正压并且测试OK //{ // // 这里要切换负压、写入负压参数、PLC信号 // CH3NowMode = "负压"; // Slot_PLC_WriteCoil(1010, true); // Slot_PLC_WriteCoil(1002, GetYiqiParam(3, "N").opmode); // // 先更新参数 // LL28CH3client.writeRegisters(1006, GetYiqiParam(3, "N").GetArray()); // Thread.Sleep(300); // // 保存正压测试记录 // CH3TestRecord.IsPTested = true; // CH3TestRecord.yiqiP_Param = GetYiqiParam(3, "P").Copy(); // CH3TestRecord.Result = result; // CH3TestRecord.PTestPressure = fTestpressure; // CH3TestRecord.PLeak = fSmallLeak; //} //else if (result == false) // 测试NG //{ // PorNfinish = true; // 正负压都测试了 //} //else if (CH3NowMode == "负压") //{ // // 这里要切换正压、写入正压参数、PLC信号 // CH3NowMode = "正压"; // Slot_PLC_WriteCoil(1010, false); // Slot_PLC_WriteCoil(1002, GetYiqiParam(3, "P").opmode); // // 先更新参数 // LL28CH3client.writeRegisters(1006, GetYiqiParam(3, "P").GetArray()); // Thread.Sleep(300); // PorNfinish = true; // 正负压都测试了 // // 保存负压测试记录 // CH3TestRecord.IsNTested = true; // CH3TestRecord.yiqiN_Param = GetYiqiParam(3, "N").Copy(); // CH3TestRecord.Result = result; // CH3TestRecord.NTestPressure = fTestpressure; // CH3TestRecord.NLeak = fSmallLeak; //} // 连续测试 if (result == false) // NG直接视为结束 { testfinish = true; } else if (m_ContinueTest && PorNfinish) // 开了连续并且正负压都测了 { CH3testCount++; CH3TestRecord.AddRecord(); if (CH3testCount >= m_ContinueTestCount) // 测试次数满足 { testfinish = true; } else // 进入下一次测试 { SetLabelText(lb_CH3_Status, "加气"); Thread.Sleep(5000); ch3workstation = (int)yiqi.start; } } else if (m_ContinueTest == false) // 没开连续测试直接视为本次测试结束 { testfinish = true; } // 表格 DataGridView1.Invoke(new System.Action(Display), 3, result, tb_CH3Code.Text, ""); // 测试完成并且正负压都完成则视为结束 if (testfinish && PorNfinish) { if (result) { m_production.AddOK(); } else { m_production.AddNG(); } // 更新产能 UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 文件 CreateFile(3, result, tb_CH3Code.Text, CH3TestRecord.GetRecordList()); // MES if (m_MESswitch) { var rdata = chuzhan(3, tb_CH3Code.Text, m_ActionName, m_Tools, G_CHECKFLOWID, result); if (rdata.result) { SetLabelText(lb_CH3MES_OUTstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH3MES_OUTstatus, "NG", Color.Red); SetUITextBox(tb_CH1MainMessage, $"CH3 出站NG:{rdata.msg}"); } } if (HCPLC_client.Connected) { Slot_PLC_WriteCoil(1006, true); mxlLog.Instance.Info($"CH3 1006信号"); } CH3testCount = 0; // 重置测试次数 CH3TestRecord.Reset(); // 重置测试记录 SetUITextBox(tb_CH3Code, ""); ch3workstation = (int)yiqi.standby; } if (PorNfinish == false) // 正负压有个没测 { ch3workstation = (int)yiqi.start; } } } break; default: break; } } // ----------- 通道4 int ch4workstation; // 状态 // 通道4状态机 public void CH4machine() { switch (ch4workstation) { case (int)yiqi.start: { SetLabelText(lb_CH4_Status, "启动"); LL28CH4client.writeCoil("0", true); ch4workstation = (int)yiqi.prepare; } break; case (int)yiqi.rst: { LL28CH4client.writeCoil("1", true); SetProgressBar(pb_CH4progressBar, 0); // 复位进度条置为0 SetLabelText(lb_CH4_Status, "复位"); CH4testCount = 0; // 重置测试次数 CH4TestRecord.Reset(); // 模式切回正压 //CH4NowMode = "正压"; //LL28CH4client.writeRegisters(1006, GetYiqiParam(4, "P").GetArray()); //// 记得给PLC也写入正负压信号 //Slot_PLC_WriteCoil(1011, false); //Slot_PLC_WriteCoil(1003, GetYiqiParam(4, "P").opmode); Thread.Sleep(200); ch4workstation = (int)yiqi.standby; } break; case (int)yiqi.prepare: { // 准备超时处理 if (!prepareOutTime_Dictionary.ContainsKey(4)) { prepareOutTime_Dictionary[4] = DateTime.Now.AddSeconds(5); // 5s后还在准备就去启动 } else if (DateTime.Now > prepareOutTime_Dictionary[4]) { prepareOutTime_Dictionary.Remove(4); // 清除超时记录 ch4workstation = (int)yiqi.start; break; } CH4TestTime.startTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); SetLabelText(lb_CH4_Result, ""); SetLabelText(lb_CH4_Status, "准备"); int CH4progressbar = Convert.ToInt32(LL28CH4client.ArrRegister[6] / 10.0) // 充气时间 + Convert.ToInt32(LL28CH4client.ArrRegister[7] / 10.0) // 平衡时间 + Convert.ToInt32(LL28CH4client.ArrRegister[8] / 10.0) // 检测时间 + Convert.ToInt32(LL28CH4client.ArrRegister[9] / 10.0); // 排气时间 // 配置进度条 SetProgressBar(pb_CH4progressBar, 0); SetProgressBarMax(pb_CH4progressBar, (CH4progressbar + 1) * 10); // 补偿1秒 // 设备运行状态 if (LL28CH4client.ArrCoil[2]) { prepareOutTime_Dictionary.Remove(4); ch4workstation = (int)yiqi.test; } } break; case (int)yiqi.standby: { SetLabelText(lb_CH4_Status, "待机"); // 设备运行状态 if (LL28CH4client.ArrCoil[2]) { ch4workstation = (int)yiqi.prepare; } } break; case (int)yiqi.test: { int yiqirunning = Convert.ToInt32(LL28CH4client.ArrRegister[34]); switch (yiqirunning) { case 1: SetLabelText(lb_CH4_Status, "准备"); break; case 2: SetLabelText(lb_CH4_Status, "充气"); break; case 3: SetLabelText(lb_CH4_Status, "平衡"); break; case 4: SetLabelText(lb_CH4_Status, "检测"); break; case 5: SetLabelText(lb_CH4_Status, "排气"); break; } // 压力单位 int punit = Convert.ToInt32(LL28CH4client.ArrRegister[27]); SetPUnit(4, punit); // 泄漏量单位 int lunit = Convert.ToInt32(LL28CH4client.ArrRegister[28]); SetLUnit(4, lunit); // 当前压力 string fNowpressure = LL28CH4client.readFloatF2(48); SetLabelText(lb_CH4nowPressure, fNowpressure); // 充气压力(测试压力) string fTestpressure = LL28CH4client.readFloatF2(57); SetLabelText(lb_CH4_TestPressure, fTestpressure); // 大漏(平衡压差) string fBigLeak = LL28CH4client.readFloatF2(35); SetLabelText(lb_CH4BigLeak, fBigLeak); // 微漏(泄漏量) string fSmallLeak = LL28CH4client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH4_SmallLeak, fSmallLeak); // 进度条 int pb_value = pb_CH4progressBar.Value + 5; SetProgressBar(pb_CH4progressBar, pb_value); if (pb_value >= pb_CH4progressBar.Maximum) { pb_value = pb_CH4progressBar.Maximum; SetProgressBar(pb_CH4progressBar, pb_value); } // 设备运行状态 if (!LL28CH4client.ArrCoil[2]) { int testresult = Convert.ToInt32(LL28CH4client.ArrRegister[41]); string Overresult = ""; if (testresult == 1) { Overresult = "OK"; SetLabelText(lb_CH4_Result, "OK", Color.Green); } else if (testresult == 2) { Overresult = "NG"; SetLabelText(lb_CH4_Result, "NG", Color.Red); } else { Overresult = ""; SetLabelText(lb_CH4_Result, ""); } if (Overresult != "") // 有ok/ng结果 { ch4workstation = (int)yiqi.finish; } else { SetProgressBar(pb_CH4progressBar, 0); ch4workstation = (int)yiqi.standby; } } } break; case (int)yiqi.finish: { SetLabelText(lb_CH4_Status, "完成"); CH4TestTime.stopTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 当前压力 string fNowpressure = LL28CH4client.readFloatF2(48); SetLabelText(lb_CH4nowPressure, fNowpressure); // 充气压力 string fTestpressure = LL28CH4client.readFloatF2(57); SetLabelText(lb_CH4_TestPressure, fTestpressure); //大漏 string fBigLeak = LL28CH4client.readFloatF2(35); SetLabelText(lb_CH4BigLeak, fBigLeak); //微漏 string fSmallLeak = LL28CH4client.readFloatF2(38); // 处理大于2000, 先显示2000,后续再处理 if (fSmallLeak.ToDouble() > 2000) { fSmallLeak = "2000"; } SetLabelText(lb_CH4_SmallLeak, fSmallLeak); // 结果 int Coil41result = Convert.ToInt32(LL28CH4client.ArrRegister[41]); bool result = false; if (Coil41result == 1) { SetLabelText(lb_CH4_Result, "OK", Color.Green); result = true; } else if (Coil41result == 2) { SetLabelText(lb_CH4_Result, "NG", Color.Red); result = false; } else { SetLabelText(lb_CH4_Result, ""); } // 设备运行状态-停止 if (!LL28CH4client.ArrCoil[2]) { SetProgressBar(pb_CH4progressBar, pb_CH4progressBar.Maximum); CH4TestRecord.Code = tb_CH4Code.Text; bool PorNfinish = true; // 正负压完成标志位 bool testfinish = false; // 测试结束标志位 //string nowmode = CH4NowMode; //if (CH4NowMode == "正压" && result) // 如果当前是正压并且测试OK //{ // // 这里要切换负压、写入负压参数、PLC信号 // CH4NowMode = "负压"; // Slot_PLC_WriteCoil(1011, true); // Slot_PLC_WriteCoil(1003, GetYiqiParam(4, "N").opmode); // // 先更新参数 // LL28CH4client.writeRegisters(1006, GetYiqiParam(4, "N").GetArray()); // Thread.Sleep(300); // // 保存正压测试记录 // CH4TestRecord.IsPTested = true; // CH4TestRecord.yiqiP_Param = GetYiqiParam(4, "P").Copy(); // CH4TestRecord.Result = result; // CH4TestRecord.PTestPressure = fTestpressure; // CH4TestRecord.PLeak = fSmallLeak; //} //else if (result == false) // 测试NG //{ // PorNfinish = true; // 正负压都测试了 //} //else if (CH4NowMode == "负压") //{ // // 这里要切换正压、写入正压参数、PLC信号 // CH4NowMode = "正压"; // Slot_PLC_WriteCoil(1011, false); // Slot_PLC_WriteCoil(1003, GetYiqiParam(4, "P").opmode); // // 先更新参数 // LL28CH4client.writeRegisters(1006, GetYiqiParam(4, "P").GetArray()); // Thread.Sleep(300); // PorNfinish = true; // 正负压都测试了 // // 保存负压测试记录 // CH4TestRecord.IsNTested = true; // CH4TestRecord.yiqiN_Param = GetYiqiParam(4, "N").Copy(); // CH4TestRecord.Result = result; // CH4TestRecord.NTestPressure = fTestpressure; // CH4TestRecord.NLeak = fSmallLeak; //} if(PorNfinish) { CH4TestRecord.AddRecord(); } // 连续测试 if (result == false) // NG直接视为结束 { testfinish = true; } else if (m_ContinueTest && PorNfinish) // 开了连续并且正负压都测了 { CH4testCount++; if (CH4testCount >= m_ContinueTestCount) // 测试次数满足 { testfinish = true; } else { SetLabelText(lb_CH4_Status, "加气"); Thread.Sleep(5000); ch4workstation = (int)yiqi.start; } } else { testfinish = true; // 没开连续测试直接视为本次测试结束 } // 表格 DataGridView2.Invoke(new System.Action(Display), 4, result, tb_CH4Code.Text, ""); // 测试完成并且正负压都完成则视为结束 if (testfinish && PorNfinish) { if (result) { m_production.AddOK(); } else { m_production.AddNG(); } // 更新产能 UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 文件 CreateFile(4, result, tb_CH4Code.Text, CH4TestRecord.GetRecordList()); // MES if (m_MESswitch) { var rdata = chuzhan(4, tb_CH4Code.Text, m_ActionName, m_Tools, G_CHECKFLOWID, result); if (rdata.result) { SetLabelText(lb_CH4MES_OUTstatus, "PASS", Color.Green); } else { SetLabelText(lb_CH4MES_OUTstatus, "NG", Color.Red); SetUITextBox(tb_CH2MainMessage, $"CH4 出站NG:{rdata.msg}"); } } if (HCPLC_client.Connected) { Slot_PLC_WriteCoil(1007, true); mxlLog.Instance.Info($"CH4 1007信号"); } CH4testCount = 0; // 重置测试次数 CH4TestRecord.Reset(); // 重置测试记录 SetUITextBox(tb_CH4Code, ""); ch4workstation = (int)yiqi.standby; } if (PorNfinish == false) // 正负压有个没测 { ch4workstation = (int)yiqi.start; } } } break; default: break; } } // 更新产能数据 void UploadProductionData(int total, int ok, int ng, double okRate) { SetLabelText(lb_Total, $"{total}"); SetLabelText(lb_OKnumber, $"{ok}"); SetLabelText(lb_NGnumber, $"{ng}"); SetLabelText(lb_OKRate, $"{okRate}%"); } //写入文件 private void CreateFile(int CH, bool result, string code, string data = null) { try { //Invoke((new System.Action(() => //Task.Run(() => //{ if (filesave.Excel) { Task.Run(() => // 这个会卡顿一下,放到线程 应该是使用和打开了Excel的app { AddExcel(CH, result, code); }); } if (filesave.TXT) { AddTxT(CH, data); } if (filesave.CSV) { AddCSV(CH, result); } //}); } catch (Exception ex) { MessageBox.Show("CreateFile:" + ex.Message); mxlLog.Instance.Error($"CreateFile写入错误 ,行号{ex.StackTrace} ", ex); //throw; } } // 设置压力单位 private void SetPUnit(int ch, int unit) { string PUnit = "Pa"; switch (unit) { case 0: PUnit = "Pa"; break; case 1: PUnit = "KPa"; break; case 2: PUnit = "MPa"; break; case 3: PUnit = "bar"; break; case 4: PUnit = "Psi"; break; case 5: PUnit = "kg/cm^2"; break; case 6: PUnit = "atm"; break; case 7: PUnit = "mmHg"; break; } switch (ch) { case 1: lb_CH1_PressureUnit.Invoke((MethodInvoker)delegate { lb_CH1BigLeakUnit.Text = PUnit; lb_CH1_nowPressureUnit.Text = PUnit; lb_CH1_PressureUnit.Text = PUnit; }); break; case 2: lb_CH2_PressureUnit.Invoke((MethodInvoker)delegate { lb_CH2BigLeakUnit.Text = PUnit; lb_CH2_nowPressureUnit.Text = PUnit; lb_CH2_PressureUnit.Text = PUnit; }); break; case 3: lb_CH3_PressureUnit.Invoke((MethodInvoker)delegate { lb_CH3BigLeakUnit.Text = PUnit; lb_CH3_nowPressureUnit.Text = PUnit; lb_CH3_PressureUnit.Text = PUnit; }); break; case 4: lb_CH4_PressureUnit.Invoke((MethodInvoker)delegate { lb_CH4BigLeakUnit.Text = PUnit; lb_CH4_nowPressureUnit.Text = PUnit; lb_CH4_PressureUnit.Text = PUnit; }); break; } } // 设置泄露量单位 private void SetLUnit(int ch, int unit) { string LUnit = "Pa"; switch (unit) { case 0: LUnit = "Pa"; break; case 1: LUnit = "KPa"; break; case 2: LUnit = "mbar"; break; case 3: LUnit = "atm"; break; case 4: LUnit = "sccm"; break; case 5: LUnit = "ccm3/s"; break; case 6: LUnit = "Pa/s"; break; } switch (ch) { case 1: lb_CH1_SmallLeakUnit.Invoke((MethodInvoker)delegate { //lb_CH1_BigLeakUnit.Text = LUnit; lb_CH1_SmallLeakUnit.Text = LUnit; }); break; case 2: lb_CH2_SmallLeakUnit.Invoke((MethodInvoker)delegate { //lb_CH2_BigLeakUnit.Text = LUnit; lb_CH2_SmallLeakUnit.Text = LUnit; }); break; case 3: lb_CH3_SmallLeakUnit.Invoke((MethodInvoker)delegate { //lb_CH3_BigLeakUnit.Text = LUnit; lb_CH3_SmallLeakUnit.Text = LUnit; }); break; case 4: lb_CH4_SmallLeakUnit.Invoke((MethodInvoker)delegate { //lb_CH4_BigLeakUnit.Text = LUnit; lb_CH4_SmallLeakUnit.Text = LUnit; }); break; } } //将数据写入Txt public void AddTxT(int CH, bool result, string code) { try { string datatime = DateTime.Now.ToString("yyyyMMdd"); if (String.IsNullOrEmpty(filesave.Path)) // 若路径处不输入则获取桌面路径 { filesave.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); filesave.Path = AppDomain.CurrentDomain.BaseDirectory + "Storage"; } string filepath = filesave.Path + "\\"; if (!Directory.Exists(filepath)) { Directory.CreateDirectory(filepath); } string updata = ""; if (CH == 1) { string ngret = ""; string fSmallLeak = LL28CH1client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH1_SmallLeak.Text + lb_CH1_SmallLeakUnit.Text; } updata = "CH1 " + "时间 " + DateTime.Now + " 条形码 " + code + " 结果" + (result ? "OK" : "NG") + " 充气时间" + (LL28CH1client.ArrRegister[6] / 10.0).ToString() + "s" + " 平衡时间" + (LL28CH1client.ArrRegister[7] / 10.0).ToString() + "s" + " 测试时间" + (LL28CH1client.ArrRegister[8] / 10.0).ToString() + "s" + " 排气时间" + (LL28CH1client.ArrRegister[9] / 10.0).ToString() + "s" + " 测试压力" + lb_CH1_TestPressure.Text + lb_CH1_PressureUnit.Text + " 泄漏量" + ngret + " \n"; } if (CH == 2) { string ngret = ""; string fSmallLeak = LL28CH2client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH2_SmallLeak.Text + lb_CH2_SmallLeakUnit.Text; } updata = "CH2 " + "时间 " + DateTime.Now + " 条形码 " + code + " 结果" + (result ? "OK" : "NG") + " 充气时间" + (LL28CH2client.ArrRegister[6] / 10.0).ToString() + "s" + " 平衡时间" + (LL28CH2client.ArrRegister[7] / 10.0).ToString() + "s" + " 测试时间" + (LL28CH2client.ArrRegister[8] / 10.0).ToString() + "s" + " 排气时间" + (LL28CH2client.ArrRegister[9] / 10.0).ToString() + "s" + " 测试压力" + lb_CH2_TestPressure.Text + lb_CH2_PressureUnit.Text + " 泄漏量" + ngret + " \n"; } if (CH == 3) { string ngret = ""; string fSmallLeak = LL28CH3client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH3_SmallLeak.Text + lb_CH3_SmallLeakUnit.Text; } updata = "CH3 " + "时间 " + DateTime.Now + " 条形码 " + code + " 结果" + (result ? "OK" : "NG") + " 充气时间" + (LL28CH3client.ArrRegister[6] / 10.0).ToString() + "s" + " 平衡时间" + (LL28CH3client.ArrRegister[7] / 10.0).ToString() + "s" + " 测试时间" + (LL28CH3client.ArrRegister[8] / 10.0).ToString() + "s" + " 排气时间" + (LL28CH3client.ArrRegister[9] / 10.0).ToString() + "s" + " 测试压力" + lb_CH3_TestPressure.Text + lb_CH3_PressureUnit.Text + " 泄漏量" + ngret + " \n"; } if (CH == 4) { string ngret = ""; string fSmallLeak = LL28CH4client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH4_SmallLeak.Text + lb_CH4_SmallLeakUnit.Text; } updata = "CH4 " + "时间 " + DateTime.Now + " 条形码 " + code + " 结果" + (result ? "OK" : "NG") + " 充气时间" + (LL28CH4client.ArrRegister[6] / 10.0).ToString() + "s" + " 平衡时间" + (LL28CH4client.ArrRegister[7] / 10.0).ToString() + "s" + " 测试时间" + (LL28CH4client.ArrRegister[8] / 10.0).ToString() + "s" + " 排气时间" + (LL28CH4client.ArrRegister[9] / 10.0).ToString() + "s" + " 测试压力" + lb_CH4_TestPressure.Text + lb_CH4_PressureUnit.Text + " 泄漏量" + ngret + " \n"; } // 文件不存在则创建 string strfile = filepath + DateTime.Today.ToString("yyyy-MM-dd") + "_" + CH + ".txt"; if (!System.IO.File.Exists(strfile)) { FileStream fs1 = new FileStream(strfile, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs1); sw.WriteLine(updata); //开始写入值 sw.Close(); fs1.Close(); } else { FileStream fs = new FileStream(strfile, FileMode.Append, FileAccess.Write); StreamWriter sr = new StreamWriter(fs); sr.WriteLine(updata); //开始写入值 sr.Close(); fs.Close(); } } catch (Exception ex) { mxlLog.Instance.Error($"AddTxT写入错误 CH{CH}: {ex.Message}", ex); } } //将数据写入Txt public void AddTxT(int CH, string updata) { try { string datatime = DateTime.Now.ToString("yyyyMMdd"); if (String.IsNullOrEmpty(filesave.Path)) // 若路径处不输入则获取桌面路径 { filesave.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); filesave.Path = AppDomain.CurrentDomain.BaseDirectory + "Storage"; } string filepath = filesave.Path + "\\"; if (!Directory.Exists(filepath)) { Directory.CreateDirectory(filepath); } // 文件不存在则创建 string strfile = filepath + DateTime.Today.ToString("yyyy-MM-dd") + "_" + CH + ".txt"; if (!System.IO.File.Exists(strfile)) { FileStream fs1 = new FileStream(strfile, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs1); sw.WriteLine(updata); //开始写入值 sw.Close(); fs1.Close(); } else { FileStream fs = new FileStream(strfile, FileMode.Append, FileAccess.Write); StreamWriter sr = new StreamWriter(fs); sr.WriteLine(updata); //开始写入值 sr.Close(); fs.Close(); } } catch (Exception ex) { mxlLog.Instance.Error($"AddTxT写入错误 CH{CH}: {ex.Message}", ex); } } //将数据写入Excel表格 通道 结果 条码 private void AddExcel(int CH, bool result, string code) { Console.WriteLine($"AddExcel code: {code}"); try { string datatime = DateTime.Now.ToString("yyyyMMdd"); if (String.IsNullOrEmpty(filesave.Path)) // 若路径处不输入则获取桌面路径 { filesave.Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); } string filepath = filesave.Path + "\\"; if (CH == 1) { filepath += "CH1\\"; } else if(CH == 2) { filepath += "CH2\\"; } else if (CH == 3) { filepath += "CH3\\"; } else if (CH == 4) { filepath += "CH4\\"; } if (!Directory.Exists(filepath)) // 没有则创建 { Directory.CreateDirectory(filepath); } string name = CH.ToString() + "_" + datatime + ".xls"; filepath += name; Excel.Application xapp = new Excel.Application(); Excel.Workbook xbook = null; if (File.Exists(filepath) == false) // 文件没有则创建 { // 若不存在该文件,则创建新文件 xbook = xapp.Workbooks.Add(); Excel.Worksheet hxsheet = (Excel.Worksheet)xbook.Sheets[1]; string[] fieldArr = { "时间", "条形码", "充气时间", "平衡时间", "检测时间", "排气时间", "充气压力上限", "充气压力下限", "平衡压差上限", "平衡压差下限", "泄漏量上限", "泄漏量下限", "测试结果", "测试压力", "微漏泄漏量" }; //写入表头 for (int i = 0; i < fieldArr.Length; i++) { hxsheet.Cells[1, i + 1] = fieldArr[i]; } xbook.SaveAs(filepath); xbook.Close(); } // 打开文件 xbook = xapp.Workbooks.Open(filepath); Excel.Worksheet xsheet = (Excel.Worksheet)xbook.Sheets[1]; // 获取最后一行 int lastRow = xsheet.Cells.Find("*", System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Row; // 准备数据 string[] dataArr = null; if (CH == 1) { string ngret = ""; string fSmallLeak = LL28CH1client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH1_SmallLeak.Text + lb_CH1_SmallLeakUnit.Text; } dataArr = new string[] { DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), code, (LL28CH1client.ArrRegister[6] / 10.0).ToString() + "s", (LL28CH1client.ArrRegister[7] / 10.0).ToString() + "s", (LL28CH1client.ArrRegister[8] / 10.0).ToString() + "s", (LL28CH1client.ArrRegister[9] / 10.0).ToString() + "s", LL28CH1client.readFloatF2(13) + lb_CH1_PressureUnit.Text, LL28CH1client.readFloatF2(15) + lb_CH1_PressureUnit.Text, LL28CH1client.readFloatF2(17) + lb_CH1_PressureUnit.Text, LL28CH1client.readFloatF2(19) + lb_CH1_PressureUnit.Text, LL28CH1client.readFloatF2(21) + lb_CH1_SmallLeakUnit.Text, LL28CH1client.readFloatF2(23) + lb_CH1_SmallLeakUnit.Text, result ? "OK":"NG", lb_CH1_TestPressure.Text + lb_CH1_PressureUnit.Text, ngret }; } else if (CH == 2) { string ngret = ""; string fSmallLeak = LL28CH2client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH2_SmallLeak.Text + lb_CH2_SmallLeakUnit.Text; } dataArr = new string[] { DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), code, (LL28CH2client.ArrRegister[6] / 10.0).ToString() + "s", (LL28CH2client.ArrRegister[7] / 10.0).ToString() + "s", (LL28CH2client.ArrRegister[8] / 10.0).ToString() + "s", (LL28CH2client.ArrRegister[9] / 10.0).ToString() + "s", LL28CH2client.readFloatF2(13) + lb_CH2_PressureUnit.Text, LL28CH2client.readFloatF2(15) + lb_CH2_PressureUnit.Text, LL28CH2client.readFloatF2(17) + lb_CH2_PressureUnit.Text, LL28CH2client.readFloatF2(19) + lb_CH2_PressureUnit.Text, LL28CH2client.readFloatF2(21) + lb_CH2_SmallLeakUnit.Text, LL28CH2client.readFloatF2(23) + lb_CH2_SmallLeakUnit.Text, result ? "OK":"NG", lb_CH2_TestPressure.Text + lb_CH2_PressureUnit.Text, ngret }; } else if (CH == 3) { string ngret = ""; string fSmallLeak = LL28CH3client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH3_SmallLeak.Text + lb_CH3_SmallLeakUnit.Text; } dataArr = new string[] { DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), code, (LL28CH3client.ArrRegister[6] / 10.0).ToString() + "s", (LL28CH3client.ArrRegister[7] / 10.0).ToString() + "s", (LL28CH3client.ArrRegister[8] / 10.0).ToString() + "s", (LL28CH3client.ArrRegister[9] / 10.0).ToString() + "s", LL28CH3client.readFloatF2(13) + lb_CH3_PressureUnit.Text, LL28CH3client.readFloatF2(15) + lb_CH3_PressureUnit.Text, LL28CH3client.readFloatF2(17) + lb_CH3_PressureUnit.Text, LL28CH3client.readFloatF2(19) + lb_CH3_PressureUnit.Text, LL28CH3client.readFloatF2(21) + lb_CH3_SmallLeakUnit.Text, LL28CH3client.readFloatF2(23) + lb_CH3_SmallLeakUnit.Text, result ? "OK":"NG", lb_CH3_TestPressure.Text + lb_CH3_PressureUnit.Text, ngret }; } else if (CH == 4) { string ngret = ""; string fSmallLeak = LL28CH4client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH4_SmallLeak.Text + lb_CH4_SmallLeakUnit.Text; } dataArr = new string[] { DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), code, (LL28CH4client.ArrRegister[6] / 10.0).ToString() + "s", (LL28CH4client.ArrRegister[7] / 10.0).ToString() + "s", (LL28CH4client.ArrRegister[8] / 10.0).ToString() + "s", (LL28CH4client.ArrRegister[9] / 10.0).ToString() + "s", LL28CH4client.readFloatF2(13) + lb_CH4_PressureUnit.Text, LL28CH4client.readFloatF2(15) + lb_CH4_PressureUnit.Text, LL28CH4client.readFloatF2(17) + lb_CH4_PressureUnit.Text, LL28CH4client.readFloatF2(19) + lb_CH4_PressureUnit.Text, LL28CH4client.readFloatF2(21) + lb_CH4_SmallLeakUnit.Text, LL28CH4client.readFloatF2(23) + lb_CH4_SmallLeakUnit.Text, result ? "OK":"NG", lb_CH4_TestPressure.Text + lb_CH4_PressureUnit.Text, ngret }; } // 写入数据 for (int i = 0; i < dataArr.Length; i++) { xsheet.Cells[lastRow + 1, i + 1] = dataArr[i]; } // 保存并关闭 xbook.Save(); xbook.Close(); xapp.Quit(); // 释放COM对象 Marshal.ReleaseComObject(xsheet); Marshal.ReleaseComObject(xbook); Marshal.ReleaseComObject(xapp); //// 在保存完成后,生成图表 //System.Threading.ThreadPool.QueueUserWorkItem(state => //{ // // 生成趋势图(每20个产品生成一次) // Chart.Create_TrendChart(CH, filepath, 20); // // 生成统计图(每天生成一次) // Chart.Create_PieChart(CH, filepath); //}); } catch (Exception ex) { MessageBox.Show("Excel写入错误:" + ex.Message); mxlLog.Instance.Error($"Excel写入错误 ,行号{ex.StackTrace} ", ex); } finally { // 确保Excel进程被关闭 GC.Collect(); GC.WaitForPendingFinalizers(); } } //离线版CSV文件 private void AddCSVLiXianNg(int CH, bool IsSpot, string code) { try { string fileName; string file = DateTime.Now.ToString("yyyyMMdd"); if (String.IsNullOrEmpty(filesave.Path)) { fileName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\"; } else { fileName = filesave.Path + "\\"; } if (IsSpot) { if (CH == 1) { fileName += "离线OK\\"; file = "1_" + file; } else if (CH == 2) { fileName += "离线OK\\"; file = "2_" + file; } else if (CH == 3) { //fileName += "Left\\"; fileName += "离线OK\\"; file = "3_" + file; } } else { if (CH == 1) { //fileName += "Left\\"; fileName += "离线NG\\"; file = "1_" + file; } else if (CH == 2) { //fileName += "Right\\"; fileName += "离线NG\\"; file = "2_" + file; } else { //fileName += "Right\\"; fileName += "离线NG\\"; file = "3_" + file; } } if (!Directory.Exists(fileName)) { Directory.CreateDirectory(fileName); } string name = file + ".csv"; fileName += name; if (File.Exists(fileName) == false) { StreamWriter fileWriter1 = new StreamWriter(fileName, true, Encoding.UTF8); fileWriter1.Write("时间,条形码,充气时间,平衡时间,测试时间,排气时间,测试压力,泄漏量,测试结果" + "\r\n"); fileWriter1.Flush(); fileWriter1.Close(); } StreamWriter fileWriter = new StreamWriter(fileName, true, Encoding.UTF8); string nowdate = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); if (CH == 1) { //fileWriter.Write(nowdate + ",\t" + MesCh1Code + ","); //fileWriter.Write(ch1params.FullTime + "s" + ","); //fileWriter.Write(ch1params.BalanTime + "s" + ","); //fileWriter.Write(ch1params.TestTime1 + "s" + ","); //fileWriter.Write(ch1params.ExhaustTime + "s" + ","); //fileWriter.Write(ch1params.FPtoplimit + ch1params.PUnit + ","); //fileWriter.Write(ch1params.FPlowlimit + ch1params.PUnit + ","); //fileWriter.Write(ch1params.BalanPreMax + "Pa" + ","); //fileWriter.Write(ch1params.BalanPreMin + "Pa" + ","); //fileWriter.Write(ch1params.Leaktoplimit + ch1params.LUnit + ","); //fileWriter.Write(ch1params.Leaklowlimit + ch1params.LUnit + ","); //fileWriter.Write(CH1Tlight.Text + ","); //fileWriter.Write(lb_CH1_TestPressure.Text + ch1params.PUnit + ","); //fileWriter.Write(CH1BigLeak.Text + ","); //fileWriter.Write(lb_CH1_SmallLeak.Text + ch1params.LUnit + ","); fileWriter.Write(lb_CH1_Result.Text + "\n"); } if (CH == 2) { //fileWriter.Write(nowdate + ",\t" + MesCh2Code + ","); //fileWriter.Write(ch2params.FullTime + "s" + ","); //fileWriter.Write(ch2params.BalanTime + "s" + ","); //fileWriter.Write(ch2params.TestTime1 + "s" + ","); //fileWriter.Write(ch2params.ExhaustTime + "s" + ","); //fileWriter.Write(ch2params.FPtoplimit + ch2params.PUnit + ","); //fileWriter.Write(ch2params.FPlowlimit + ch2params.PUnit + ","); //fileWriter.Write(ch2params.BalanPreMax + "Pa" + ","); //fileWriter.Write(ch2params.BalanPreMin + "Pa" + ","); //fileWriter.Write(ch2params.Leaktoplimit + ch2params.LUnit + ","); //fileWriter.Write(ch2params.Leaklowlimit + ch2params.LUnit + ","); //fileWriter.Write(CH2Tlight.Text + ","); //fileWriter.Write(CH2LeakPress.Text + ch2params.PUnit + ","); //fileWriter.Write(CH2BigLeak.Text + ","); //fileWriter.Write(CH2SmallLeak.Text + ch2params.LUnit + ","); //fileWriter.Write(CH2Tlight.Text + "\n"); } fileWriter.Flush(); fileWriter.Close(); } catch (Exception ex) { //MessageBox.Show("CSV:" + ex.Message); //wa.InsertWarningData(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "-", "CSV:" + ex.Message); } } //将数据写入CSV文件中 private void AddCSV(int CH, bool IsSpot) { try { string fileName; string file = DateTime.Now.ToString("yyyyMMdd"); if (String.IsNullOrEmpty(filesave.Path)) { fileName = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\"; } else { fileName = filesave.Path + "\\"; } if (IsSpot) { if (CH == 1) { fileName += "在线OK\\"; file = "1_" + file; } else if (CH == 2) { fileName += "在线OK\\"; file = "2_" + file; } else { fileName += "在线OK\\"; file = "3_" + file; } } else { if (CH == 1) { //fileName += "Left\\"; fileName += "在线NG\\"; file = "1_" + file; } else if (CH == 2) { //fileName += "Right\\"; fileName += "在线NG\\"; file = "2_" + file; } else { fileName += "在线NG\\"; file = "3_" + file; } } if (!Directory.Exists(fileName)) { Directory.CreateDirectory(fileName); } string name = file + ".csv"; fileName += name; if (File.Exists(fileName) == false) { StreamWriter fileWriter1 = new StreamWriter(fileName, true, Encoding.UTF8); fileWriter1.Write("时间,条形码,充气时间,平衡时间,测试时间,排气时间,测试压力,泄漏量,测试结果" + "\r\n"); fileWriter1.Flush(); fileWriter1.Close(); } StreamWriter fileWriter = new StreamWriter(fileName, true, Encoding.UTF8); string nowdate = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); if (CH == 1) { //fileWriter.Write(nowdate + ",\t" + MesCh1Code + ","); //fileWriter.Write(ch1params.FullTime + "s" + ","); //fileWriter.Write(ch1params.BalanTime + "s" + ","); //fileWriter.Write(ch1params.TestTime1 + "s" + ","); //fileWriter.Write(ch1params.ExhaustTime + "s" + ","); //fileWriter.Write(ch1params.FPtoplimit + ch1params.PUnit + ","); //fileWriter.Write(ch1params.FPlowlimit + ch1params.PUnit + ","); //fileWriter.Write(ch1params.BalanPreMax + "Pa" + ","); //fileWriter.Write(ch1params.BalanPreMin + "Pa" + ","); //fileWriter.Write(ch1params.Leaktoplimit + ch1params.LUnit + ","); //fileWriter.Write(ch1params.Leaklowlimit + ch1params.LUnit + ","); //fileWriter.Write(lb_CH1_TestPressure.Text + ch1params.PUnit + ","); //fileWriter.Write(CH1BigLeak.Text + ","); //fileWriter.Write(lb_CH1_SmallLeak.Text + ch1params.LUnit + ","); fileWriter.Write(lb_CH1_Result.Text + "\n"); //fileWriter.Write(CH1Tlight.Text + "\n"); } if (CH == 2) { //fileWriter.Write(nowdate + ",\t" + MesCh2Code + ","); //fileWriter.Write(ch2params.FullTime + "s" + ","); //fileWriter.Write(ch2params.BalanTime + "s" + ","); //fileWriter.Write(ch2params.TestTime1 + "s" + ","); //fileWriter.Write(ch2params.ExhaustTime + "s" + ","); //fileWriter.Write(ch2params.FPtoplimit + ch2params.PUnit + ","); //fileWriter.Write(ch2params.FPlowlimit + ch2params.PUnit + ","); //fileWriter.Write(ch2params.BalanPreMax + "Pa" + ","); //fileWriter.Write(ch2params.BalanPreMin + "Pa" + ","); //fileWriter.Write(ch2params.Leaktoplimit + ch2params.LUnit + ","); //fileWriter.Write(ch2params.Leaklowlimit + ch2params.LUnit + ","); fileWriter.Write(lb_CH2_Result.Text + ","); //fileWriter.Write(CH2LeakPress.Text + ch2params.PUnit + ","); fileWriter.Write(lb_CH2BigLeak.Text + ","); //fileWriter.Write(CH2SmallLeak.Text + ch2params.LUnit + ","); fileWriter.Write(lb_CH2_Result.Text + "\n"); } fileWriter.Flush(); fileWriter.Close(); } catch (Exception ex) { //MessageBox.Show("CSV:" + ex.Message); //wa.InsertWarningData(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "-", "CSV:" + ex.Message); } } //在界面显示数据 private void Display(int CH, bool result, string code ,string mode) { string nowdate = DateTime.Now.ToString("HH:mm:ss"); if (CH == 1) { string ngret = ""; string fSmallLeak = LL28CH1client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH1_SmallLeak.Text + lb_CH1_SmallLeakUnit.Text; } string[] dataArr = { $"[CH{CH}{mode}] {nowdate}", code, lb_CH1_TestPressure.Text + lb_CH1_PressureUnit.Text, ngret, result ? "OK":"NG"}; DataGridView1.Rows.Insert(0, dataArr[0], dataArr[1], dataArr[2], dataArr[3], dataArr[4]); } if (CH == 3) { string ngret = ""; string fSmallLeak = LL28CH3client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH3_SmallLeak.Text + lb_CH3_SmallLeakUnit.Text; } string[] dataArr = { $"[CH{CH}{mode}] {nowdate}", code, lb_CH3_TestPressure.Text + lb_CH3_PressureUnit.Text, ngret, result ? "OK" : "NG" }; DataGridView1.Rows.Insert(0, dataArr[0], dataArr[1], dataArr[2], dataArr[3], dataArr[4]); } if (CH == 2) { string ngret = ""; string fSmallLeak = LL28CH2client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH2_SmallLeak.Text + lb_CH2_SmallLeakUnit.Text; } string[] dataArr = { $"[CH{CH}{mode}] {nowdate}", code, lb_CH2_TestPressure.Text + lb_CH2_PressureUnit.Text, ngret, result ? "OK" : "NG"}; DataGridView2.Rows.Insert(0, dataArr[0], dataArr[1], dataArr[2], dataArr[3], dataArr[4]); } if (CH == 4) { string ngret = ""; string fSmallLeak = LL28CH4client.readFloatF2(38); if (fSmallLeak.ToDouble() > 2000) { ngret = LeakNG_ARP(fSmallLeak); } else { ngret = lb_CH4_SmallLeak.Text + lb_CH4_SmallLeakUnit.Text; } string[] dataArr = { $"[CH{CH}{mode}] {nowdate}", code, lb_CH4_TestPressure.Text + lb_CH4_PressureUnit.Text, ngret, result ? "OK" : "NG" }; DataGridView2.Rows.Insert(0, dataArr[0], dataArr[1], dataArr[2], dataArr[3], dataArr[4]); } } // 解析NG项 private string LeakNG_ARP(string leakdata) { //int sw = leakdata.ToInt(); if (leakdata.Split(".")[0] == "5000") { return "超出充气上限"; } if (leakdata.Split(".")[0] == "5001") { return "超出充气下限"; } if (leakdata.Split(".")[0] == "5002") { return "超出平衡压差上限"; } if (leakdata.Split(".")[0] == "5003") { return "超出平衡压差下限"; } if (leakdata.Split(".")[0] == "5004") { return "平衡超出充气压力上限"; } if (leakdata.Split(".")[0] == "5005") { return "平衡超出充气压力下限"; } return "--"; } // 解析NG项 private string LeakNG_ARP_Text(string leakdata) { if (leakdata.Split(".")[0] == "5000") return "50"; // "超出充气上限" if (leakdata.Split(".")[0] == "5001") return "51"; // "超出充气下限" if (leakdata.Split(".")[0] == "5002") return "52"; //"超出平衡压差上限" if (leakdata.Split(".")[0] == "5003") return "53"; //"超出平衡压差下限" if (leakdata.Split(".")[0] == "5004") return "54"; //"平衡超出充气压力上限" if (leakdata.Split(".")[0] == "5005") return "55"; //"平衡超出充气压力下限" return "49"; } // 关闭窗口 private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show("将要关闭窗体,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes) { if (cts != null && !cts.IsCancellationRequested) { cts.Cancel(); // 取消任务 cts.Dispose(); // 释放资源 } LL28CH1client?.Stop(); // 停止线程 LL28CH1client?.Disconnect(); // 断开连接 LL28CH1client?.Dispose(); // 释放资源 LL28CH1client = null; LL28CH2client?.Stop(); // 停止线程 LL28CH2client?.Disconnect(); // 断开连接 LL28CH2client?.Dispose(); // 释放资源 LL28CH2client = null; LL28CH3client?.Stop(); // 停止线程 LL28CH3client?.Disconnect(); // 断开连接 LL28CH3client?.Dispose(); // 释放资源 LL28CH3client = null; LL28CH4client?.Stop(); // 停止线程 LL28CH4client?.Disconnect(); // 断开连接 LL28CH4client?.Dispose(); // 释放资源 LL28CH4client = null; e.Cancel = false; Application.Exit(); } else { e.Cancel = true; } } // 更新UI标签文本 private void SetLabelText(System.Windows.Forms.Label label, string text, Color? color = null) { try { if (label.IsDisposed || cts?.IsCancellationRequested == true) return; if (label.InvokeRequired) { label.BeginInvoke((MethodInvoker)delegate { if (!label.IsDisposed) { label.Text = text; if (color.HasValue) label.ForeColor = color.Value; } }); } else { if (!label.IsDisposed) { label.Text = text; if (color.HasValue) label.ForeColor = color.Value; } } } catch (ObjectDisposedException) { } } // 更新UI文本框文本 private void SetUITextBox(UITextBox textbox, string text, Color? color = null) { try { if (textbox.IsDisposed || cts?.IsCancellationRequested == true) return; if (textbox.InvokeRequired) { textbox.BeginInvoke((MethodInvoker)delegate { if (!textbox.IsDisposed) { textbox.Text = text; if (color.HasValue) textbox.ForeColor = color.Value; } }); } else { if (!textbox.IsDisposed) { textbox.Text = text; if (color.HasValue) textbox.ForeColor = color.Value; } } } catch (ObjectDisposedException) { } } // 更新UI文本框文本 private void SetUITextBox(System.Windows.Forms.TextBox textbox, string text, Color? color = null) { try { if (textbox.IsDisposed || cts?.IsCancellationRequested == true) return; if (textbox.InvokeRequired) { textbox.BeginInvoke((MethodInvoker)delegate { if (!textbox.IsDisposed) { textbox.Text = text; if (color.HasValue) textbox.ForeColor = color.Value; } }); } else { if (!textbox.IsDisposed) { textbox.Text = text; if (color.HasValue) textbox.ForeColor = color.Value; } } } catch (ObjectDisposedException) { } } // 更新进度条值 private void SetProgressBar(Sunny.UI.UIProcessBar progressBar, int value) { try { if (progressBar.IsDisposed || cts?.IsCancellationRequested == true) return; if (progressBar.InvokeRequired) { progressBar.BeginInvoke((MethodInvoker)delegate { if (!progressBar.IsDisposed) { progressBar.Value = Math.Min(value, progressBar.Maximum); } }); } else { if (!progressBar.IsDisposed) { progressBar.Value = Math.Min(value, progressBar.Maximum); } } } catch (ObjectDisposedException) { // } } // 设置进度条最大值 private void SetProgressBarMax(Sunny.UI.UIProcessBar progressBar, int maximum) { try { if (progressBar.IsDisposed || cts?.IsCancellationRequested == true) return; if (progressBar.InvokeRequired) { progressBar.BeginInvoke((MethodInvoker)delegate { if (!progressBar.IsDisposed) { progressBar.Maximum = maximum; // 确保当前值不超过新的最大值 if (progressBar.Value > maximum) progressBar.Value = maximum; } }); } else { if (!progressBar.IsDisposed) { progressBar.Maximum = maximum; if (progressBar.Value > maximum) progressBar.Value = maximum; } } } catch (ObjectDisposedException) { // } } // 串口1接收函数(扫码枪1) //private void CodePort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) //{ // try // { // System.Threading.Thread.Sleep(50); // int len = CodePort1.BytesToRead; //获取可以读取的字节数 // if (len > 1) // { // byte[] buff = new byte[len]; //创建缓存数据数组 // CodePort1.Read(buff, 0, len); //把数据读取到buff数组 // Invoke((new System.Action(() => //接收计数 // { // string time = DateTime.Now.ToString(); // string code = Encoding.Default.GetString(buff); // string CODE = code.Replace("\r\n", ""); // //log.MES_Logmsg(time + " " + CODE); // //ClcCode = CODE; // string codecd = CODE.Length.ToString(); // // PlcCode = code.Substring(0,int.Parse(CH1codeLeng.Text)); // Console.WriteLine("扫码枪1串口收到:" + code); // if (CODE.Length == int.Parse(CH1codeLeng.Text)) // { // CH1Code.Text = CODE; // Slot_PLC_WriteCoil(502, true); // ChkINMsg.Text = "CH1扫码完成"; // } // else // { // ChkINMsg.Text = "当前条形码长度为" + CODE.Length + " " + "所设置的条码长度为" + CH1codeLeng.Text; // } // //PlcReadCode.Interval = 500; // //PlcReadCode.Start(); // // CodeLength(code); // CodePort1.DiscardInBuffer(); // //c#如何把a跟b数据绑定在一起并判断 a是string b是bool // }))); // //入站接口 // // AddGhMES_CheckPass(); // } // else // { // return; // } // } // catch (Exception ex) // { // ShowMessage("Code1:" + ex.Message, 2); // log.PLC_Logmsg(DateTime.Now.ToString() + " " + ex.Message); // } //} // 主界面菜单栏 private void uiNavBar1_MenuItemClick(string itemText, int menuIndex, int pageIndex) { if (!String.IsNullOrEmpty(User) && (User != "操作员")) { if (itemText == "PLC控制") { Form_PLCcontrol elec = new Form_PLCcontrol(); elec.Signal_PLC_WriteCoil += Slot_PLC_WriteCoil; OpenForm(elec); } if (itemText == "PLC通讯配置") { Form_PLC_Serialport elec = new Form_PLC_Serialport(); OpenForm(elec); } if (itemText == "PLC网口配置") { Form_PLC_TCP elec = new Form_PLC_TCP(); OpenForm(elec); } //if (itemText == "基本设置") //{ // Config c1 = new Config(); // OpenForm(c1); //} if (itemText == "测试参数") { Electricity elec = new Electricity(); elec.Signal_PLC_WriteCoil += Slot_PLC_WriteCoil; OpenForm(elec); } if (itemText == "产能清零") { DialogResult result = MessageBox.Show( "确定要清零吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question ); if (result == DialogResult.Yes) { m_production.Clear(); UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 更新产能 } } //if (itemText == "LIN设置") //{ // LinConfig lin = new LinConfig(); // OpenForm(lin); //} if (itemText == "存储设置") { Form_Save save = new Form_Save(); OpenForm(save); } if (itemText == "仪器网络设置") { Form_NetworkSet tcp = new Form_NetworkSet(); OpenForm(tcp); } if (itemText == "MES在线/离线") { MES_Switch(); //Form_Save tcp = new Form_Save(); //OpenForm(tcp); } if (itemText == "查看UPH") { //UPH upph = new UPH(); //OpenForm(upph); } if (itemText == "扫码器设置") { Form_SaomaSet port = new Form_SaomaSet("SerialPort"); // SerialPort/TCP OpenForm(port); } if (itemText == "复测数据") { //DateNG port = new DateNG(); //OpenForm(port); } if (itemText == "权限设置") { UserManagement user = new UserManagement(); OpenForm(user); } if (itemText == "报警记录") { Warning warn = new Warning(); OpenForm(warn); } if (itemText == "清理日志") { mxlLog.Instance.ClearOldLogs(); } //if (itemText=="SPC设置") //{ // SpcApi spc = new SpcApi(); // OpenForm(spc); //} //if (itemText == "智能手表设置") //{ // Watch spc = new Watch(); // OpenForm(spc); //} //if (itemText == "打开文件") //{ // OpenMachineINI.CheckFileExists = true; // OpenMachineINI.Multiselect = false; // OpenMachineINI.CheckPathExists = true; // OpenMachineINI.DefaultExt = ".ini"; // OpenMachineINI.Filter = "配置文件(*.ini)|*.ini"; // OpenMachineINI.ShowDialog(); // string machine_path = OpenMachineINI.FileName; // if (!String.IsNullOrEmpty(machinepath) && (machine_path != "openFileDialog1")) // { // machine = OpenMachineINI.SafeFileName; // machinepath = OpenMachineINI.FileName; // //ReadOrder(); // //ReadSetting(); // } //} //if (itemText == "左工位1通道自检") //{ // ReadParameters(4, 1); //} //if (itemText == "左工位2通道自检") //{ // ReadParameters(4, 2); //} //if (itemText == "右工位1通道自检") //{ // ReadParameters(4, 3); //} //if (itemText == "右工位2通道自检") //{ // ReadParameters(4, 4); //} } if (itemText == "PLC重连") { } if (itemText == "段别查询") { //DuanBie db = new DuanBie(); //OpenForm(db); } if (itemText == "MES设置") { Form_HQMESconfig mes = new Form_HQMESconfig(); OpenForm(mes); //GhMes mes = new GhMes(); //OpenForm(mes); } //if (itemText == "启动") //{ // plc.MachineStart(); //} //if (itemText == "复位") //{ // plc.MachineReset(); //} if (itemText == "登录") { Form_LogOn log = new Form_LogOn(); OpenForm(log); } if (itemText == "注销") { User = "操作员"; lb_User.Text = "操作员"; tb_CH1codeLeng.Enabled = false; tb_CH2codeLeng.Enabled = false; tb_CH3codeLeng.Enabled = false; tb_CH4codeLeng.Enabled = false; } if (itemText == "MES日志") { //MESMsg.mesmsg.Show(); //if (filesave.ChkMES) //{ // //mesmsg.Show(); // string path = System.Environment.CurrentDirectory + "\\MES_Log" + "/" + DateTime.Today.ToString("yyyy-MM-dd") + ".txt"; // if (File.Exists(path)) // { // Process.Start(path); // //File.Open(path, FileMode.Open); // //pro // } // else // { // //MessageBox.Show("无今日mes日志!"); // } //} //else //{ // //MessageBox.Show("没有勾选mes!"); //} } if (User == "厂商" || User == "工程师") { if (itemText == "CH1仪器启动") { ch1workstation = (int)yiqi.start; return; } if (itemText == "CH2仪器启动") { ch2workstation = (int)yiqi.start; return; } if (itemText == "CH3仪器启动") { ch3workstation = (int)yiqi.start; return; } if (itemText == "CH4仪器启动") { ch4workstation = (int)yiqi.start; return; } if (itemText == "CH1仪器-复位") { ch1workstation = (int)yiqi.rst; return; } if (itemText == "CH2仪器-复位") { ch2workstation = (int)yiqi.rst; return; } if (itemText == "CH3仪器-复位") { ch3workstation = (int)yiqi.rst; return; } if (itemText == "CH4仪器-复位") { ch4workstation = (int)yiqi.rst; return; } if (itemText == "厂商配置") { Form_RootSet root = new Form_RootSet(); OpenForm(root); } } if (User == "厂商") { if (itemText == "高级功能设置") { LeakCompensate comp = new LeakCompensate(); OpenForm(comp); } } } // MES开关 private void MES_Switch() { var jsconfig = new JsonConfig("config.json"); if (m_MESswitch) { m_MESswitch = false; lb_MESswitch.Text = "MES离线"; pb_MESswitch.BackColor = Color.Red; jsconfig.SetValue("MESswitch", false); } else { // mes初始化 if (HQMES_Init()) { m_MESswitch = true; lb_MESswitch.Text = "MES在线"; pb_MESswitch.BackColor = Color.Green; jsconfig.SetValue("MESswitch", true); } else { m_MESswitch = false; lb_MESswitch.Text = "MES离线"; pb_MESswitch.BackColor = Color.Red; jsconfig.SetValue("MESswitch", false); } } } // 表格1根据结果变色 //#region 表格根据结果变色 private void DataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) { for (int i = 0; i < this.DataGridView1.Rows.Count - 1; i++) { if (this.DataGridView1.Rows[i].Cells["Column7"].Value.ToString() == "OK") { this.DataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Green; } if (this.DataGridView1.Rows[i].Cells["Column7"].Value.ToString() == "NG") { this.DataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Red; } if ((this.DataGridView1.Rows[i].Cells["Column7"].Value.ToString() != "NG") && (this.DataGridView1.Rows[i].Cells["Column7"].Value.ToString() != "OK")) { this.DataGridView1.Rows[i].DefaultCellStyle.ForeColor = Color.Blue; } } } // 表格2根据结果变色 private void DataGridView2_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) { for (int i = 0; i < this.DataGridView2.Rows.Count - 1; i++) { if (this.DataGridView2.Rows[i].Cells["dataGridViewTextBoxColumn7"].Value.ToString() == "OK") { this.DataGridView2.Rows[i].DefaultCellStyle.ForeColor = Color.Green; } if (this.DataGridView2.Rows[i].Cells["dataGridViewTextBoxColumn7"].Value.ToString() == "NG") { this.DataGridView2.Rows[i].DefaultCellStyle.ForeColor = Color.Red; } if ((this.DataGridView2.Rows[i].Cells["dataGridViewTextBoxColumn7"].Value.ToString() != "NG") && (this.DataGridView2.Rows[i].Cells["dataGridViewTextBoxColumn7"].Value.ToString() != "OK")) { this.DataGridView2.Rows[i].DefaultCellStyle.ForeColor = Color.Blue; } } } // 界面退出按钮 private void uiHeaderButton1_Click(object sender, EventArgs e) { System.Environment.Exit(0); } // 字节转字符串 public string ByteToHexStr(byte[] bytes) { string returnStr = ""; try { if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("X2");//每个字节转换成两位十六进制 // returnStr += " ";//两个16进制用空格隔开,方便看数据 } } return returnStr; } catch (Exception) { return returnStr; } } //将发送数据转为十六进制数据 private static byte[] StrtoHexbyte(String hexstring) { hexstring = hexstring.Replace(" ", ""); byte[] returnBytes = new byte[(hexstring.Length) / 2]; try { for (int i = 0; i < returnBytes.Length; i++) { returnBytes[i] = Convert.ToByte(hexstring.Substring(i * 2, 2), 16); } } catch (Exception ex) { //MessageBox.Show(ex.Message); return null; } return returnBytes; } //定时清理垃圾 [DllImport("kernel32.dll")] private static extern bool SetProcessWorkingSetSize(IntPtr process, int minsuze, int maxSize); //定时清理垃圾 private void timer1_Tick(object sender, EventArgs e) { FlushMemory(); if (lb_MESswitch.Text == "MES离线") { lb_CH1MES_INstatus.Text = ""; lb_CH2MES_INstatus.Text = ""; lb_CH3MES_INstatus.Text = ""; lb_CH4MES_INstatus.Text = ""; lb_CH1MES_OUTstatus.Text = ""; lb_CH2MES_OUTstatus.Text = ""; lb_CH3MES_OUTstatus.Text = ""; lb_CH4MES_OUTstatus.Text = ""; } } //强制释放内存 public static void FlushMemory() { GC.Collect(); GC.WaitForPendingFinalizers(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1); } } // 定时函数 定时退出用户 private void UserClear_Tick(object sender, EventArgs e) { if (Environment.MachineName.Trim() == "PC-20230419CFZS") // 计算机名 return; if (Form1.f1.lb_User.Text == "厂商") { lb_User.Text = "操作员"; User = "操作员"; } } // 用户变化 private void Admin_TextChanged(object sender, EventArgs e) { if (lb_User.Text == "厂商" && lb_User.Text == "管理员") { tb_CH1codeLeng.Enabled = true; tb_CH2codeLeng.Enabled = true; tb_CH3codeLeng.Enabled = true; tb_CH4codeLeng.Enabled = true; } else { tb_CH1codeLeng.Enabled = false; tb_CH2codeLeng.Enabled = false; tb_CH3codeLeng.Enabled = false; tb_CH4codeLeng.Enabled = false; } } // 用户属性变化 private void Admin_TabIndexChanged(object sender, EventArgs e) { if (lb_User.Text == "厂商") { // 用户重置 UserClear.Interval = 600000; UserClear.Start(); } } // 清除条码1 private void button2_Click(object sender, EventArgs e) { tb_CH1Code.Text = ""; ch1_oldcode = ""; lb_CH1MES_INstatus.Text = "##"; } // 清除条码2 private void button3_Click(object sender, EventArgs e) { tb_CH2Code.Text = ""; ch1_oldcode = ""; lb_CH2MES_INstatus.Text = "##"; } // 清除条码3 private void bt_code3clear_Click(object sender, EventArgs e) { tb_CH3Code.Text = ""; ch1_oldcode = ""; lb_CH3MES_INstatus.Text = "##"; } // 清除条码4 private void bt_code4clear_Click(object sender, EventArgs e) { tb_CH4Code.Text = ""; ch1_oldcode = ""; lb_CH4MES_INstatus.Text = "##"; } //防止打开多个相同的窗口 public void OpenForm(System.Windows.Forms.Form frm, bool isStatic = false) { if (frm == null) return; foreach (System.Windows.Forms.Form f in System.Windows.Forms.Application.OpenForms) { if (f.Name == frm.Name) { f.Activate(); //if(isStatic) // f.ShowDialog(); //else f.Show(); frm.Dispose(); System.GC.Collect(); System.GC.WaitForPendingFinalizers(); return; } } frm.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; //if (isStatic) // frm.ShowDialog(); //else frm.Show(); System.GC.Collect(); System.GC.WaitForPendingFinalizers(); } public bool ch1AutoConnect = true; // 仪器自动重连 public bool ch2AutoConnect = true; public bool ch3AutoConnect = true; public bool ch4AutoConnect = true; private int ch1ReconnectCount = 0; // 仪器自动重连次数 private int ch2ReconnectCount = 0; private int ch3ReconnectCount = 0; private int ch4ReconnectCount = 0; // 定时器 监控仪器通讯状态 private void timer_yiqiRun_Tick(object sender, EventArgs e) { try { // 通道1 if (LL28CH1client != null && LL28CH1client.isRunning) { lb_CH1Communication_status.Text = "OK"; lb_CH1Communication_status.ForeColor = Color.Green; ch1ReconnectCount = 0; } else { lb_CH1Communication_status.Text = "NG"; lb_CH1Communication_status.ForeColor = Color.Red; if(ch1AutoConnect) // 重连 { ch1ReconnectCount++; if (ch1ReconnectCount % 6 == 0) { LL28CH1client?.Stop(); // 先停止线程(如果正在运行) LL28CH1client?.Disconnect(); // 断开旧连接 LL28CH1client?.Connect(ch1ipaddress); // 连接新 IP LL28CH1client?.Start(); // 重新启动线程 } } } // 通道2 if (LL28CH2client != null && LL28CH2client.isRunning) { lb_CH2Communication_status.Text = "OK"; lb_CH2Communication_status.ForeColor = Color.Green; ch2ReconnectCount = 0; } else { lb_CH2Communication_status.Text = "NG"; lb_CH2Communication_status.ForeColor = Color.Red; if(ch2AutoConnect) // 重连 { ch2ReconnectCount++; if (ch2ReconnectCount % 6 == 0) { LL28CH2client?.Stop(); // 先停止线程(如果正在运行) LL28CH2client?.Disconnect(); // 断开旧连接 LL28CH2client?.Connect(ch2ipaddress); // 连接新 IP LL28CH2client?.Start(); // 重新启动线程 } } } // 通道3 if (LL28CH3client != null && LL28CH3client.isRunning) { lb_CH3Communication_status.Text = "OK"; lb_CH3Communication_status.ForeColor = Color.Green; ch3ReconnectCount = 0; } else { lb_CH3Communication_status.Text = "NG"; lb_CH3Communication_status.ForeColor = Color.Red; if (ch3AutoConnect) // 重连 { ch3ReconnectCount++; if (ch3ReconnectCount % 6 == 0) { LL28CH3client?.Stop(); // 先停止线程(如果正在运行) LL28CH3client?.Disconnect(); // 断开旧连接 LL28CH3client?.Connect(ch3ipaddress); // 连接新 IP LL28CH3client?.Start(); // 重新启动线程 } } } // 通道4 if (LL28CH4client != null && LL28CH4client.isRunning) { lb_CH4Communication_status.Text = "OK"; lb_CH4Communication_status.ForeColor = Color.Green; ch4ReconnectCount = 0; } else { lb_CH4Communication_status.Text = "NG"; lb_CH4Communication_status.ForeColor = Color.Red; if (ch4AutoConnect) // 重连 { ch4ReconnectCount++; if (ch4ReconnectCount % 6 == 0) { LL28CH4client?.Stop(); // 先停止线程(如果正在运行) LL28CH4client?.Disconnect(); // 断开旧连接 LL28CH4client?.Connect(ch4ipaddress); // 连接新 IP LL28CH4client?.Start(); // 重新启动线程 } } } } catch (OverflowException) { ch1ReconnectCount = 0; // 溢出时重置 ch2ReconnectCount = 0; ch3ReconnectCount = 0; ch4ReconnectCount = 0; } } // 更新条码框 private void UpdateCodeBox(string CODE) { // 1-4顺序放 if (string.IsNullOrEmpty(tb_CH1Code.Text)) { tb_CH1Code.Text = CODE; lastUseCodebox = 1; } else if (string.IsNullOrEmpty(tb_CH2Code.Text)) { tb_CH2Code.Text = CODE; lastUseCodebox = 2; } else if (string.IsNullOrEmpty(tb_CH3Code.Text)) { tb_CH3Code.Text = CODE; lastUseCodebox = 3; } else if (string.IsNullOrEmpty(tb_CH4Code.Text)) { tb_CH4Code.Text = CODE; lastUseCodebox = 4; } else // suoy 所有框都有条码时 { lastUseCodebox = lastUseCodebox % 4 + 1; switch (lastUseCodebox) { case 1: tb_CH1Code.Text = CODE; break; case 2: tb_CH2Code.Text = CODE; break; case 3: tb_CH3Code.Text = CODE; break; case 4: tb_CH4Code.Text = CODE; break; } } } //string lastCode = ""; // 保存上一次条码 int lastUseCodebox = 0; // 保存上一次填充的条码框 // 扫码枪1串口接收函数 private void SerialPort_CH1Saoma_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { System.Threading.Thread.Sleep(50); int len = SerialPort_CH1Saoma.BytesToRead; // 获取可以读取的字节数 if (len > 1) { byte[] buff = new byte[len]; // 创建缓存数据数组 SerialPort_CH1Saoma.Read(buff, 0, len); // 把数据读取到buff数组 Invoke((new System.Action(() => { string time = DateTime.Now.ToString(); string code = Encoding.Default.GetString(buff).Replace(" ", "").Replace("\r", "").Replace("\n", ""); Console.WriteLine("扫码枪1串口收到:" + code); //code = code.Split(';')[0]; //Console.WriteLine("扫码枪1串口去掉分隔符:" + code); if (tb_CH1Code.Text == code || tb_CH2Code.Text == code || tb_CH3Code.Text == code || tb_CH4Code.Text == code) { //MessageBox.Show($"条码 {CODE} 已存在", "重复提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); SerialPort_CH1Saoma.DiscardInBuffer(); return; } if (code.Length.ToString() == tb_CH1codeLeng.Text.Trim()) { tb_CH1Code.Text = code; } else { //SetUITextBox(tb_CH1MainMessage, "CH1当前条形码长度为" + code.Length + " 所设置的条码长度为" + tb_CH1codeLeng.Text); } SerialPort_CH1Saoma.DiscardInBuffer(); }))); } else { return; } } catch (Exception ex) { mxlLog.Instance.Error($"串口扫码枪1接收函数 异常 ,行号{ex.StackTrace} ", ex); } } // 扫码枪2串口接收函数 private void SerialPort_CH2Saoma_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { System.Threading.Thread.Sleep(50); int len = SerialPort_CH2Saoma.BytesToRead; // 获取可以读取的字节数 if (len > 1) { byte[] buff = new byte[len]; // 创建缓存数据数组 SerialPort_CH2Saoma.Read(buff, 0, len); // 把数据读取到buff数组 Invoke((new System.Action(() => { string time = DateTime.Now.ToString(); string code = Encoding.Default.GetString(buff).Replace(" ", "").Replace("\r", "").Replace("\n", ""); Console.WriteLine("扫码枪2串口收到:" + code); //code = code.Split(';')[0]; //Console.WriteLine("扫码枪1串口去掉分隔符:" + code); if (tb_CH1Code.Text == code || tb_CH2Code.Text == code || tb_CH3Code.Text == code || tb_CH4Code.Text == code) { //MessageBox.Show($"条码 {CODE} 已存在", "重复提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); SerialPort_CH2Saoma.DiscardInBuffer(); return; } if (code.Length.ToString() == tb_CH2codeLeng.Text.Trim()) { tb_CH2Code.Text = code; } else { //SetUITextBox(tb_CH2MainMessage, "CH2当前条形码长度为" + code.Length + " 所设置的条码长度为" + tb_CH2codeLeng.Text); } SerialPort_CH2Saoma.DiscardInBuffer(); }))); } else { return; } } catch (Exception ex) { mxlLog.Instance.Error($"串口扫码枪2接收函数 异常 ,行号{ex.StackTrace} ", ex); } } // 扫码枪3串口接收函数 private void SerialPort_CH3Saoma_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { System.Threading.Thread.Sleep(50); int len = SerialPort_CH3Saoma.BytesToRead; // 获取可以读取的字节数 if (len > 1) { byte[] buff = new byte[len]; // 创建缓存数据数组 SerialPort_CH3Saoma.Read(buff, 0, len); // 把数据读取到buff数组 Invoke((new System.Action(() => { string time = DateTime.Now.ToString(); string code = Encoding.Default.GetString(buff).Replace(" ", "").Replace("\r", "").Replace("\n", ""); Console.WriteLine("扫码枪3串口收到:" + code); //code = code.Split(';')[0]; //Console.WriteLine("扫码枪3串口去掉分隔符:" + code); if (tb_CH1Code.Text == code || tb_CH2Code.Text == code || tb_CH3Code.Text == code || tb_CH4Code.Text == code) { //MessageBox.Show($"条码 {CODE} 已存在", "重复提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); SerialPort_CH3Saoma.DiscardInBuffer(); return; } if (code.Length.ToString() == tb_CH3codeLeng.Text.Trim()) { tb_CH3Code.Text = code; } else { //SetUITextBox(tb_CH3MainMessage, "CH3当前条形码长度为" + code.Length + " 所设置的条码长度为" + tb_CH3codeLeng.Text); } SerialPort_CH3Saoma.DiscardInBuffer(); }))); } else { return; } } catch (Exception ex) { mxlLog.Instance.Error($"串口扫码枪3接收函数 异常 ,行号{ex.StackTrace} ", ex); } } // 扫码枪4串口接收函数 private void SerialPort_CH4Saoma_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { System.Threading.Thread.Sleep(50); int len = SerialPort_CH4Saoma.BytesToRead; // 获取可以读取的字节数 if (len > 1) { byte[] buff = new byte[len]; // 创建缓存数据数组 SerialPort_CH4Saoma.Read(buff, 0, len); // 把数据读取到buff数组 Invoke((new System.Action(() => { string time = DateTime.Now.ToString(); string code = Encoding.Default.GetString(buff).Replace(" ", "").Replace("\r", "").Replace("\n", ""); Console.WriteLine("扫码枪4串口收到:" + code); //code = code.Split(';')[0]; //Console.WriteLine("扫码枪4串口去掉分隔符:" + code); if (tb_CH1Code.Text == code || tb_CH2Code.Text == code || tb_CH3Code.Text == code || tb_CH4Code.Text == code) { //MessageBox.Show($"条码 {CODE} 已存在", "重复提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); SerialPort_CH4Saoma.DiscardInBuffer(); return; } if (code.Length.ToString() == tb_CH4codeLeng.Text.Trim()) { tb_CH4Code.Text = code; } else { //SetUITextBox(tb_CH4MainMessage, "CH4当前条形码长度为" + code.Length + " 所设置的条码长度为" + tb_CH4codeLeng.Text); } SerialPort_CH4Saoma.DiscardInBuffer(); }))); } else { return; } } catch (Exception ex) { mxlLog.Instance.Error($"串口扫码枪1接收函数 异常 ,行号{ex.StackTrace} ", ex); } } // 条码变化函数 private void CH1Code_TextChanged(object sender, EventArgs e) { if (!tb_CH1Code.Text.IsNullOrEmpty()) { bool len_bool = tb_CH1Code.Text.Length.ToString() == tb_CH1codeLeng.Text.Trim(); // 长度 bool rep_bool = (tb_CH1Code.Text != tb_CH2Code.Text && tb_CH1Code.Text != tb_CH3Code.Text && tb_CH1Code.Text != tb_CH4Code.Text); // 重复 if (len_bool && rep_bool) { // 首次扫码要写入正压 CH1NowMode = "正压"; LL28CH1client.writeRegisters(1006, GetYiqiParam(1, "P").GetArray()); Slot_PLC_WriteCoil(1008, false); Slot_PLC_WriteCoil(1000, GetYiqiParam(1, "P").opmode); Console.WriteLine("CH1Code_TextChanged()"); // 治具下压-仪器启动 if (m_MESswitch) { Task.Run(() => { // MES入站 var ret = ruzhan(tb_CH1Code.Text, m_ActionName, m_Tools); if (ret.result) { SetLabelText(lb_CH1MES_INstatus, "PASS", Color.Green); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(10, 10); mxlLog.Instance.Info($"CH1入站 PLC写入10"); } catch(Exception ex) { mxlLog.Instance.Error($"CH1入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } else { SetLabelText(lb_CH1MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH1MainMessage, $"CH1 入站NG:{ret.msg}"); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(10, 0); mxlLog.Instance.Info($"CH1入站 PLC写入0"); } catch (Exception ex) { mxlLog.Instance.Error($"CH1入站 PLC写入0异常 ,行号{ex.StackTrace} ", ex); } } } } SetLabelText(lb_CH1MES_OUTstatus, ""); }); } else { if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(10, 10); mxlLog.Instance.Info($"CH1入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH1入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } } else { if(!len_bool) SetUITextBox(tb_CH1MainMessage, $"[CH1]当前条码长度{tb_CH1Code.Text.Length},限定{tb_CH1codeLeng.Text}"); else if(!rep_bool) SetUITextBox(tb_CH1MainMessage, "[CH1]当前条码重复"); // 看起来条码接收函数处理了,这里不会触发 tb_CH1Code.Text = ""; } } else { tb_CH1Code.Focus(); } } private void CH2Code_TextChanged(object sender, EventArgs e) { if (!tb_CH2Code.Text.IsNullOrEmpty()) { bool len_bool = tb_CH2Code.Text.Length.ToString() == tb_CH2codeLeng.Text.Trim(); bool rep_bool = (tb_CH2Code.Text != tb_CH1Code.Text && tb_CH2Code.Text != tb_CH3Code.Text && tb_CH2Code.Text != tb_CH4Code.Text); if (len_bool && rep_bool) { // 首次扫码要写入正压 CH2NowMode = "正压"; LL28CH2client.writeRegisters(1006, GetYiqiParam(2, "P").GetArray()); Slot_PLC_WriteCoil(1009, false); Slot_PLC_WriteCoil(1001, GetYiqiParam(2, "P").opmode); Console.WriteLine("CH2Code_TextChanged()"); // 治具下压-仪器启动 if (m_MESswitch) { Task.Run(() => { // MES入站 var ret = ruzhan(tb_CH2Code.Text, m_ActionName, m_Tools); if (ret.result) { SetLabelText(lb_CH2MES_INstatus, "PASS", Color.Green); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(11, 10); mxlLog.Instance.Info($"CH2入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH2入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } else { SetLabelText(lb_CH2MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH2MainMessage, $"CH2 入站NG:{ret.msg}"); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(11, 0); mxlLog.Instance.Info($"CH2入站 PLC写入0"); } catch (Exception ex) { mxlLog.Instance.Error($"CH2入站 PLC写入0异常 ,行号{ex.StackTrace} ", ex); } } } } SetLabelText(lb_CH2MES_OUTstatus, ""); }); } else { if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(11, 10); mxlLog.Instance.Info($"CH2入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH2入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } } else { if (!len_bool) SetUITextBox(tb_CH2MainMessage, $"[CH2]当前条码长度{tb_CH2Code.Text.Length},限定{tb_CH2codeLeng.Text}"); else if (!rep_bool) SetUITextBox(tb_CH2MainMessage, "[CH2]当前条码重复"); tb_CH2Code.Text = ""; } } else { tb_CH2Code.Focus(); } } private void lb_CH3Code_TextChanged(object sender, EventArgs e) { if (!tb_CH3Code.Text.IsNullOrEmpty()) { bool len_bool = tb_CH3Code.Text.Length.ToString() == tb_CH3codeLeng.Text.Trim(); bool rep_bool = (tb_CH3Code.Text != tb_CH1Code.Text && tb_CH3Code.Text != tb_CH2Code.Text && tb_CH3Code.Text != tb_CH4Code.Text); if (len_bool && rep_bool) { // 首次扫码要写入正压 CH3NowMode = "正压"; LL28CH3client.writeRegisters(1006, GetYiqiParam(3, "P").GetArray()); Slot_PLC_WriteCoil(1010, false); Slot_PLC_WriteCoil(1002, GetYiqiParam(3, "P").opmode); Console.WriteLine("CH3Code_TextChanged()"); // 治具下压-仪器启动 if (m_MESswitch) { Task.Run(() => { // MES入站 var ret = ruzhan(tb_CH3Code.Text, m_ActionName, m_Tools); if (ret.result) { SetLabelText(lb_CH3MES_INstatus, "PASS", Color.Green); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(12, 10); mxlLog.Instance.Info($"CH3入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH3入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } else { SetLabelText(lb_CH3MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH1MainMessage, $"CH3 入站NG:{ret.msg}"); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(12, 0); mxlLog.Instance.Info($"CH3入站 PLC写入0"); } catch (Exception ex) { mxlLog.Instance.Error($"CH3入站 PLC写入0异常 ,行号{ex.StackTrace} ", ex); } } } } SetLabelText(lb_CH3MES_OUTstatus, ""); }); } else { if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(12, 10); mxlLog.Instance.Info($"CH3入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH3入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } } else { if (!len_bool) SetUITextBox(tb_CH1MainMessage, $"[CH3]当前条码长度{tb_CH3Code.Text.Length},限定{tb_CH3codeLeng.Text}"); else if (!rep_bool) SetUITextBox(tb_CH1MainMessage, "[CH3]当前条码重复"); tb_CH3Code.Text = ""; } } else { tb_CH3Code.Focus(); } } private void lb_CH4Code_TextChanged(object sender, EventArgs e) { if (!tb_CH4Code.Text.IsNullOrEmpty()) { bool len_bool = tb_CH4Code.Text.Length.ToString() == tb_CH4codeLeng.Text.Trim(); bool rep_bool = (tb_CH4Code.Text != tb_CH1Code.Text && tb_CH4Code.Text != tb_CH2Code.Text && tb_CH4Code.Text != tb_CH3Code.Text); if (len_bool && rep_bool) { // 首次扫码要写入正压 CH4NowMode = "正压"; LL28CH4client.writeRegisters(1006, GetYiqiParam(4, "P").GetArray()); Slot_PLC_WriteCoil(1011, false); Slot_PLC_WriteCoil(1003, GetYiqiParam(4, "P").opmode); Console.WriteLine("CH4Code_TextChanged()"); // 治具下压-仪器启动 if (m_MESswitch) { Task.Run(() => { // MES入站 var ret = ruzhan(tb_CH4Code.Text, m_ActionName, m_Tools); if (ret.result) { SetLabelText(lb_CH4MES_INstatus, "PASS", Color.Green); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(13, 10); mxlLog.Instance.Info($"CH4入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH4入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } else { SetLabelText(lb_CH4MES_INstatus, "NG", Color.Red); SetUITextBox(tb_CH2MainMessage, $"CH4 入站NG:{ret.msg}"); if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(13, 0); mxlLog.Instance.Info($"CH4入站 PLC写入0"); } catch (Exception ex) { mxlLog.Instance.Error($"CH4入站 PLC写入0异常 ,行号{ex.StackTrace} ", ex); } } } } SetLabelText(lb_CH4MES_OUTstatus, ""); }); } else { if (HCPLC_client.Connected) { lock (plcLock) // 加锁 { try { HCPLC_client.WriteSingleRegister(13, 10); mxlLog.Instance.Info($"CH4入站 PLC写入10"); } catch (Exception ex) { mxlLog.Instance.Error($"CH4入站 PLC写入10异常 ,行号{ex.StackTrace} ", ex); } } } } } else { if (!len_bool) SetUITextBox(tb_CH2MainMessage, $"[CH4]当前条码长度{tb_CH4Code.Text.Length},限定{tb_CH4codeLeng.Text}"); else if (!rep_bool) SetUITextBox(tb_CH2MainMessage, "[CH4]当前条码重复"); tb_CH4Code.Text = ""; } } else { tb_CH4Code.Focus(); } } // 信息栏变化 private void tb_CH1MainMessage_TextChanged(object sender, EventArgs e) { timer_ClearMainMessage.Stop(); timer_ClearMainMessage.Start(); // 重新计时 } private void tb_CH2MainMessage_TextChanged(object sender, EventArgs e) { timer_ClearMainMessage.Stop(); timer_ClearMainMessage.Start(); } // 定时清空主界面信息框 private void timer_ClearMainMessage_Tick(object sender, EventArgs e) { timer_ClearMainMessage.Stop(); tb_CH1MainMessage.Clear(); tb_CH2MainMessage.Clear(); } static int aaaaa = 0; private void bt_test_Click(object sender, EventArgs e) { //coil1032[0] = true; //int aaa = Convert.ToInt32(tb_mxl.Text); //coil1032[aaa] = true; return; // 读取到M1100为true AlarmManager.UpdateAlarm("M1100", true); AlarmManager.UpdateAlarm("M1101", true); //LL28CH1client.writeRegisters(1006, GetYiqiParam(1,"P").GetArray()); return; aaaaa++; if(aaaaa % 10 == 1) { m_production.AddNG(); } else { m_production.AddOK(); } UploadProductionData(m_production.GetTotal(), m_production.GetOK(), m_production.GetNG(), m_production.GetOKRate()); // 更新产能 //// 测试文件冲突 //CreateFile(1, true, "123456789"); //CreateFile(2, true, "123456789"); //CreateFile(3, true, "123456789"); //CreateFile(4, true, "123456789"); // 写入激活状态 //ActivationManager.WriteActivationStatus(false); //this.Enabled = false; //Form_Activate elec = new Form_Activate(); //elec.Signal_LoginResult += Slot_MainShow; //OpenForm(elec, true); //this.Enabled = false; //mxlLog.Instance.ClearOldLogs(); // MES //if (MESswitch) //{ // RtValue rdata = chuzhan(2, lb_CH2Code.Text, false); // if (rdata.result) // { // SetLabelText(lb_CH2MES_OUTstatus, "PASS", Color.Green); // } // else // { // SetLabelText(lb_CH2MES_OUTstatus, "NG", Color.Red); // } //} //AddTxT(1,true,"123456789"); //tb_CH1MainMessage.Text = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20"; //mxlLog.Instance.Debug($"debug2"); //mxlLog.Instance.Error($"error2"); //LL28CH2client.writeRegisters(1076, new int[] {1}); } private void bt_test2_Click(object sender, EventArgs e) { //int aaa = Convert.ToInt32(tb_mxl.Text); //coil1032[aaa] = false; return; // 读取到M1100为false AlarmManager.UpdateAlarm("M1100", false); //// 读取到M1101为true //AlertManager.UpdateAlert("M1101", true, "CH1通道异常急停触发"); } // 条码长度变化 private void tb_CH1codeLeng_TextChanged(object sender, EventArgs e) { if(tcpSaoma_Enabled && saomaClient1 != null && !tb_CH1codeLeng.Text.IsNullOrEmpty()) { saomaClient1.codeLength = Convert.ToInt32(tb_CH1codeLeng.Text); } } private void tb_CH2codeLeng_TextChanged(object sender, EventArgs e) { if(tcpSaoma_Enabled && saomaClient2 != null && !tb_CH2codeLeng.Text.IsNullOrEmpty()) { saomaClient2.codeLength = Convert.ToInt32(tb_CH2codeLeng.Text); } } // 发送扫码启动 private void timer_SaomaStart_Tick(object sender, EventArgs e) { Slot_SaomaStart(1); Slot_SaomaStart(2); Slot_SaomaStart(3); Slot_SaomaStart(4); } // 显示时间 private void timer_nowTime_Tick(object sender, EventArgs e) { string time = System.DateTime.Now.ToString("HH:mm:ss"); lb_NowTime.Text = time; } private string GetLocalIPv4() { var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { return ip.ToString(); } } throw new Exception("No IPv4 address found."); } #region USB扫码 private StringBuilder codeBuff = new StringBuilder(); private DateTime lastKeyTime = DateTime.Now; private readonly int timeoutMs = 300; private bool monitorAllInput = false; private void tb_CHxCode_KeyPress(object sender, KeyPressEventArgs e) { if (monitorAllInput || sender is Sunny.UI.UITextBox) { ProcessKeyPress(e.KeyChar); e.Handled = true; // 阻止字符显示 } } // 条码字符处理 private void ProcessKeyPress(char keyChar) { TimeSpan elapsed = DateTime.Now - lastKeyTime; if (elapsed.TotalMilliseconds > timeoutMs) { codeBuff.Clear(); } lastKeyTime = DateTime.Now; if (keyChar == '\r' || keyChar == '\n') { string barcode = codeBuff.ToString().Trim(); if (!string.IsNullOrEmpty(barcode)) { UpdateCodeBox(barcode); } codeBuff.Clear(); } else { codeBuff.Append(keyChar); } } // 主窗口的KeyPreview设置为true,重写函数捕获所有键盘输入(勿删,没有引用,但是运行需调用) protected override void OnKeyPress(KeyPressEventArgs e) { if (monitorAllInput) { ProcessKeyPress(e.KeyChar); e.Handled = true; // 阻止进一步处理 } base.OnKeyPress(e); // 调用基类实现,确保其他功能正常 } // 专注扫码复选框 private void chk_SaomaFocus_CheckedChanged(object sender, EventArgs e) { monitorAllInput = chk_SaomaFocus.Checked; if (monitorAllInput) { // 监控所有输入时,让文本框获取焦点以便接收键盘事件 this.Focus(); } } #endregion #region 华勤MES [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int MESBackFunc(StringBuilder data); /// /// mes函数执行成功 /// public const int MesBackOK = 0; /// /// MES的句柄 /// public static int hMes = 0; private const string DLLPATH = "HQMES.dll"; [DllImport(DLLPATH)] public static extern int MesInit(MESBackFunc func, ref int hMes, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] public static extern int MesStart(int hMes, string SN, string ActionName, string Tools, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] public static extern int MesStart2(int hMes, string SN, string SNType, string ActionName, string Tools, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] public static extern int MesEnd(int hMes, string SN, string ActionName, string Tools, string ErrorCode, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] public static extern int MesEnd2(int hMes, string SN, string SNType, string ActionName, string Tools, string ErrorCode, string AllData, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] private static extern int MesSaveAndGetExtraInfo(int hMes, string G_TYPE, string G_POSITION, string G_KEY, string G_VALUE, string G_EXTINFO, StringBuilder sInfo, ref int InfoLen); [DllImport(DLLPATH)] public static extern int MesUnInit(int hMes); [DllImport(DLLPATH)] public static extern int MesStart3(int hMes, string SN, string SNType, string ActionName, string Tools, string Extinfo, StringBuilder sInfo, ref int InfoLen); private static MESBackFunc tempFunc;// 必须要加一个变量,这样不会被回收 public static int WriteLogFile(StringBuilder data) { return 0; } // 华勤mes参数 public static string m_ActionName; public static string m_Tools; public static string m_LINE; public static string G_CHECKFLOWID; static int hmes = 0; // 华勤MES初始化 public static bool HQMES_Init() { int len = 102400; StringBuilder strdata = new StringBuilder(len); if (hMes == 0) { tempFunc = WriteLogFile; // 必须要加一个变量,这样不会被回收 这个回调函数赋值只能放在这个位置,防止当多次点击init之后可能会出现回调函数被回收的现象 if (0 == MesInit(tempFunc, ref hMes, strdata, ref len)) { JObject mesObj = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); string version = ""; version = mesObj.GetValue("H_MSG") == null ? "" : mesObj.GetValue("H_MSG").ToString(); // 获取meshelepr的版本 MessageBox.Show("初始化链接MES 成功 !MEShelper版本:" + version); // strdata会返回一个meshelper的版本号表示初始化成功 return true; } else { hMes = 0; MessageBox.Show("初始化链接MES 失败!"); return false; } } else { //MessageBox.Show("请勿重复初始化MES链接!"); return true; } } // 华勤MES入站 public static (bool result, string msg) ruzhan(string SN, string ActionName, string toolName) { string time1 = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); int InfoLen = 102400; StringBuilder sInfo = new StringBuilder(InfoLen); if (hMes != 0) { string DATA = ""; string H_MSG = ""; string G_RET_DATA = ""; string NeedLoad = ""; mxlLog.Instance.MESDebug($"入站 SN:{SN} - ActionName:{ActionName} - toolName:{toolName} - sInfo:{sInfo} - InfoLen:{InfoLen}"); if (0 == MesStart(hMes, SN, ActionName, toolName, sInfo, ref InfoLen)) { mxlLog.Instance.MESDebug($"入站 OK:{SN} - sInfo:{sInfo.ToString()}"); JObject retObj = (JObject)JsonConvert.DeserializeObject(sInfo.ToString()); DATA = retObj.GetValue("DATA") == null ? "" : retObj.GetValue("DATA").ToString(); // data是一个json字符串,其中包含mes返回的主要字段,按照这个参考继续解析出来 例如获取CSN // 解析返回信息 JObject dataObj = (JObject)JsonConvert.DeserializeObject(DATA); string CSN = dataObj.GetValue("CSN") == null ? "" : dataObj.GetValue("CSN").ToString(); G_CHECKFLOWID = dataObj.GetValue("G_CHECKFLOWID") == null ? "" : dataObj.GetValue("G_CHECKFLOWID").ToString(); H_MSG = retObj.GetValue("H_MSG") == null ? "" : retObj.GetValue("H_MSG").ToString(); G_RET_DATA = retObj.GetValue("G_RET_DATA") == null ? "" : retObj.GetValue("G_RET_DATA").ToString(); // 标记工具需要回传给MES的字段,是json格式,将其解析出来可以得到字段,工具必须将该字段赋值并回传给MES,在endmes函数回传 NeedLoad = retObj.GetValue("NeedLoad") == null ? "" : retObj.GetValue("NeedLoad").ToString(); // 标记工具是否需要重启 if (!String.IsNullOrEmpty(H_MSG) && H_MSG == "MES response:") { return (true, H_MSG); } else { return (false, H_MSG); } } else { mxlLog.Instance.MESDebug($"入站 NG:{SN} - sInfo:{sInfo.ToString()}"); JObject retObj = (JObject)JsonConvert.DeserializeObject(sInfo.ToString()); H_MSG = retObj.GetValue("H_MSG") == null ? "" : retObj.GetValue("H_MSG").ToString(); // mes返回的错误信息最好将其在工具界面展示出来给操作人员查看 return (false, sInfo.ToString()); } } else { MessageBox.Show("请初始化MES链接!"); return (false, sInfo.ToString()); } } public static (bool result, string msg) chuzhan(int CH, string SN, string ActionName, string Tools, string checkFlowId, bool result) { int InfoLen = 102400; Log log = new Log(); StringBuilder sInfo = new StringBuilder(InfoLen); if (hMes != 0) { string ErrorCode = "0"; Dictionary map = new Dictionary(); // 确认错误码和错误项 if (result) { ErrorCode = "0"; } else { ErrorCode = "NG"; sInfo.Append($"泄漏量超出设定范围"); // 错误详细描述 } switch (CH) { case 1: map["Xlvall"] = Form1.f1.lb_CH1_TestPressure.Text + Form1.f1.lb_CH1_PressureUnit.Text; // 测试压力 map["Csvall"] = Form1.f1.LL28CH1client.readFloatF2(38); // 泄漏量 break; case 2: map["Xlvall"] = Form1.f1.lb_CH2_TestPressure.Text + Form1.f1.lb_CH2_PressureUnit.Text; // 测试压力 map["Csvall"] = Form1.f1.LL28CH2client.readFloatF2(38); // 泄漏量 break; case 3: map["Xlvall"] = Form1.f1.lb_CH3_TestPressure.Text + Form1.f1.lb_CH3_PressureUnit.Text; // 测试压力 map["Csvall"] = Form1.f1.LL28CH3client.readFloatF2(38); // 泄漏量 break; case 4: map["Xlvall"] = Form1.f1.lb_CH4_TestPressure.Text + Form1.f1.lb_CH4_PressureUnit.Text; // 测试压力 map["Csvall"] = Form1.f1.LL28CH4client.readFloatF2(38); // 泄漏量 break; } //压力转换 map["G_OP_LINE"] = m_LINE; map["DateTime"] = DateTime.Now.ToString(); map["G_CHECKFLOWID"] = checkFlowId; string AllData = JsonConvert.SerializeObject(map); string SNType = "1"; mxlLog.Instance.MESDebug($"出站-通道{CH} MesEnd2:" + $"hMes:{hMes}-SN:{SN}-SNType:{SNType}-ActionName:{ActionName}-toolName:{Tools}-ErrorCode:{ErrorCode}-AllData:{AllData}-strdata:{sInfo}-len:{InfoLen}"); if (0 == MesEnd2(hMes, SN, SNType, ActionName, Tools, ErrorCode, AllData, sInfo, ref InfoLen)) { mxlLog.Instance.MESDebug($"出站-通道{CH} OK:{SN} - sInfo:{sInfo.ToString()}"); JObject retObj = (JObject)JsonConvert.DeserializeObject(sInfo.ToString()); string msg = retObj.GetValue("G_NEXTWS") == null ? "" : retObj.GetValue("G_NEXTWS").ToString(); if (!String.IsNullOrEmpty(msg) && (msg.Contains("过站成功") || msg.Contains("测试PASS"))) // 还需优化,文档未标注已过站字段 { return (true, msg); } else { return (false, msg); } } else { mxlLog.Instance.MESDebug($"出站-通道{CH} NG:{SN} - sInfo:{sInfo.ToString()}"); return (false, sInfo.ToString()); } } else { MessageBox.Show("请初始化MES链接!"); return (false, sInfo.ToString()); } } #endregion // 启动5s后,如果仪器在运行则写入正压参数 private void timer2_Tick(object sender, EventArgs e) { timer2.Stop(); Task.Run(() => { { CH1NowMode = "正压"; LL28CH1client.writeRegisters(1006, GetYiqiParam(1, "P").GetArray()); Slot_PLC_WriteCoil(1008, false); Slot_PLC_WriteCoil(1000, GetYiqiParam(1, "P").opmode); } { CH2NowMode = "正压"; LL28CH2client.writeRegisters(1006, GetYiqiParam(2, "P").GetArray()); Slot_PLC_WriteCoil(1009, false); Slot_PLC_WriteCoil(1001, GetYiqiParam(2, "P").opmode); } { CH3NowMode = "正压"; LL28CH3client.writeRegisters(1006, GetYiqiParam(3, "P").GetArray()); Slot_PLC_WriteCoil(1010, false); Slot_PLC_WriteCoil(1002, GetYiqiParam(3, "P").opmode); } { CH4NowMode = "正压"; LL28CH4client.writeRegisters(1006, GetYiqiParam(4, "P").GetArray()); Slot_PLC_WriteCoil(1011, false); Slot_PLC_WriteCoil(1003, GetYiqiParam(4, "P").opmode); } }); } } }