using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using System.Security.Cryptography; using System.Text; using AR; using Chilkat; namespace Project { public partial class FMain { public Boolean _RUN_ROOT_SEQUENCE(eWorkPort target, eSMStep cmdIndex) { UInt16 idx = 1; var mv = PUB.Result.vModel; var mc = PUB.Result.mModel; var funcName = System.Reflection.MethodBase.GetCurrentMethod().Name; var seqTime = PUB.sm.seq.GetTime(cmdIndex); var msgType = (Class.eStatusMesage)target; var item = target == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR; //var Jobtype = VAR.STR[eVarString.JOB_TYPE]; var CVMode = VAR.BOOL[eVarBool.Use_Conveyor]; //option check var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target); var OPT_CameraOff = PUB.OPT_CAMERA(); var OPT_BYPASS = PUB.OPT_BYPASS(); //#################################################### //### 작업시작 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { PUB.StatusMessage.set(msgType, $"[{target}] 작업을 시작 합니다"); //프린터용 백큠이 켜져있다면 오류로 한다. if (target == eWorkPort.Left) { if (DIO.GetIOOutput(eDOName.PRINTL_AIRON)) { PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NEED_AIROFF_L, eNextStep.PAUSE); return false; } } else { if (DIO.GetIOOutput(eDOName.PRINTR_AIRON)) { PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NEED_AIROFF_R, eNextStep.PAUSE); return false; } } //Keyence_Trigger(true); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터(Y,Z) 안전위치로 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { sPositionData PosY, PosZ; if (target == eWorkPort.Left) { PosY = MOT.GetLMPos(eLMLoc.READY); PosZ = MOT.GetLZPos(eLZLoc.READY); } else { PosY = MOT.GetRMPos(eRMLoc.READY); PosZ = MOT.GetRZPos(eRZLoc.READY); } //Y축이 준비위가 아닌경우에만 이 처리를 한다. if (MOT.getPositionMatch(PosY) == false) { if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false; if (MOT.CheckMotionPos(seqTime, PosY, funcName) == false) return false; } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 로더에 릴이 감지되어있어야 다음 작업을 진행할 수 있음 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { //Check Port Ready if (PUB.flag.get(eVarBool.FG_RDY_PORT_PC) == false && DIO.GetIOInput(eDIName.PORTC_DET_UP) == false) return false; //Check Reel Detect Sensor if (DIO.GetIOInput(eDIName.PORTC_DET_UP) == false) return false; //check Reel Limit Sensor if (DIO.GetIOInput(eDIName.PORTC_LIM_UP) == true) return false; if (CVMode) { if (target == eWorkPort.Left) { if (DIO.GetIOInput(eDIName.L_CONV1)) return false; //혹은 컨베이어 가동시간이 5초전이라면 넘어간다 230926 if (VAR.I32[eVarInt32.LEFT_ITEM_COUNT] > 0) { if (seqTime.TotalSeconds > 5) { //if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_L) && PUB.flag.get(eVarBool.VS_DETECT_REEL_L) == false) //{ // //비젼에서 없다고 보고 되어있다면 그대로 진행한다.. // PUB.log.AddAT($"(L)비전에서 자재가 감지되지 않아 강제 진행 합니다"); // VAR.I32[eVarInt32.LEFT_ITEM_COUNT] = 0; //} if (VAR.DBL[eVarDBL.CONVL_RUNTIME] > 15) { PUB.log.AddE($"(L) Buffer cleared due to conveyor exceeding 15 seconds"); VAR.I32[eVarInt32.LEFT_ITEM_COUNT] = 0; } else return false; } else return false; } } else { if (DIO.GetIOInput(eDIName.R_CONV1)) return false; //혹은 컨베이어 가동시간이 5초전이라면 넘어간다 230926 if (VAR.I32[eVarInt32.RIGT_ITEM_COUNT] > 0) { if (seqTime.TotalSeconds > 5) { //if (PUB.flag.get(eVarBool.FG_RDY_CAMERA_R) && PUB.flag.get(eVarBool.VS_DETECT_REEL_R) == false) //{ // //비젼에서 없다고 보고 되어있다면 그대로 진행한다.. // PUB.log.AddAT($"(r)비전에서 자재가 감지되지 않아 강제 진행 합니다"); // VAR.I32[eVarInt32.RIGT_ITEM_COUNT] = 0; //} if (VAR.DBL[eVarDBL.CONVR_RUNTIME] > 15) { PUB.log.AddE($"(R) Buffer cleared due to conveyor exceeding 15 seconds"); VAR.I32[eVarInt32.RIGT_ITEM_COUNT] = 0; } else return false; } else return false; } } //PUB.log.Add($"CVMODE에서 컨베이어 비어있음(SEQ)"); } VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now; PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 피커 사용확인 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { PUB.StatusMessage.set(msgType, $"[{target}] 피커(X) 사용 권한 확인"); if (LockPK.WaitOne(1) == false) return false; LockPK.Reset(); hmi1.AddLockItem((int)target, "PICKER"); PUB.mot.ClearPosition((int)eAxis.Z_THETA); if (target == eWorkPort.Left) { //카트가 없으면 동작하지 않게한다. PUB.flag.set(eVarBool.FG_RUN_RIGHT, false, funcName); PUB.flag.set(eVarBool.FG_RUN_LEFT, true, funcName); } else { PUB.flag.set(eVarBool.FG_RUN_LEFT, false, funcName); PUB.flag.set(eVarBool.FG_RUN_RIGHT, true, funcName); } PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY); PUB.Result.ItemDataC.VisionData.STime = DateTime.Now; PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 피커 리딩위치 이동 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { var PickerRetryCount = AR.VAR.I32[AR.eVarInt32.PickOnRetry]; //PUB.StatusMessage.set(msgType, $"[{target}] 피커(X) 읽기위치 이동"); //비젼이 읽혀지지 않다면 안전위치로 이동시킨다. //PUB.log.AddAT("비젼이 읽히지 않은 경우에만 리딩위치로 이동시켜준다"); //완료되지않았다면 비켜준다 220920 if (PUB.Result.ItemDataC.VisionData.Confirm == false) { if (PickerRetryCount == 0) //처음작업이다 { sPositionData Pos; if (target == eWorkPort.Left) { //우측을 사용하지 않으면 좌측으로 이동한다 if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT) == false) Pos = MOT.GetPXPos(ePXLoc.READYR); else Pos = MOT.GetPXPos(ePXLoc.READYL); } else { //우측이나 좌측을 사용하지 않으면 좌측으로 이동한다 if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT) == false) Pos = MOT.GetPXPos(ePXLoc.READYL); else Pos = MOT.GetPXPos(ePXLoc.READYR); } if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false; PUB.log.AddAT($"###### Initial work avoidance movement completed ({target})"); } else { //재시도 작업이므로 잡아서 79도 돌리는 작업 한다 if (PICKER_RETRY(target, eSMStep.RUN_PICK_RETRY) == false) return false; PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY); } } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 픽온작업용 시퀀스값 초기화 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { VAR.BOOL[eVarBool.wait_for_keyence] = true; if (target == eWorkPort.Left) { PUB.sm.seq.Clear(eSMStep.RUN_KEYENCE_READ_L); PUB.Result.ItemDataL.Clear(funcName); VAR.BOOL[eVarBool.wait_for_keyenceR] = false; VAR.BOOL[eVarBool.wait_for_keyenceL] = true; } else { PUB.sm.seq.Clear(eSMStep.RUN_KEYENCE_READ_R); PUB.Result.ItemDataR.Clear(funcName); VAR.BOOL[eVarBool.wait_for_keyenceL] = false; VAR.BOOL[eVarBool.wait_for_keyenceR] = true; } //키엔스데이터 기다리는중 VAR.BOOL[eVarBool.FG_WAIT_INFOSELECTCLOSE] = false; PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 키엔스바코드 확인 작업 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { EResultKeyence Complete = EResultKeyence.Wait; if (target == eWorkPort.Left) Complete = KEYENCE_READ(target, eSMStep.RUN_KEYENCE_READ_L); else Complete = KEYENCE_READ(target, eSMStep.RUN_KEYENCE_READ_R); if (Complete == EResultKeyence.Wait) { //읽을수있도록 좌표를 이동시켜준다 sPositionData Pos; if (target == eWorkPort.Left) { //우측을 사용하지 않으면 좌측으로 이동한다 if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT) == false) Pos = MOT.GetPXPos(ePXLoc.READYR); else Pos = MOT.GetPXPos(ePXLoc.READYL); } else { //우측이나 좌측을 사용하지 않으면 좌측으로 이동한다 if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT) == false) Pos = MOT.GetPXPos(ePXLoc.READYL); else Pos = MOT.GetPXPos(ePXLoc.READYR); } //sPositionData Pos = target == eWorkPort.Left ? MOT.GetPXPos(ePXLoc.READYL) : MOT.GetPXPos(ePXLoc.READYR); if (MOT.getPositionMatch(Pos) == false) { PUB.log.AddAT($"######Avoidance movement II due to no vision data({target})"); MOT.Move(Pos); } return false; } else if (Complete == EResultKeyence.MultiSID) { //이미 사용자 확인창 if (PUB.flag.get(eVarBool.FG_WAIT_INFOSELECT)) { //아무것도 하지 않는다 //사용자가 정보를 설정하는 중 } else { //사용자사 해당 창을 닫았다. if (VAR.BOOL[eVarBool.FG_WAIT_INFOSELECTCLOSE] == true & PUB.Result.ItemDataC.VisionData.SID.isEmpty()) { //사용자가 창을 닫았고 SID값이 없다면 오류 처리한다. PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOTSELECTMULTISID, eNextStep.PAUSE); VAR.BOOL[eVarBool.FG_WAIT_INFOSELECTCLOSE] = false; } else { bool SHowUserFormINF = true; //사용자 확인창을 표시한다 if (SHowUserFormINF) //다중SID정보 선택건 { this.Invoke(new Action(() => { PUB.log.Add("Calling user selection window (INF)"); var f = new Dialog.fSelectSIDInformation(); f.Show(); })); } } } return false; } else if (Complete == EResultKeyence.TimeOut) { //이미 사용자 확인창 if (PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO)) { //아무것도 하지 않는다 //사용자가 정보를 설정하는 중 } else { //반복시도횟수가 설정되지 않았거나 최대를 초과하면 사용자 확인창을 띄운다 bool ShowUserFormBCD = false; if (AR.SETTING.Data.RetryPickOnMaxCount == 0) { PUB.log.Add($"Showing user confirmation window due to no pick-on retry count"); ShowUserFormBCD = true; } else if (AR.VAR.I32[AR.eVarInt32.PickOnRetry] >= AR.SETTING.Data.RetryPickOnMaxCount) { PUB.log.Add($"Pick-on retry count exceeded (Max: {AR.SETTING.Data.RetryPickOnMaxCount})"); ShowUserFormBCD = true; } else { if (VAR.BOOL[eVarBool.Need_UserConfirm_Data]) { PUB.log.Add($"Need to show user confirmation window"); ShowUserFormBCD = true; } else { //읽은데이터가 atkstandard라면 바로 팝업을 띄운다 if (PUB.Result.ItemDataC.VisionData.SID.isEmpty() || PUB.Result.ItemDataC.VisionData.SID_Trust == false) { PUB.log.Add($"Retrying pick-on ({AR.VAR.I32[AR.eVarInt32.PickOnRetry]}/{AR.SETTING.Data.RetryPickOnMaxCount})"); ShowUserFormBCD = false; } else { PUB.log.Add($"SID value exists, showing user confirmation window instead of retrying"); ShowUserFormBCD = true; } } } if (ShowUserFormBCD) { this.Invoke(new Action(() => { var itemC = PUB.Result.ItemDataC; PUB.log.Add("Calling user confirmation window"); var f = new Dialog.fLoaderInfo(itemC.VisionData.bcdMessage); f.Show(); })); } else { //픽온재시도 PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY); VAR.I32[eVarInt32.PickOnRetry] += 1;//, 1); VAR.BOOL[eVarBool.JOB_PickON_Retry] = true; PUB.log.Add($"Pick-on retry ({VAR.I32[eVarInt32.PickOnRetry]})"); PUB.sm.seq.Update(cmdIndex, -2); } } return false; } //키엔스대기상태를 설정해준다 VAR.BOOL[eVarBool.wait_for_keyence] = false; if (target == eWorkPort.Left) VAR.BOOL[eVarBool.wait_for_keyenceL] = false; else VAR.BOOL[eVarBool.wait_for_keyenceR] = false; PUB.Result.ItemDataC.VisionData.ReelSize = DIO.getCartSize(1); PUB.log.AddI($"[{target}] Keyence verification completed (Size: {PUB.Result.ItemDataC.VisionData.ReelSize})"); PUB.log.AddI($"[{target}] Print Position:{PUB.Result.ItemDataC.VisionData.PrintPositionData}"); //픽온작업용 시퀀스값 초기화 if (target == eWorkPort.Left) { //프린트Z축을 픽온위치에둔다. var PosLM = MOT.GetLZPos(eLZLoc.PICKON); MOT.Move(PosLM); PUB.sm.seq.Clear(eSMStep.RUN_PICKER_ON_L); PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_F); PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_ON_F); //PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_OFF_F); PUB.Result.ItemDataC.CopyTo(ref PUB.Result.ItemDataL); PUB.log.Add($"[{target}] Vision data copy (C->L) ID:{PUB.Result.ItemDataL.VisionData.RID}"); } else { var PosRM = MOT.GetRZPos(eRZLoc.PICKON); MOT.Move(PosRM); PUB.sm.seq.Clear(eSMStep.RUN_PICKER_ON_R); PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_R); PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_ON_R); //PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_OFF_R); PUB.Result.ItemDataC.CopyTo(ref PUB.Result.ItemDataR); PUB.log.Add($"[{target}] Vision data copy (C->R) ID:{PUB.Result.ItemDataR.VisionData.RID}"); } //트리거 OFF System.Threading.Tasks.Task.Run(() => { if (PUB.keyenceF != null) PUB.keyenceF.Trigger(false); if (PUB.keyenceR != null) PUB.keyenceR.Trigger(false); }); PUB.log.Add($"[{target}] Print Pos={item.VisionData.PrintPositionData}"); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 릴아이디 사용 체크 221107 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { //만약 현재의 바코드가 이전바코드와 동일하다면 오류로 처리한다. var pre_ridN = VAR.STR[eVarString.PrePick_ReelIDNew].Trim(); var pre_ridO = VAR.STR[eVarString.PrePick_ReelIDOld].Trim(); var pre_targ = VAR.STR[eVarString.PrePick_ReelIDTarget].ToUpper().Trim(); var cur_ridN = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData.RID : PUB.Result.ItemDataR.VisionData.RID.Trim(); var cur_ridO = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData.RID0 : PUB.Result.ItemDataR.VisionData.RID0.Trim(); if (OPT_BYPASS) { PUB.log.Add($"Bypass mode - skipping previous reel ID check"); } else { if (pre_ridN.isEmpty() == false) //일단 무조건 신규아이디가 있어야한다 { //이전과 동일한 ID를 처리했다 오류, 스카이웍스는 본래의 ID를 사용하므로 이곳에서 걸린다 if (pre_ridN.Equals(cur_ridN)) { if (pre_targ == "LEFT") PUB.Result.SetResultMessage(eResult.OPERATION, eECode.PRE_USE_REELID_L, eNextStep.ERROR, target, pre_ridN, cur_ridN); else PUB.Result.SetResultMessage(eResult.OPERATION, eECode.PRE_USE_REELID_R, eNextStep.ERROR, target, pre_ridN, cur_ridN); } else { PUB.log.Add($"New ID usage check OK PRE={pre_ridN},NEW={cur_ridN}"); if (pre_ridO.isEmpty() == false && cur_ridO.isEmpty() == false) //구형아이디는 둘다 값이 있을때 처리한다. { if (pre_ridO.Equals(cur_ridO)) { if (pre_targ == "LEFT") PUB.Result.SetResultMessage(eResult.OPERATION, eECode.PRE_USE_REELID_L, eNextStep.ERROR, target, pre_ridO, cur_ridO); else PUB.Result.SetResultMessage(eResult.OPERATION, eECode.PRE_USE_REELID_R, eNextStep.ERROR, target, pre_ridO, cur_ridO); } else PUB.log.Add($"New ID usage check (ORG) OK PRE={pre_ridO},NEW={cur_ridO}"); } else { PUB.log.Add($"New ID usage check (ORG) SKIP (NO DATA) PRE={pre_ridO},NEW={cur_ridO}"); } } } else { PUB.log.Add($"First work - skipping previous reel ID check"); } VAR.STR[eVarString.PrePick_ReelIDNew] = cur_ridN; VAR.STR[eVarString.PrePick_ReelIDOld] = cur_ridO; VAR.STR[eVarString.PrePick_ReelIDTarget] = target.ToString(); PUB.log.Add($"Previous work reel ID set values N={cur_ridN},O={cur_ridO}"); } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### bypass check 230510 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { //컨베이어모드에서는 좌측 센서에 릴이 있다면 대기해야한다. 230829 if (CVMode) { if (target == eWorkPort.Left) { if (DIO.GetIOInput(eDIName.L_CONV1)) return false; //혹은 컨베이어 가동시간이 5초전이라면 넘어간다 230926 if (VAR.I32[eVarInt32.LEFT_ITEM_COUNT] > 0) return false; //{ // var cvrun = VAR.DBL[eVarDBL.LEFT_ITEM_PICKOFF]; // if (cvrun < 6) return false; //} } else { if (DIO.GetIOInput(eDIName.R_CONV1)) return false; //혹은 컨베이어 가동시간이 5초전이라면 넘어간다 230926 if (VAR.I32[eVarInt32.RIGT_ITEM_COUNT] > 0) return false; //{ // var cvrun = VAR.DBL[eVarDBL.RIGT_ITEM_PICKOFF]; // if (cvrun < 6) return false; //} } PUB.log.Add($"Conveyor empty in CV MODE (SEQ)"); } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### PICKER ON //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (target == eWorkPort.Left) { if (PRINTER(target, eSMStep.RUN_PRINTER_F)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_F); Complete = PICKER_ON(target, eSMStep.RUN_PICKER_ON_L); } else { if (PRINTER(target, eSMStep.RUN_PRINTER_R)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_R); Complete = PICKER_ON(target, eSMStep.RUN_PICKER_ON_R); } if (Complete == false) return false; //PUB.log.Add($"[{target}] 피커 ON 작업 완료"); VAR.I32.Clear((int)eVarInt32.PickOnRetry); //픽온작업용 시퀀스값 초기화 if (target == eWorkPort.Left) { PUB.sm.seq.Clear(eSMStep.RUN_PICKER_OFF_L); //PUB.Result.ItemData[1].CopyTo(ref PUB.Result.ItemData[0]); PUB.log.Add($"Barcode data copy (LEFT)"); PUB.flag.set(eVarBool.FG_BUSY_LEFT, true, funcName); //프린터용 AIR처리해준다. DIO.SetPrintLVac(ePrintVac.inhalation); DIO.SetPrintLAir(true); //PUB.Result.ItemData[1].UpdateTo(ref PUB.Result.ItemData[0]); } else { PUB.sm.seq.Clear(eSMStep.RUN_PICKER_OFF_R); //PUB.Result.ItemData[1].CopyTo(ref PUB.Result.ItemData[0]); PUB.log.Add($"Barcode data copy (RIGHT)"); PUB.flag.set(eVarBool.FG_BUSY_RIGHT, true, funcName); //프린터용 AIR처리해준다. DIO.SetPrintRVac(ePrintVac.inhalation); DIO.SetPrintRAir(true); //PUB.Result.ItemData[1].UpdateTo(ref PUB.Result.ItemData[2]); } PUB.Result.ItemDataC.Clear($"[{target}] Pick-on completed"); //Clear after transmission KeyenceBarcodeDataF = string.Empty; KeyenceBarcodeDataR = string.Empty; //PUB.log.AddAT($"바코드데이터 삭제(CENTER)"); //다음데이터를 읽을 수 있도록 트리거를 전송한다 System.Threading.Tasks.Task.Run(() => { if (PUB.keyenceF != null) PUB.keyenceF.Trigger(true); if (PUB.keyenceR != null) PUB.keyenceR.Trigger(true); }); //Keyence_Trigger(true); //SID목록을 저장한다 231005 string sid, prn; sid = prn = ""; if (target == eWorkPort.Left) { sid = PUB.Result.ItemDataL.VisionData.SID; prn = PUB.Result.ItemDataL.VisionData.PrintPositionData; } else { sid = PUB.Result.ItemDataR.VisionData.SID; prn = PUB.Result.ItemDataR.VisionData.PrintPositionData; } if (sid.isEmpty() == false) { if (PUB.Result.PrintPostionList.ContainsKey(sid) == false) { PUB.Result.PrintPostionList.Add(sid, prn); PUB.log.AddAT($"Print position saved SID:{sid} = {prn}"); } else { var predata = PUB.Result.PrintPostionList[sid]; if (predata != prn) { PUB.log.AddAT($"Print position save value changed SID:{sid} = {predata} -> {prn}"); PUB.Result.PrintPostionList[sid] = prn; } } } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### PICKER OFF //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (target == eWorkPort.Left) { if (PRINTER(target, eSMStep.RUN_PRINTER_F)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_F); Complete = PICKER_OFF(target, eSMStep.RUN_PICKER_OFF_L); } else { if (PRINTER(target, eSMStep.RUN_PRINTER_R)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_R); Complete = PICKER_OFF(target, eSMStep.RUN_PICKER_OFF_R); } if (Complete == false) return false; //PUB.log.Add($"[{target}] 피커 OFF 작업 완료"); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 피커위치로 이동시키고 권한을 넘겨준다 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { //프린터와 pickoin 작업을 진행한다 if (target == eWorkPort.Left) { if (PRINTER(target, eSMStep.RUN_PRINTER_F)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_F); } else { if (PRINTER(target, eSMStep.RUN_PRINTER_R)) PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_R); } //X축 중앙으로 이동 var Pos = MOT.GetPXPos(ePXLoc.PICKON); if (target == eWorkPort.Left && PUB.flag.get(eVarBool.FG_ENABLE_RIGHT) == false) Pos = MOT.GetPXPos(ePXLoc.READYR); //우측이 꺼져잇다면 바코드 읽도록 우측으로 비켜준다 if (target == eWorkPort.Right && PUB.flag.get(eVarBool.FG_ENABLE_LEFT) == false) Pos = MOT.GetPXPos(ePXLoc.READYL); //좌측이 꺼져있다면 바코드 읽도록 좌측으로 비켜준다 if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false; //X축을 놓아준다 LockPK.Set(); hmi1.RemoveLockItem((int)target, "LD-FRONT"); PUB.logDbg.Add($"[{target}] X축 권한 해제"); PUB.mot.ClearPosition((int)eAxis.Z_THETA); //if (target == eWorkShuttle.Left) // PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_F); //else // PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_R); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (target == eWorkPort.Left) Complete = PRINTER(target, eSMStep.RUN_PRINTER_F); else Complete = PRINTER(target, eSMStep.RUN_PRINTER_R); if (Complete == false) return false; //PUB.log.Add($"[{target}] 프린터 작업 완료"); //if (target == eWorkShuttle.Left) // PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_ON_F); //else // PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_ON_R); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터 PICK ON //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (target == eWorkPort.Left) Complete = PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_F); else Complete = PRINTER_ON(target, eSMStep.RUN_PRINTER_ON_R); if (Complete == false) return false; //PUB.log.Add($"[{target}] 프린터 ON 작업 완료"); if (target == eWorkPort.Left) { PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_OFF_F); DIO.SetPrintLAir(false); } else { PUB.sm.seq.Clear(eSMStep.RUN_PRINTER_OFF_R); DIO.SetPrintRAir(false); } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터 PICK OFF //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (target == eWorkPort.Left) Complete = PRINTER_OFF(target, eSMStep.RUN_PRINTER_OFF_F); else Complete = PRINTER_OFF(target, eSMStep.RUN_PRINTER_OFF_R); if (Complete == false) return false; //PUB.log.Add($"[{target}] 프린터 OFF 작업 완료"); PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터(Y,Z) 안전위치로 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { sPositionData PosZ; if (target == eWorkPort.Left) { PosZ = MOT.GetLZPos(eLZLoc.READY); } else { PosZ = MOT.GetRZPos(eRZLoc.READY); } if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false; //카메라를 사용한다면 검증해야하니 컨베이어를 멈춘다 if (OPT_CameraOff == false) { if (target == eWorkPort.Left) PUB.iLockCVL.set((int)eILockCV.VISION, true, funcName); else PUB.iLockCVR.set((int)eILockCV.VISION, true, funcName); } //Z가 올라갔으니 컨베이어를 돌려도된다 if (CVMode) { //카메라를 사용하지 않는다면 바로 OFF 한다 if (VAR.BOOL[eVarBool.Opt_DisableCamera] == false) { if (target == eWorkPort.Left) PUB.iLockCVL.set((int)eILockCV.BUSY, false, funcName); else PUB.iLockCVR.set((int)eILockCV.BUSY, false, funcName); } } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 실리더 원위치 이동시킨다 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { if (target == eWorkPort.Left) { DIO.SetOutput(eDOName.PRINTL_FWD, false); } else { DIO.SetOutput(eDOName.PRINTR_FWD, false); } PUB.sm.seq.Update(cmdIndex); return false; } if (PUB.sm.seq.Get(cmdIndex) == idx++) { if (target == eWorkPort.Left) { if (DIO.checkDigitalO(eDIName.L_PICK_BW, seqTime, true) != eNormalResult.True) return false; } else { if (DIO.checkDigitalO(eDIName.R_PICK_BW, seqTime, true) != eNormalResult.True) return false; } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 프린터(Y,Z) 안전위치로 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { sPositionData PosY, PosZ; if (target == eWorkPort.Left) { PosY = MOT.GetLMPos(eLMLoc.READY); PosZ = MOT.GetLZPos(eLZLoc.READY); PUB.sm.seq.Clear(eSMStep.RUN_QRVALID_F); } else { PosY = MOT.GetRMPos(eRMLoc.READY); PosZ = MOT.GetRZPos(eRZLoc.READY); PUB.sm.seq.Clear(eSMStep.RUN_QRVALID_R); } if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false; if (MOT.CheckMotionPos(seqTime, PosY, funcName) == false) return false; PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### QR코드 검증 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { bool Complete = false; if (OPT_CameraOff) //카메라사용하지 않음 { PUB.log.Add($"QR Validation SKIP:{target} - Camera Off"); Complete = true; item.PrintQRValidResult = "SKIP"; //var sendok = WS_Send(target, WS, item.guid, "TRIG", item.VisionData.PrintQRData); } else { if (target == eWorkPort.Left) Complete = QR_VALIDATION(target, eSMStep.RUN_QRVALID_F); else Complete = QR_VALIDATION(target, eSMStep.RUN_QRVALID_R); } if (Complete == false) return false; PUB.log.Add($"QR Validation Complete:{target}"); //작업이완료되었다 if (target == eWorkPort.Left) { PUB.iLockCVL.set((int)eILockCV.BUSY, false, funcName); PUB.iLockCVL.set((int)eILockCV.VISION, false, funcName); WS_Send(eWorkPort.Left, PUB.wsL, "", "OFF", ""); } else { PUB.iLockCVR.set((int)eILockCV.BUSY, false, funcName); PUB.iLockCVR.set((int)eILockCV.VISION, false, funcName); WS_Send(eWorkPort.Right, PUB.wsR, "", "OFF", ""); } PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 결과업데이트(22/07/07) //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { item.JobEnd = DateTime.Now; //전송한다 var reelsize = "0"; if (item.VisionData.ReelSize == eCartSize.Inch7) reelsize = "7"; else if (item.VisionData.ReelSize == eCartSize.Inch13) reelsize = "13"; var reelinfo = new { AMKOR_SID = item.VisionData.SID,// tbsid.Text, AMKOR_BATCH = item.VisionData.BATCH,// tbbatch.Text, LABEL_ID = item.VisionData.RID,// tbrid.Text, LABEL_VENDOR_LOT = item.VisionData.VLOT,// tblot.Text, LABEL_AMKOR_SID = item.VisionData.SID,// tbsid.Text, LABEL_QTY = item.VisionData.QTY,// tbqty.Text, LABEL_MANUFACTURER = item.VisionData.VNAME,// tbvname.Text, LABEL_PRODUCTION_DATE = item.VisionData.MFGDATE,// tbmfg.Text, LABEL_INCH_INFO = reelsize,// tbinch.Text, LABEL_PART_NUM = item.VisionData.PARTNO,// tbpart.Text, EQP_ID = AR.SETTING.Data.McName,// tbeqid.Text, EQP_NAME = $"Auto Label Attach {SETTING.Data.McName}", BADGE = string.Empty, OPER_NAME = string.Empty, CPN = item.VisionData.MCN, TARGET = item.VisionData.Target, }; bool rlt = false; string errmsg = string.Empty; //var systembypassmode = SETTING PUB.Result.vModel.Title.Equals("BYPASS"); CVMode == true && if (SETTING.Data.SystemBypass == false) { rlt = PUB.UpdateWMS(item.VisionData); //rlt = Amkor.RestfulService.Inbound_label_attach_reel_info(reelinfo, out errmsg); PUB.log.AddE("WMS transmission " + (rlt ? "success" : "failed") + $": {errmsg}"); if (rlt == false) //230927 - 오류발생시 { PUB.Result.SetResultMessage(eResult.OPERATION, eECode.INBOUNDWEBAPIERROR, eNextStep.PAUSE, target, errmsg); return false; ; } } else { errmsg = "bypass"; rlt = false; PUB.log.AddAT($"WMS save disabled due to System bypass"); } if (errmsg.Length > 190) errmsg = errmsg.Substring(0, 190); //230810 maxlength error SaveData_EE(item, (target == eWorkPort.Left ? "L" : "R"), (rlt ? "OK" : errmsg), "root_sequence"); //RefreshList(); //목록업데이트 //EEMStatus.AddStatusCount(1, $"{item.VisionData.SID}|{item.VisionData.RID}"); //eem 추가 230620 PUB.sm.seq.Update(cmdIndex); return false; } //#################################################### //### 다시`` 처음으로 이동 //#################################################### if (PUB.sm.seq.Get(cmdIndex) == idx++) { PUB.StatusMessage.set(msgType, $"[{target}] 전체작업완료 초기화"); UserStepWait(target); item.Clear($"{target}:{funcName}"); if (target == eWorkPort.Left) { PUB.flag.set(eVarBool.FG_BUSY_LEFT, false, funcName); } else { PUB.flag.set(eVarBool.FG_BUSY_RIGHT, false, funcName); } VAR.TIME[(int)eVarTime.JOBEVENT] = DateTime.Now; PUB.log.AddI($"[{target}] Work completed"); PUB.sm.seq.Clear(cmdIndex); return true; } PUB.sm.seq.Clear(cmdIndex); return true; } } }