Browse Source

s4/5 进站 出战

lipeihang123 1 month ago
parent
commit
09eb34b8f4
1 changed files with 583 additions and 20 deletions
  1. 583 20
      MainForm/FaForm/Form_Home.cs

+ 583 - 20
MainForm/FaForm/Form_Home.cs

@@ -2437,6 +2437,585 @@ namespace MainForm
         #endregion [S3] 值板机
         #endregion PLC3 刘永村
 
+        /// <summary>
+        /// [S4] 点胶检测设备
+        /// </summary>
+        /// <param name="plcNo">PLC编号</param>
+        private void ReadStation_S4(int plcNo)
+        {
+            string stationCode = "[S4]";
+            string stationName = "点胶检测设备";
+            string stationNameStr = stationCode + stationName;
+            string tagBaseName = "g_OP40_MES";   //标签变量名称
+            string tagMesCommName = "mesCommToPC";   //标签变量名称
+            string tagAgvCommName = "agvCommFrmPC";
+            string tagBarsetName = "BarcodeSet";
+
+            OP40_MesData_t stPLC_MesData;        //PLC的MES数据
+            (int, string) result;
+            bool ProgressState = true;
+
+            #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0);  // PLC_FLAG 载具进站查询状态
+            s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0);          // PLC_FLAG 上料进站校验
+            s1PLCSignal_Old.Add("a1PLC_FLAG", 0);                // PLC_FLAG 出站接口
+            s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0);            // PLC_FLAG 将SN发给ICT标机(串口)
+            s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0);             // PLC_FLAG 节拍接口
+            s1PLCSignal_Old.Add("a1AGVUpCall", 0);               // AGV上料叫agv信号 AGV上料
+            s1PLCSignal_Old.Add("a1AGVUpEnd", 0);                // AGV上料完成信号 AGV上料
+            s1PLCSignal_Old.Add("a1AGVDownCall", 0);             // AGV下料叫agv信号 AGV下料
+            s1PLCSignal_Old.Add("a1AGVDownEnd", 0);              // AGV下料完成信号 AGV下料
+
+            // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0);    // PLC_FLAG 载具进站查询状态
+            s1PLCData.Add("a1MES_FLAG_VehicleStates", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_VehicleStates", "");  // 产品SN(载具码)
+            s1PLCData.Add("a1PLC_FLAG_Check", 0);    // PLC_FLAG 上料进站校验
+            s1PLCData.Add("a1MES_FLAG_Check", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_Check", "");  // 产品SN(物料码)
+            s1PLCData.Add("a1PLC_FLAG", 0);      // PLC_FLAG 出站接口
+            s1PLCData.Add("a1MES_FLAG", 0);      // MES_FLAG
+            s1PLCData.Add("a1ProductSN", "");    // 产品SN(载具SN)
+            s1PLCData.Add("a1PartNo1", "");      // 物料码1(穴位1)
+            s1PLCData.Add("a1PartNo2", "");      // 物料码2(穴位2)
+            s1PLCData.Add("a1Result", 0);        // 产品结果
+            s1PLCData.Add("a1PLC_FLAG_ICT", 0);    // PLC_FLAG 将SN发给ICT标机(串口)
+            s1PLCData.Add("a1MES_FLAG_ICT", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_ICT", "");  // 产品SN(载具SN)
+            s1PLCData.Add("a1PartNo1_ICT", "");    // 物料码1(穴位1)
+            s1PLCData.Add("a1PartNo2_ICT", "");    // 物料码2(穴位2)
+            s1PLCData.Add("a1OEEPLC_FLAG", 0);      // PLC_FLAG 节拍接口
+            s1PLCData.Add("a1OEEMES_FLAG", 0);      // MES_FLAG
+            s1PLCData.Add("a1OEEPartNo", "");       // 物料码(物料码还未绑定载具SN时必填)
+            s1PLCData.Add("a1OEEVehicleCode", "");  // 载具SN
+            s1PLCData.Add("a1OEEPartNum", 0);       // 穴位号
+            s1PLCData.Add("a1OEEType", 0);          // 节拍类型(plc写入) 
+            s1PLCData.Add("a1AGVUpCall", 0);   // AGV上料叫agv信号 AGV上料
+            s1PLCData.Add("a1AGVUpStart", 0);  // AGV上料开始信号
+            s1PLCData.Add("a1AGVUpEnd", 0);    // AGV上料完成信号
+            s1PLCData.Add("a1AGVDownCall", 0);   // AGV下料叫agv信号 AGV下料
+            s1PLCData.Add("a1AGVDownStart", 0);  // AGV下料开始信号
+            s1PLCData.Add("a1AGVDownEnd", 0);    // AGV下料完成信号
+            #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+
+            while (true)
+            {
+                try
+                {
+                    if (!GlobalContext._IsCon_Funs1)
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);
+                        continue;
+                    }
+                    if (Funs[plcNo].IsConnected)  // 检查PLC是否已连接上
+                    {
+                        Stopwatch stopwatch1 = new Stopwatch();
+                        Stopwatch stopwatch2 = new Stopwatch();
+                        stopwatch1.Start();
+
+                        stopwatch2.Start();
+                        #region 一次性读取所有数据
+                        // 一次性读取所有数据
+                        result = Funs[plcNo].Read_SingleTag<OP40_MesData_t>(tagBaseName, 1, out stPLC_MesData);  //读取单个结构体数据
+                        if (result.Item1 != 0)
+                        {
+                            //richTextBox1.AppendText("\n" + strRet);
+                        }
+                        else
+                        {
+                            //richTextBox1.AppendText("\n" + "读取成功");
+                        }
+                        #endregion 一次性读取所有数据
+                        stopwatch2.Stop();
+
+                        #region 进站
+                        try
+                        {
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
+                            {
+                                ProgressState = false;
+                                Task.Run(() => S4进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, out ProgressState));
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            ProgressState = false;
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 进站
+
+                        #region 出站
+                        try
+                        {
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
+                            {
+                                ProgressState = false;
+                                Task.Run(() => S4出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 进站
+
+
+                        UpdatePLCMonitor(1, plcNo, 1);  // 更新PLC状态的UI  // 更新PLC状态的UI
+
+                        stopwatch1.Stop();
+                        OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
+                    }
+                    else
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                        AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
+
+                        Funs[plcNo].Connect();  // 重连
+                    }
+                }
+                catch (Exception ex)
+                {
+                    UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
+                }
+
+                Thread.Sleep(IntervalReadPLC);
+            }
+        }
+
+
+        /// <summary>
+        /// [S4] 点胶检测设备 - 进站
+        /// </summary>
+        /// <param name="plcNo">PLC编号</param>
+        /// <param name="stationNameStr">工站全称</param>
+        /// <param name="stPLC_MesData"></param>
+        /// <param name="tagMesCommName"></param>
+        private void S4进站(int plcNo, string stationNameStr, OP40_MesData_t stPLC_MesData, string tagMesCommName, out bool ProgressState)
+        {
+            int nRet = 0;
+            string strRet = "";
+            Stopwatch stopwatch1 = new Stopwatch();
+            Stopwatch stopwatch2 = new Stopwatch();
+            ProgressState = true;
+            try
+            {
+                stopwatch1.Start();
+                string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品SN(物料码)
+                string MachineId = GlobalContext.S4_MachineId;  // 装备ID(可配置)
+                string StationId = GlobalContext.S4_StationId;  // 工位ID(可配置)
+
+                // 产品SN(物料码)校验
+                List<TestItem> item = new List<TestItem>();
+                stopwatch2.Start();
+                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
+                stopwatch2.Stop();
+
+                //指令执行结果 1:OK   110:失败
+                byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
+
+                //进站结果写入PLC
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+            }
+            catch (Exception ex)
+            {
+                string str = ex.StackTrace;
+                AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+            }
+
+            stopwatch1.Stop();
+            AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
+        }
+
+
+        /// <summary>
+        /// [S4] 点胶检测设备 - 出站接口
+        /// </summary>
+        private void S4出站(int plcNo, string stationNameStr, OP40_MesData_t stPLC_MesData, string tagMesCommName, string stationCode, string stationName, out bool ProgressState)
+        {
+            ProgressState = true;
+            Stopwatch stopwatch1 = new Stopwatch();
+            Stopwatch stopwatch2 = new Stopwatch();
+
+
+            try
+            {
+                stopwatch1.Start();
+
+                string equipmentCode = GlobalContext.LineCode + "-" + stationCode;  // 设备编号
+                string processItem = stationName;  // 测试项目
+                string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
+                string supplierCode = "";     // 供应商代码
+                string workorder_code = GlobalContext.WorkOrderCode;  // 工单号
+                string batch_num = GlobalContext.BatchNumber;         // 批次号
+                string mtltmrk = GlobalContext.Mtltmrk;               // 产品型号
+                string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;
+                string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode;  // 载具条码;
+                string MachineId = GlobalContext.S4_MachineId;  // 装备id(可配置)  // ZS
+                string StationId = GlobalContext.S4_StationId;  // ⼯位ID(可配置)  // ZS
+                int a1Result = (int)stPLC_MesData.iotData.testStatus;          // 产品结果
+                bool pass = a1Result == 1;
+
+                List<TestItem> items = new List<TestItem>();
+                items.Add(new TestItem()
+                {
+                    Parameter_name = "载具码",
+                    Parameter_value = CarrierBarcode,
+                    Parameter_unit = ""
+                });
+                items.Add(new TestItem()
+                {
+                    Parameter_name = "产品码",
+                    Parameter_value = mtltmrk,
+                    Parameter_unit = ""
+                });
+
+                ResponseMessage responseMessage = InsertOp40Data("", stPLC_MesData.mesData.fGlue_Areas[0], stPLC_MesData.mesData.fGlue_Heights[0],"");
+                if (!responseMessage.result)
+                {
+                    AddMessage_Station(stationNameStr, LogType.Error, "OP40记录插入出错!");
+                }
+
+                //绑定PLC返回MES数据到本地
+
+                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
+
+                byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
+
+                stopwatch2.Start();
+                //进站结果写入PLC
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+                stopwatch2.Stop();
+
+                WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
+            }
+            catch (Exception ex)
+            {
+                stopwatch2.Start();
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+                stopwatch2.Stop();
+
+                string str = ex.StackTrace;
+                AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+            }
+
+            stopwatch1.Stop();
+            AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
+        }
+
+        /// <summary>
+        /// [S5] 点胶检测设备
+        /// </summary>
+        /// <param name="plcNo">PLC编号</param>
+        private void ReadStation_S5(int plcNo)
+        {
+            string stationCode = "[S5]";
+            string stationName = "点胶检测设备";
+            string stationNameStr = stationCode + stationName;
+            string tagBaseName = "g_OP50_MES";   //标签变量名称
+            string tagMesCommName = "mesCommToPC";   //标签变量名称
+            string tagAgvCommName = "agvCommFrmPC";
+            string tagBarsetName = "BarcodeSet";
+
+            OP50_MesData_t stPLC_MesData;        //PLC的MES数据
+            (int, string) result;
+            bool ProgressState = true;
+
+            #region 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            // 触发信号字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            s1PLCSignal_Old.Add("a1PLC_FLAG_VehicleStates", 0);  // PLC_FLAG 载具进站查询状态
+            s1PLCSignal_Old.Add("a1PLC_FLAG_Check", 0);          // PLC_FLAG 上料进站校验
+            s1PLCSignal_Old.Add("a1PLC_FLAG", 0);                // PLC_FLAG 出站接口
+            s1PLCSignal_Old.Add("a1PLC_FLAG_ICT", 0);            // PLC_FLAG 将SN发给ICT标机(串口)
+            s1PLCSignal_Old.Add("a1OEEPLC_FLAG", 0);             // PLC_FLAG 节拍接口
+            s1PLCSignal_Old.Add("a1AGVUpCall", 0);               // AGV上料叫agv信号 AGV上料
+            s1PLCSignal_Old.Add("a1AGVUpEnd", 0);                // AGV上料完成信号 AGV上料
+            s1PLCSignal_Old.Add("a1AGVDownCall", 0);             // AGV下料叫agv信号 AGV下料
+            s1PLCSignal_Old.Add("a1AGVDownEnd", 0);              // AGV下料完成信号 AGV下料
+
+            // PLC数据字典 赋值 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+            s1PLCData.Add("a1PLC_FLAG_VehicleStates", 0);    // PLC_FLAG 载具进站查询状态
+            s1PLCData.Add("a1MES_FLAG_VehicleStates", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_VehicleStates", "");  // 产品SN(载具码)
+            s1PLCData.Add("a1PLC_FLAG_Check", 0);    // PLC_FLAG 上料进站校验
+            s1PLCData.Add("a1MES_FLAG_Check", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_Check", "");  // 产品SN(物料码)
+            s1PLCData.Add("a1PLC_FLAG", 0);      // PLC_FLAG 出站接口
+            s1PLCData.Add("a1MES_FLAG", 0);      // MES_FLAG
+            s1PLCData.Add("a1ProductSN", "");    // 产品SN(载具SN)
+            s1PLCData.Add("a1PartNo1", "");      // 物料码1(穴位1)
+            s1PLCData.Add("a1PartNo2", "");      // 物料码2(穴位2)
+            s1PLCData.Add("a1Result", 0);        // 产品结果
+            s1PLCData.Add("a1PLC_FLAG_ICT", 0);    // PLC_FLAG 将SN发给ICT标机(串口)
+            s1PLCData.Add("a1MES_FLAG_ICT", 0);    // MES_FLAG
+            s1PLCData.Add("a1ProductSN_ICT", "");  // 产品SN(载具SN)
+            s1PLCData.Add("a1PartNo1_ICT", "");    // 物料码1(穴位1)
+            s1PLCData.Add("a1PartNo2_ICT", "");    // 物料码2(穴位2)
+            s1PLCData.Add("a1OEEPLC_FLAG", 0);      // PLC_FLAG 节拍接口
+            s1PLCData.Add("a1OEEMES_FLAG", 0);      // MES_FLAG
+            s1PLCData.Add("a1OEEPartNo", "");       // 物料码(物料码还未绑定载具SN时必填)
+            s1PLCData.Add("a1OEEVehicleCode", "");  // 载具SN
+            s1PLCData.Add("a1OEEPartNum", 0);       // 穴位号
+            s1PLCData.Add("a1OEEType", 0);          // 节拍类型(plc写入) 
+            s1PLCData.Add("a1AGVUpCall", 0);   // AGV上料叫agv信号 AGV上料
+            s1PLCData.Add("a1AGVUpStart", 0);  // AGV上料开始信号
+            s1PLCData.Add("a1AGVUpEnd", 0);    // AGV上料完成信号
+            s1PLCData.Add("a1AGVDownCall", 0);   // AGV下料叫agv信号 AGV下料
+            s1PLCData.Add("a1AGVDownStart", 0);  // AGV下料开始信号
+            s1PLCData.Add("a1AGVDownEnd", 0);    // AGV下料完成信号
+            #endregion 创建字典 - 赛米可以放在while中,add前查询下存不存在,存在就赋值不存在就add
+
+            while (true)
+            {
+                try
+                {
+                    if (!GlobalContext._IsCon_Funs1)
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);
+                        continue;
+                    }
+                    if (Funs[plcNo].IsConnected)  // 检查PLC是否已连接上
+                    {
+                        Stopwatch stopwatch1 = new Stopwatch();
+                        Stopwatch stopwatch2 = new Stopwatch();
+                        stopwatch1.Start();
+
+                        stopwatch2.Start();
+                        #region 一次性读取所有数据
+                        // 一次性读取所有数据
+                        result = Funs[plcNo].Read_SingleTag<OP50_MesData_t>(tagBaseName, 1, out stPLC_MesData);  //读取单个结构体数据
+                        if (result.Item1 != 0)
+                        {
+                            //richTextBox1.AppendText("\n" + strRet);
+                        }
+                        else
+                        {
+                            //richTextBox1.AppendText("\n" + "读取成功");
+                        }
+                        #endregion 一次性读取所有数据
+                        stopwatch2.Stop();
+
+                        #region 进站
+                        try
+                        {
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.InStation && ProgressState == true)
+                            {
+                                ProgressState = false;
+                                Task.Run(() => S5进站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, out ProgressState));
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            ProgressState = false;
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 进站
+
+                        #region 出站
+                        try
+                        {
+                            if (stPLC_MesData.mesCommFrmPLC.cmd == (byte)eMesCmd.OutStation && ProgressState == true)
+                            {
+                                ProgressState = false;
+                                Task.Run(() => S5出站(plcNo, stationNameStr, stPLC_MesData, tagBaseName + "." + tagMesCommName, stationCode, stationName, out ProgressState));
+                            }
+                        }
+                        catch (Exception ex)
+                        {
+                            string str = ex.StackTrace;
+                            AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+                        }
+                        #endregion 进站
+
+
+                        UpdatePLCMonitor(1, plcNo, 1);  // 更新PLC状态的UI  // 更新PLC状态的UI
+
+                        stopwatch1.Stop();
+                        OnMessage(LogType.Info, $"循环读取PLC数据一次,总用时{stopwatch1.ElapsedMilliseconds}ms[读取用时{stopwatch2.ElapsedMilliseconds}ms]");
+                    }
+                    else
+                    {
+                        UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                        AddMessage_Station(stationNameStr, LogType.Info, "PLC" + plcNo.ToString() + "_" + stationNameStr + "连接失败!");
+
+                        Funs[plcNo].Connect();  // 重连
+                    }
+                }
+                catch (Exception ex)
+                {
+                    UpdatePLCMonitor(1, plcNo, 0);  // 更新PLC状态的UI
+                    AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr}运行出错!错误信息:" + ex.Message.ToString());
+                }
+
+                Thread.Sleep(IntervalReadPLC);
+            }
+        }
+
+
+        /// <summary>
+        /// [S5] 点胶检测设备 - 进站
+        /// </summary>
+        /// <param name="plcNo">PLC编号</param>
+        /// <param name="stationNameStr">工站全称</param>
+        /// <param name="stPLC_MesData"></param>
+        /// <param name="tagMesCommName"></param>
+        private void S5进站(int plcNo, string stationNameStr, OP50_MesData_t stPLC_MesData, string tagMesCommName, out bool ProgressState)
+        {
+            int nRet = 0;
+            string strRet = "";
+            Stopwatch stopwatch1 = new Stopwatch();
+            Stopwatch stopwatch2 = new Stopwatch();
+            ProgressState = true;
+            try
+            {
+                stopwatch1.Start();
+                string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品SN(物料码)
+                string MachineId = GlobalContext.S5_MachineId;  // 装备ID(可配置)
+                string StationId = GlobalContext.S5_StationId;  // 工位ID(可配置)
+
+                // 产品SN(物料码)校验
+                List<TestItem> item = new List<TestItem>();
+                stopwatch2.Start();
+                int result = SaveStationInData(stationNameStr, GlobalContext.WorkOrderCode, GlobalContext.Mtltmrk, sn, item, MachineId, StationId);
+                stopwatch2.Stop();
+
+                //指令执行结果 1:OK   110:失败
+                byte mesResultFrmWeb = (byte)(result == 1 ? 1 : 110);
+
+                //进站结果写入PLC
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+            }
+            catch (Exception ex)
+            {
+                string str = ex.StackTrace;
+                AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_{stationNameStr} 上料进站校验出错!错误信息:" + ex.Message + "异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+            }
+
+            stopwatch1.Stop();
+            AddMessage(LogType.Info, stationNameStr + "_进站;总用时" + stopwatch1.ElapsedMilliseconds + "ms;调用MES用时" + stopwatch2.ElapsedMilliseconds + "ms");
+        }
+
+
+        /// <summary>
+        /// [S5] 点胶检测设备 - 出站接口
+        /// </summary>
+        private void S5出站(int plcNo, string stationNameStr, OP50_MesData_t stPLC_MesData, string tagMesCommName, string stationCode, string stationName, out bool ProgressState)
+        {
+            ProgressState = true;
+            Stopwatch stopwatch1 = new Stopwatch();
+            Stopwatch stopwatch2 = new Stopwatch();
+
+
+            try
+            {
+                stopwatch1.Start();
+
+                string equipmentCode = GlobalContext.LineCode + "-" + stationCode;  // 设备编号
+                string processItem = stationName;  // 测试项目
+                string plcDate_YMD = DateTime.Now.ToString("yyyyMMdd");
+                string supplierCode = "";     // 供应商代码
+                string workorder_code = GlobalContext.WorkOrderCode;  // 工单号
+                string batch_num = GlobalContext.BatchNumber;         // 批次号
+                string mtltmrk = GlobalContext.Mtltmrk;               // 产品型号
+                string sn = (string)stPLC_MesData.BarcodeSet.strProductBarcode;  // 产品条码;
+                string CarrierBarcode = (string)stPLC_MesData.BarcodeSet.strCarrierBarcode;  // 载具条码;
+                string MachineId = GlobalContext.S5_MachineId;  // 装备id(可配置)  // ZS
+                string StationId = GlobalContext.S5_StationId;  // ⼯位ID(可配置)  // ZS
+                int a1Result = (int)stPLC_MesData.iotData.testStatus;          // 产品结果
+                bool pass = a1Result == 1;
+
+                List<TestItem> items = new List<TestItem>();
+                items.Add(new TestItem()
+                {
+                    Parameter_name = "载具码",
+                    Parameter_value = CarrierBarcode,
+                    Parameter_unit = ""
+                });
+                items.Add(new TestItem()
+                {
+                    Parameter_name = "产品码",
+                    Parameter_value = mtltmrk,
+                    Parameter_unit = ""
+                });
+
+                ResponseMessage responseMessage = InsertOp50Data(CarrierBarcode,sn, stPLC_MesData.BarcodeSet.strPartBarcode, stPLC_MesData.mesData.nIsAddPCBAsmOK,"", stPLC_MesData.mesData.nHaveAddPCB,stPLC_MesData.mesData.fForceAddPCB);
+                if (!responseMessage.result)
+                {
+                    AddMessage_Station(stationNameStr, LogType.Error, "OP50记录插入出错!");
+                }
+
+                //绑定PLC返回MES数据到本地
+
+                int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem
+    , workorder_code, batch_num, mtltmrk, plcDate_YMD, supplierCode, sn, pass, CarrierBarcode, "1", MachineId, StationId);
+
+                byte mesResultFrmWeb = (byte)(result1 == 1 ? 1 : 110);
+
+                stopwatch2.Start();
+                //进站结果写入PLC
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = mesResultFrmWeb;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+                stopwatch2.Stop();
+
+                WritePLCLog(LogType.Debug, $"PLC{plcNo}_[{stationNameStr}]-Write" + (result1 == 1 ? "成功!" : "失败!"));
+            }
+            catch (Exception ex)
+            {
+                stopwatch2.Start();
+                CommandFromPLC resultToPlC = new CommandFromPLC();
+                resultToPlC.cmd = 0;
+                resultToPlC.cmdParam = 0; //指令参数
+                resultToPlC.cmdResult = 110;
+                WriteResultToPlc(plcNo, stationNameStr, tagMesCommName, 1, resultToPlC);
+                stopwatch2.Stop();
+
+                string str = ex.StackTrace;
+                AddMessage_Station(stationNameStr, LogType.Error, $"PLC{plcNo}_[{stationNameStr}]上传加工报错!错误信息:" + ex.Message.ToString() + ";异常位置:" + str.Substring(str.LastIndexOf("\\") + 1, str.Length - str.LastIndexOf("\\") - 1));
+            }
+
+            stopwatch1.Stop();
+            AddMessage(LogType.Info, stationNameStr + "_出站接口;总用时" + stopwatch1.ElapsedMilliseconds + "ms;写入用时" + stopwatch2.ElapsedMilliseconds + "ms");
+        }
+
+
         #region PLC4 刘果段
         #region [S4] 取放桁架
         /// <summary>
@@ -5172,12 +5751,10 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                //绑定载具和产品
-                ResponseMessage message = new ResponseMessage();
-                message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
-                if (message.result == false)
+                ResponseMessage responseMessage = InsertOp60Data(CarrierBarcode, sn, stPLC_MesData.mesData.nIsTopCoverAsmOK, "", stPLC_MesData.mesData.nHaveTopCover, stPLC_MesData.mesData.fForceTopCover);
+                if (!responseMessage.result)
                 {
-                    AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
+                    AddMessage_Station(stationNameStr,LogType.Error, "OP60记录插入出错!");                
                 }
 
                 //绑定PLC返回MES数据到本地
@@ -5464,13 +6041,7 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                //绑定载具和产品
-                ResponseMessage message = new ResponseMessage();
-                message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
-                if (message.result == false)
-                {
-                    AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
-                }
+
 
                 //绑定PLC返回MES数据到本地
 
@@ -5756,14 +6327,6 @@ namespace MainForm
                     Parameter_unit = ""
                 });
 
-                //绑定载具和产品
-                ResponseMessage message = new ResponseMessage();
-                message = SQLHelper.InsertCarrierBind(CarrierBarcode, CarrierBarcode, stationNameStr);
-                if (message.result == false)
-                {
-                    AddMessage(LogType.Info, stationNameStr + "_载具码与产品码绑定失败");
-                }
-
                 //绑定PLC返回MES数据到本地
 
                 int result1 = SwitctProcessData(stationNameStr, items, equipmentCode, processItem