using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using AR; namespace Project { public partial class FMain { //System.Threading.ManualResetEvent LockLL = new System.Threading.ManualResetEvent(true); //System.Threading.ManualResetEvent LockLR = new System.Threading.ManualResetEvent(true); System.Threading.ManualResetEvent LockPK = new System.Threading.ManualResetEvent(true); System.Threading.ManualResetEvent LockUserL = new System.Threading.ManualResetEvent(true); System.Threading.ManualResetEvent LockUserR = new System.Threading.ManualResetEvent(true); async public void _STEP_RUN_START(eSMStep step) { //새로시작하면 포트 얼라인을 해제 해준다 PUB.flag.set(eVarBool.FG_RDY_PORT_PL, false, "SM_RUN"); PUB.flag.set(eVarBool.FG_RDY_PORT_PC, false, "SM_RUN"); PUB.flag.set(eVarBool.FG_RDY_PORT_PR, false, "SM_RUN"); //작업완료기준시간 초기화 if (PUB.flag.get(eVarBool.FG_JOB_END) == true) VAR.TIME.Update(eVarTime.JOB_END); //라이브뷰시간 초기화 VAR.TIME.Update(eVarTime.LIVEVIEW0); VAR.TIME.Update(eVarTime.LIVEVIEW1); VAR.TIME.Update(eVarTime.LIVEVIEW2); //룸조명과, 타워램프 ON 한다 - 210402 //COMM.SETTING.Data.Disable_RoomLight = false; //COMM.SETTING.Data.Disable_TowerLamp = false; //얼라인상태 초기화 hmi1.arVar_Port[1].AlignReset(); hmi1.Scean = UIControl.HMI.eScean.Nomal; //loader1.arVar_Port.ToList().ForEach(t => t.AlignReset()); //daycount 초기화 if (SETTING.Counter.DateStr != DateTime.Now.ToString("yyyy-MM-dd")) { SETTING.Counter.ClearDay(); SETTING.Counter.DateStr = DateTime.Now.ToString("yyyy-MM-dd"); SETTING.Counter.Save(); } //키엔스 시작시간을 초기화한다. VAR.TIME.Update(eVarTime.KEYENCEWAIT); //조명켜기 - 201228 DIO.SetRoomLight(true); //조명은 켜는 것으로 한다 221107 //각스텝의 시작변수 초기화한다. PUB.sm.seq.ClearTime();//.ClearRunStepSeqTime(); //대기메세지소거 PUB.WaitMessage = new string[] { "", "", "", "", "", "", "", "", "", "", "" }; if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) && PUB.flag.get(eVarBool.FG_END_VISIONL) == false) { //작업을 재시작하면 카메라 트리거를 다시 보낸다 WS_Send(eWorkPort.Left, PUB.wsL, PUB.Result.ItemDataL.guid, "TRIG", PUB.Result.ItemDataL.VisionData.PrintQRData); } if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) && PUB.flag.get(eVarBool.FG_END_VISIONR) == false) { //Pub.Result.ItemData[2].Clear("[0] RUN FIRST"); WS_Send(eWorkPort.Right, PUB.wsR, PUB.Result.ItemDataR.guid, "TRIG", PUB.Result.ItemDataR.VisionData.PrintQRData); } //재시작할때에는 이것이 동작하면 안됨 if (PUB.sm.getOldStep == eSMStep.IDLE) { //인쇄용지감지상태 초기화 PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTL, false, ""); PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTR, false, ""); PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, ""); PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, ""); PUB.flag.set(eVarBool.FG_END_VISIONL, false, ""); PUB.flag.set(eVarBool.FG_END_VISIONR, false, ""); PUB.flag.set(eVarBool.FG_OK_PRINTL, false, ""); PUB.flag.set(eVarBool.FG_OK_PRINTR, false, ""); PUB.flag.set(eVarBool.FG_RUN_PRINTL, false, ""); PUB.flag.set(eVarBool.FG_RUN_PRINTR, false, ""); PUB.flag.set(eVarBool.FG_RDY_PX_PICKON, false, ""); PUB.flag.set(eVarBool.FG_RDY_PX_LPICKOF, false, ""); PUB.flag.set(eVarBool.FG_RDY_PX_RPICKOF, false, ""); PUB.flag.set(eVarBool.FG_SET_DATA_PORT0, false, ""); PUB.flag.set(eVarBool.FG_SET_DATA_PORT2, false, ""); PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITL, false, ""); PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITR, false, ""); PUB.flag.set(eVarBool.FG_PORTL_ITEMON, false, ""); PUB.flag.set(eVarBool.FG_PORTR_ITEMON, false, ""); //PUB.flag.set(eVarBool.INPUT_LEFT, false, "SM_RUN"); //step seq 를 모두 소거해준다 PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY); //자료를 소거한다. //PUB.Result.Clear("RUN_START"); //PUB.Result.JobStartTime = DateTime.Now; //200728 //신규실행이므로 작업차수별 수량을 초기화해준다 SETTING.Counter.ClearP(); //200711 PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN"); PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_L); PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_R); if (await _SM_RUN_STARTCHKSW(true, new TimeSpan(0)) == false) return; if (_SM_RUN_STARTCHKHW(true, new TimeSpan(0)) == false) return; //plc의 SID 데이터를 갱신하도록 한다 PUB.Result.ClearAllSID = true; PUB.log.AddI("*** New job has started ***"); //PUB.flag.set(eVarBool.RDY_VISION1, true, "JOB START"); //최초 시작시에는 1번 비젼이 동작하게 한다 //새로시작할때에는 이 값을 초기화 해준다. PUB.Result.LastSIDFrom = string.Empty; PUB.Result.LastSIDTo = string.Empty; //Pub.Result.LastSID103_2 = string.Empty; PUB.Result.LastSIDCnt = -1; PUB.Result.LastVName = string.Empty; //릴아디이 221107 VAR.STR[eVarString.PrePick_ReelIDNew] = string.Empty; VAR.STR[eVarString.PrePick_ReelIDOld] = string.Empty; VAR.STR[eVarString.PrePick_ReelIDTarget] = string.Empty; } else { if (VAR.BOOL[eVarBool.wait_for_keyence]) { PUB.log.Add($"Deleting existing values because barcode reception was waiting (CONF={PUB.Result.ItemDataC.VisionData.Confirm}, ID:{PUB.Result.ItemDataC.VisionData.RID})"); PUB.Result.ItemDataC.VisionData.Clear("RESTART", true); } PUB.log.AddI("*** Job has been restarted ***"); } } public StepResult _STEP_RUN(eSMStep step, TimeSpan stepTime, TimeSpan seqTime) { if (PUB.popup.needClose) { System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다. return StepResult.Wait; } //사용자 스텝처리가 아닌경우에만 동작 중지를 검사 한다 //중단조건 검사는 0번 축에만 동작하게 한다 //if (PUB.flag.get(eVarBool.UserStepCheck) == false) //{ // return false; //} if (CheckSystemRunCondition() == false) { return StepResult.Wait; } //동작상태가 아니라면 처리하지 않는다. if (PUB.sm.Step == eSMStep.RUN && PUB.sm.getNewStep == eSMStep.RUN) { var RStepisFirst = runStepisFirst[0]; //릴포트 제어 _SM_RUN_MOT_PORT(0, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT0)); _SM_RUN_MOT_PORT(1, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT1)); _SM_RUN_MOT_PORT(2, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT2)); //컨베어 상시동작 - 230503 Boolean cvl = PUB.iLockCVL.IsEmpty(); Boolean cvr = PUB.iLockCVR.IsEmpty(); DIO.SetOutput(eDOName.LEFT_CONV, cvl); DIO.SetOutput(eDOName.RIGHT_CONV, cvr); //왼쪽작업 if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT)) { _RUN_ROOT_SEQUENCE(eWorkPort.Left, eSMStep.RUN_ROOT_SEQUENCE_L); } //오른쪽작업 if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT)) { _RUN_ROOT_SEQUENCE(eWorkPort.Right, eSMStep.RUN_ROOT_SEQUENCE_R); } //작업완료조건확인 var PLReady = MOT.GetLMPos(eLMLoc.READY); var PRReady = MOT.GetRMPos(eRMLoc.READY); //최종이벤트시간에서 10초이상 기다려준다 230504 var tsEventTime = VAR.TIME.RUN((int)eVarTime.JOBEVENT); //컨베이어모드 var CVMode = VAR.BOOL[eVarBool.Use_Conveyor]; if (tsEventTime.TotalSeconds > 10 && stepTime.TotalSeconds > 5.0 && DIO.isSaftyDoorF(false) == true && PUB.flag.get(eVarBool.FG_PK_ITEMON) == false && PUB.flag.get(eVarBool.FG_PL_ITEMON) == false && PUB.flag.get(eVarBool.FG_PR_ITEMON) == false && //신규로 추가된 컨베이어 센서이다 (CVMode == false || DIO.GetIOInput(eDIName.L_CONV1) == false) && // (CVMode == false || DIO.GetIOInput(eDIName.L_CONV3) == false) && (CVMode == false || DIO.GetIOInput(eDIName.L_CONV4) == false) && (CVMode == false || DIO.GetIOInput(eDIName.R_CONV1) == false) && // (CVMode == false || DIO.GetIOInput(eDIName.R_CONV3) == false) && (CVMode == false || DIO.GetIOInput(eDIName.R_CONV4) == false) && //작업진행중 확인 PUB.flag.get(eVarBool.FG_BUSY_LEFT) == false && PUB.flag.get(eVarBool.FG_BUSY_RIGHT) == false && //비전처리중 확인 //PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false && //PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false && //모든 모터는 멈춰있어야 한다 PUB.mot.HasMoving == false && //피커는 중앙에 있어야 한다 //좌,우측 프린터 Y축이 정위치에 있어야 한다 MOT.getPositionMatch(PLReady) && MOT.getPositionMatch(PRReady) && isPortDetUp(1) == false && isPortLimUP(1) && //드라이런 중에는 완료하지 않는다 PUB.Result.DryRun == false) { if (PUB.flag.get(eVarBool.FG_JOB_END) == false) { PUB.log.AddAT("Work completion condition execution"); VAR.TIME.Update(eVarTime.JOB_END); PUB.flag.set(eVarBool.FG_JOB_END, true, "SM_RUN"); } else { //10초가 지나면 최조 완료로 한다 var ts = VAR.TIME.RUN((int)eVarTime.JOB_END); if (ts.TotalSeconds >= AR.SETTING.Data.Timeout_JOBEnd) { PUB.Result.JobEndTime = DateTime.Now; PUB.log.AddI($"Switching to job completion state (wait time: {AR.SETTING.Data.Timeout_JOBEnd} seconds)"); PUB.sm.SetNewStep(eSMStep.FINISH); PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN:FINISH"); } } } else { //이조건일때에는 job_End 가 없어야한다 if (PUB.flag.get(eVarBool.FG_JOB_END) == true) { PUB.log.AddI("Work completion condition released"); PUB.flag.set(eVarBool.FG_JOB_END, false, "run"); //메인메세지를 제거 해준다. PUB.StatusMessage.set(Class.eStatusMesage.Main, string.Empty); } } } return StepResult.Wait; } public Boolean CheckSystemRunCondition() { if (PUB.mot.IsInit == false) { PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR); return false; } if (PUB.dio.IsInit == false) { PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR); return false; } if (PUB.mot.HasHomeSetOff == true) { PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.MOT_HSET, eNextStep.ERROR); return false; } if (PUB.Result.vModel == null || PUB.Result.vModel.Title.isEmpty()) { PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELV, eNextStep.ERROR); return false; } if (PUB.Result.mModel == null || PUB.Result.mModel.Title.isEmpty()) { PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR); return false; } if (DIO.isSaftyDoorF() == false || DIO.isSaftyDoorR() == false) { PUB.Result.SetResultMessage(eResult.OPERATION, eECode.DOORSAFTY, eNextStep.PAUSE); return false; } return true; } } }