Initial commit

This commit is contained in:
ChiKyun Kim
2025-07-17 16:11:46 +09:00
parent 4865711adc
commit 4a1b1924ba
743 changed files with 230954 additions and 0 deletions

View File

@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AR;
namespace Project
{
public partial class FMain
{
async public Task<bool> _SM_RUN_STARTCHKSW(bool isFirst, TimeSpan stepTime)
{
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
double free = 0;
var savepath = PUB.getSavePath(out free);
if (free < 3.0)
{
string msg = "FREE SPACE ERROR\n" +
"디스크 공간(3%)이 부족하여 작업을 진행할 수 없습니다\n" +
"저장경로 : {0}\n" +
"데이터를 삭제하거나 설정의 삭제주기를 확인하세요";
msg = string.Format(msg, AR.SETTING.Data.Path_Data);
PUB.popup.setMessage(msg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
if (PUB.Result.isSetmModel == false)
{
string msg = "모션모델이 선택되지 않았습니다\n작업모델의 'MOTION'항목을 확인하세요";
PUB.popup.setMessage(msg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
//모션의 모든 위치가 원점이 아니라면 홈 초기화를 요청한다.
var initMsg = "";
if (initMsg != "")
{
PUB.popup.setMessage(initMsg);
DIO.SetBuzzer(true);
PUB.sm.SetNewStep(eSMStep.IDLE);
return false;
}
//모델정보가 설정되어있는지 확인
if (PUB.Result == null ||
PUB.Result.vModel == null ||
PUB.Result.vModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELV, eNextStep.ERROR);
return false;
}
//모션모델자동선택 230823
var motionmode = VAR.BOOL[eVarBool.Use_Conveyor] ? "Conveyor" : "Default";
if (PUB.SelectModelM(motionmode) == false)
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
//모델정보가 설정되어있는지 확인
if (PUB.Result == null ||
PUB.Result.mModel == null ||
PUB.Result.mModel.Title.isEmpty())
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
return false;
}
//ECS데이터확인 230823
var conv = VAR.BOOL[eVarBool.Use_Conveyor];
if (conv)
{
var sidinfo = await PUB.UpdateSIDInfoByECS();
var systembypass = SETTING.Data.SystemBypass;
if (systembypass == false && sidinfo.Item1 == false)
{
PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOECSDATA, eNextStep.ERROR, sidinfo.Item2);
return false;
}
//else if (systembypass == false && sidinfo.Item3 < 1)
//{
// PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOECSDATAACTIVE, eNextStep.ERROR, sidinfo.Item2);
// return false;
//}
}
//SID변환정보 필요 230823
//이값도 테이블에서 실시간으로 조회되므로 미리 불러올 필요 없다
//사용자추가정보 필요 230823
//기존에 사용하던 사용자 추가 정보
//ECS정보가 수신되면 기존 TABLE 을 삭제하는 구조이므로 병행할수 없음
//데이터는 테이블에서 실시간으로 조 회됨
//사용자스텝실행
if (PUB.flag.get(eVarBool.FG_USERSTEP))
{
PUB.flag.set(eVarBool.FG_USERSTEP, false, "STACHKSW");
PUB.log.AddI("작업 시작으로 인해 H/W검사 무시기능을 해제 함");
}
//공용변수초기화
PUB.log.Add("공용변수(카운트)값 초기화");
VAR.I32.Clear((int)eVarInt32.LPickOfCount);
VAR.I32.Clear((int)eVarInt32.LPickOnCount);
VAR.I32.Clear((int)eVarInt32.RPickOfCount);
VAR.I32.Clear((int)eVarInt32.RPickOnCount);
VAR.I32.Clear((int)eVarInt32.PickOfCount);
VAR.I32.Clear((int)eVarInt32.PickOnCount);
VAR.I32.Clear((int)eVarInt32.PickOnRetry); //221102
PUB.flag.set(eVarBool.FG_RUN_LEFT, false, "POSREST");
PUB.flag.set(eVarBool.FG_RUN_RIGHT, false, "POSREST");
VAR.BOOL[eVarBool.JOB_Empty_SIDConvertInfo] = false;
PUB.Result.ItemDataL.Clear("START_CHKSW");
PUB.Result.ItemDataC.Clear("START_CHKSW");
PUB.Result.ItemDataR.Clear("START_CHKSW");
var modelName = PUB.Result.vModel.Title;
PUB.Result.BCDPattern = PUB.GetPatterns(modelName, false);
PUB.Result.BCDIgnorePattern = PUB.GetPatterns(modelName, true);
PUB.Result.BCDPrintPattern = PUB.GetPrintPatterns();
PUB.log.Add($"모델패턴로딩:{PUB.Result.BCDPattern.Count}/{PUB.Result.BCDIgnorePattern.Count}");
//변환SID SID확인여부데이터 삭제
PUB.Result.DTSidConvertEmptyList.Clear();
PUB.Result.DTSidConvertMultiList.Clear();
PUB.Result.JobStartTime = DateTime.Now;
warninactivelist.Clear();
//작업락기능해제
LockPK.Set();
LockUserL.Set();
LockUserR.Set();
return true;
}
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 장치의 초기화 여부를 우선 체크 한다.
/// 장치에 문제가 있는 경우에는 ERROR상황으로 뺀다
/// ERROR 상황은 RESET 시 IDLE로 전환된다.
/// 복구불가능한 오류 상황이다.
///
/// </summary>
/// <param name="isFirst"></param>
/// <param name="stepTime"></param>
/// <returns></returns>
public Boolean _SM_RUN_STARTCHKHW(bool isFirst, TimeSpan stepTime)
{
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
//최초시작이므로 - 셔틀2의 안전위치 이동 플래그를 OFF해준다.
//장치초기화 확인
if (PUB.mot.IsInit == false || PUB.dio.IsInit == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
return false;
}
//서보 off 상태 확인
if (PUB.mot.HasServoOff)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_SVOFF, eNextStep.ERROR);//, msg);
return false;
}
//홈 검색완료 체크1
if (PUB.mot.HasHomeSetOff)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.MOT_HSET, eNextStep.ERROR);
return false;
}
//air확인
if (DIO.GetIOOutput(eDOName.SOL_AIR) == false)
{
PUB.Result.SetResultMessage(eResult.SENSOR, eECode.AIRNOOUT, eNextStep.ERROR);
return false;
}
//카메라초기화체크(초기화가 오래걸려서 쓰레드분리함) - 201229
if (VAR.BOOL[eVarBool.Opt_DisableCamera] == false && AR.SETTING.Data.Enable_Unloader_QRValidation && PUB.flag.get(eVarBool.FG_RDY_CAMERA_L) == false && AR.SETTING.Data.Disable_Left == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CAM_LEFT, eNextStep.ERROR);
return false;
}
if (VAR.BOOL[eVarBool.Opt_DisableCamera] == false && AR.SETTING.Data.Enable_Unloader_QRValidation && PUB.flag.get(eVarBool.FG_RDY_CAMERA_R) == false && AR.SETTING.Data.Disable_Right == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CAM_RIGHT, eNextStep.ERROR);
return false;
}
//안전위치 센서가 안들어와잇으면 오류 처리한다
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == false)
{
PUB.Result.SetResultMessage(eResult.MOTION, eECode.NEED_JOBCANCEL, eNextStep.ERROR, eAxis.PL_MOVE, PUB.mot.ErrorMessage);
return false;
}
//프린터확인
if (PUB.flag.get(eVarBool.FG_INIT_PRINTER) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER, eNextStep.ERROR);
return false;
}
//부착 실린더 위치 확인
if (AR.SETTING.Data.Enable_PickerCylinder)
{
if (DIO.GetIOInput(eDIName.L_CYLUP) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_LPRINTER_NOUP, eNextStep.ERROR);
return false;
}
if (DIO.GetIOInput(eDIName.R_CYLUP) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_RPRINTER_NOUP, eNextStep.ERROR);
return false;
}
}
//부착 실린더 위치 확인
if (DIO.GetIOInput(eDIName.L_PICK_BW) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_LPICKER_NOBW, eNextStep.ERROR);
return false;
}
if (DIO.GetIOInput(eDIName.R_PICK_BW) == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTER_RPICKER_NOBW, eNextStep.ERROR);
return false;
}
//컨베이어 모드에서 컨베이어에 릴이 감지되면 시작하지 못한다
if (VAR.BOOL[eVarBool.Use_Conveyor])
{
if (DIO.GetIOInput(eDIName.L_CONV1))
{
//감지되면 안된다
var ssname = $"X{eDIName.L_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_REEL_DECTECT_ALL, eNextStep.ERROR, ssname);
return false;
}
if (DIO.GetIOInput(eDIName.R_CONV1) ||
DIO.GetIOInput(eDIName.R_CONV4))
{
//감지되면 안된다
var ssname = $"X{eDIName.R_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_REEL_DECTECT_ALL, eNextStep.ERROR, ssname);
return false;
}
}
////카메라체크
//for (int i = 0; i < _isCrevisOpen.Length; i++)
//{
// if (COMM.SETTING.Data.DisableCamera(i) == true)
// {
// PUB.log.AddAT($"카메라({i})번 비활성 됨(환경설정)");
// }
// else if (_isCrevisOpen[i] == false)
// {
// if (i == 0 && COMM.SETTING.Data.DisableCamera0 == false && COMM.SETTING.Data.Disable_Left == false)
// {
// PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_NOCONN, eNextStep.ERROR, i);
// return false;
// }
// if (i == 2 && COMM.SETTING.Data.DisableCamera2 == false && COMM.SETTING.Data.Disable_Right == false)
// {
// PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_NOCONN, eNextStep.ERROR, i);
// return false;
// }
// }
//}
//트리거 OFF작업
WS_Send(eWorkPort.Left, PUB.wsL, "", "OFF", "");
WS_Send(eWorkPort.Right, PUB.wsR, "", "OFF", "");
var systembypassmode = SETTING.Data.SystemBypass;
//바코드설정업데이트
if (systembypassmode == false)
{
var k1 = PUB.UpLoadBarcodeConfig(PUB.keyenceF);
var k2 = PUB.UpLoadBarcodeConfig(PUB.keyenceR);
if (k1 == false && k2 == false) //결과확인하도록함 230511
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.CONFIG_KEYENCE, eNextStep.ERROR);
return false;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,667 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using AR;
using Project.Class;
namespace Project
{
public partial class FMain
{
public enum EResultKeyence
{
Wait = 0,
Complete,
TimeOut,
}
public EResultKeyence KEYENCE_READ(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 itemC = PUB.Result.ItemDataC;
if (PUB.sm.getNewStep != eSMStep.RUN) return EResultKeyence.Wait;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = PUB.OPT_BYPASS();
//데이터가 완료되었는지 확인
if (itemC.VisionData.Confirm)
{
PUB.log.AddAT("비젼 데이터 완료로 인해 바코드 메세지를 제거 합니다");
itemC.VisionData.bcdMessage.Clear();
return EResultKeyence.Complete;
}
//사용자 입력 대기중이면 아에 처리하지 않는다 210203
if (PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO) == true)
{
PUB.WaitMessage[1] = "Wait for User Confirm Interface";
return EResultKeyence.Wait;
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (PUB.Result.DryRun)
{
PUB.log.Add($"[{target}] DRY-RUN 으로 인한 완료");
SetDryrunData();
}
else
{
PUB.logDbg.Add($"[{target}] 키엔스 읽기 시작");
if (PUB.keyenceF != null) PUB.keyenceF.Trigger(true);
if (PUB.keyenceR != null) PUB.keyenceR.Trigger(true);
}
VAR.BOOL[eVarBool.Need_UserConfirm_Data] = false;
VAR.TIME.Update(eVarTime.KEYENCEWAIT);
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//아무것도안함
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//### 키엔스데이터를 처리해준다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
bool vQtyOK = false;
//동작중이아니라면 처리하지 않음
if (PUB.sm.getNewStep != eSMStep.RUN) return EResultKeyence.Wait;
//var k1 = UpLoadBarcodeConfig(PUB.keyenceF);
//바이패스라면 무조건ok한다.
var systembypassmode = SETTING.Data.SystemBypass;
if (systembypassmode && PUB.flag.get(eVarBool.FG_RDY_PORT_PC))
{
PUB.Result.ItemDataC.VisionData.SetRID("BP" + DateTime.Now.ToString("yyyyMMddHHmmss"), "bp");
PUB.Result.ItemDataC.VisionData.SID = ("100000000");
PUB.Result.ItemDataC.VisionData.VNAME = "BYPASS";
PUB.Result.ItemDataC.VisionData.MFGDATE = DateTime.Now.ToString("yyyy-MM-dd");
PUB.Result.ItemDataC.VisionData.VLOT = "BYPASS";
PUB.Result.ItemDataC.VisionData.CUSTCODE = "0000";
PUB.Result.ItemDataC.VisionData.CUSTNAME = "BYPASS";
PUB.Result.ItemDataC.VisionData.QTY = "10000";
PUB.Result.ItemDataC.VisionData.ConfirmUser = true;
PUB.Result.ItemDataC.VisionData.PrintPositionData = "1";
PUB.Result.ItemDataC.VisionData.PrintPositionCheck = true;
return EResultKeyence.Complete;
}
//로더정보를 사용자가 처리중이면 동작 안함
if (PUB.flag.get(eVarBool.FG_WAIT_LOADERINFO)) return EResultKeyence.TimeOut;
//데이터 처리 시간을 넘어서면 사용자 확인 창을 띄운다 220621
var ts = VAR.TIME.RUN((int)eVarTime.KEYENCEWAIT);
if (PUB.flag.get(eVarBool.FG_RDY_PORT_PC) && ts.TotalMilliseconds > AR.SETTING.Data.Timeout_VisionProcessL)
{
//화면업데이트를 종료한다
if (PUB.keyenceF != null) PUB.keyenceF.Trigger(false);
if (PUB.keyenceR != null) PUB.keyenceR.Trigger(false);
//이미지저장용 작업시작
var tempfileF = System.IO.Path.Combine(UTIL.CurrentPath, "Temp", "Image", DateTime.Now.ToString("yyyMMddHhmmss_fff" + "F.bmp"));
var tempfileR = System.IO.Path.Combine(UTIL.CurrentPath, "Temp", "Image", DateTime.Now.ToString("yyyMMddHhmmss_fff" + "R.bmp"));
var tempfiF = new System.IO.FileInfo(tempfileF);
var tempfiR = new System.IO.FileInfo(tempfileR);
if (tempfiF.Directory.Exists == false) tempfiF.Directory.Create();
if (tempfiR.Directory.Exists == false) tempfiR.Directory.Create();
//마지막 사진을 추출한다
var CurImageF = PUB.keyenceF.SaveImage(tempfiF.FullName);
var CurImageR = false;
if (PUB.keyenceR != null) CurImageR = PUB.keyenceR.SaveImage(tempfiR.FullName);
if (CurImageF && CurImageR)
{
itemC.VisionData.SetImage(
new Emgu.CV.Mat(tempfiF.FullName, Emgu.CV.CvEnum.ImreadModes.Grayscale),
new Emgu.CV.Mat(tempfiR.FullName, Emgu.CV.CvEnum.ImreadModes.Grayscale));
//using (var tempimg = new Emgu.CV.Image<Emgu.CV.Structure.Gray, byte>(tempfi.FullName))
//{
// itemC.VisionData.SetImage(tempimg);
//}
}
else if (CurImageF)
{
itemC.VisionData.SetImage(new Emgu.CV.Mat(tempfiF.FullName, Emgu.CV.CvEnum.ImreadModes.Grayscale));
//using (var tempimg = new Emgu.CV.Image<Emgu.CV.Structure.Gray, byte>(tempfi.FullName))
//{
// itemC.VisionData.SetImage(tempimg);
//}
}
PUB.keyenceF.Trigger(true);
PUB.keyenceR.Trigger(true);
return EResultKeyence.TimeOut;
}
//수량임의 입력의 경우
if (VAR.BOOL[eVarBool.Opt_UserQtyRQ])
{
if (itemC.VisionData.QTYRQ) vQtyOK = true; ////RQ의 값이 들어있으면 성공
else vQtyOK = false; //수량임의모드인데 RQ값이 들어있지않으면 자동진행하지 않는다
}
else
{
//자동에서는 수량값이 들어있으면 바로 넘어가게한다.
vQtyOK = itemC.VisionData.QTY.isEmpty() == false;
}
//커스터머 이름 확인
if (OPT_BYPASS == false && (itemC.VisionData.CUSTNAME.isEmpty() && itemC.VisionData.CUSTCODE.isEmpty() == false))
{
var qta = new DataSet1TableAdapters.QueriesTableAdapter();
var custname = qta.GetCustName(itemC.VisionData.CUSTCODE);
if (custname.isEmpty() == false)
{
PUB.log.Add($"New CustName => {custname}");
itemC.VisionData.CUSTNAME = custname;
}
}
//릴Id 신규부여
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_NewReelID])
{
if (itemC.VisionData.RIDNew == false && itemC.VisionData.CUSTCODE.isEmpty() == false)
{
var newid = Amkor.RestfulService.Allocation_Unique_ReelID_AmkorSTD(itemC.VisionData.CUSTCODE, "4", "A", out string errmsg);
if (newid.isEmpty() == false)
{
//backup origin reel id
itemC.VisionData.RID0 = itemC.VisionData.RID;
//set new reel id
itemC.VisionData.SetRID(newid, "SPS:CHKDATACOMPLETE");// = newid;
itemC.VisionData.RIDNew = true; //applied new reel id
//서버의수량업데이트기능이 켜져있다면 해당 값을 제거해준다. (다시 조회되도록 함)
if (VAR.BOOL[eVarBool.Opt_ServerQty])
{
//이미 수량업데이트된 경우이므로 복원시켜준다
if (itemC.VisionData.QTY0.isEmpty() == false)
{
PUB.log.AddAT($"릴아이디 변경으로 인해 수량을 복원합니다({itemC.VisionData.QTY}->{itemC.VisionData.QTY0})");
itemC.VisionData.QTY = itemC.VisionData.QTY0;
itemC.VisionData.QTY0 = string.Empty;
}
}
}
else
{
var logtime = VAR.TIME.RUN((int)eVarTime.LOG_NEWIDERROR);
if (logtime.TotalSeconds >= 3000)
{
PUB.log.AddAT($"Reel_ID 생성실패 : {errmsg}");
VAR.TIME.Update(eVarTime.LOG_NEWIDERROR);
}
}
}
}
//기본 벤더이름
if (OPT_BYPASS == false && PUB.Result.vModel.Def_Vname.isEmpty() == false)
{
if (itemC.VisionData.VNAME.Equals(PUB.Result.vModel.Def_Vname) == false)
{
itemC.VisionData.VNAME = PUB.Result.vModel.Def_Vname;
itemC.VisionData.VNAME_Trust = true;
PUB.log.Add($"Defaul V.Name Set to {PUB.Result.vModel.Def_Vname}");
}
}
//기본 MFG
if (OPT_BYPASS == false && PUB.Result.vModel.Def_MFG.isEmpty() == false)
{
if (itemC.VisionData.MFGDATE.Equals(PUB.Result.vModel.Def_MFG) == false)
{
itemC.VisionData.MFGDATE = PUB.Result.vModel.Def_MFG;
itemC.VisionData.MFGDATE_Trust = true;
PUB.log.Add($"Defaul MFGDATE Set to {PUB.Result.vModel.Def_MFG}");
}
}
if (itemC.VisionData.Confirm)
{
//이미 완료된 데이터
if (itemC.VisionData.ConfirmAuto)
PUB.log.AddI($"데이터확정완료(자동)로 인한 진행");
else if (itemC.VisionData.ConfirmUser)
PUB.log.AddI($"데이터확정완료(수동)로 인한 진행");
else
PUB.log.AddI($"데이터확정완료(BYPASS)로 인한 진행");
}
else if (itemC.VisionData.QRInputRaw.isEmpty() == false && itemC.VisionData.BATCH.isEmpty() == false)
{
//ATK STD QR데이터가 입력되었으니 더이상 읽지 않아도 진행하도록 하자
//데이터가 부족하다면 바로 채우기 작업을 해야한다
CheckDataComplte(itemC, "STD", true);
return EResultKeyence.Wait;
}
else if (vQtyOK &&
(OPT_BYPASS || itemC.VisionData.VNAME.isEmpty() == false) &&
itemC.VisionData.VLOT.isEmpty() == false &&
itemC.VisionData.SID.Length == 9 &&
(OPT_BYPASS || itemC.VisionData.MFGDATE.isEmpty() == false) &&
itemC.VisionData.PARTNO.isEmpty() == false &&
itemC.VisionData.BATCH.isEmpty() == false &&
itemC.VisionData.RID.isEmpty() == false)
{
//모든값이 입력되어 있다면 조건 체크후 진행할 수 있도록 한다
//2206211400
CheckDataComplte(itemC, "SINGLE", true);
return EResultKeyence.Wait;
}
else
{
//아직데이터가 완료되지 않았다면
//대기시간이 지나면 사용자 확인창을 띄운다
return EResultKeyence.Wait;
}
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return EResultKeyence.Wait;
}
PUB.sm.seq.Clear(cmdIndex);
return EResultKeyence.Complete;
}
/// <summary>
/// 데이터입력이 완료되었는지 확인 합니다
/// </summary>
/// <param name="item"></param>
/// <param name="Source"></param>
/// <param name="mainjob"></param>
void CheckDataComplte(Class.JobData item, string Source, bool mainjob)
{
Boolean NeedConfirm = false;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
var OPT_BYPASS = SETTING.Data.SystemBypass;// Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
if (item.VisionData.Confirm)
{
//사용자에의해 완성된 자료는 완료된 자료이다
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
return;
}
//DB정보에서 데이터를 쓸것이 있다면 기록한다
//이전작업내역에서 데이터를 쓸것이 있다면 기록한다
//서버의수량업데이트기능
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_ServerQty])
{
//수량원본이 없는 경우
if (item.VisionData.QTY0.isEmpty())
{
string msg;
var cnt = (int)(Amkor.RestfulService.get_stock_count(item.VisionData.RID, out msg));
if (cnt > 0)
{
//새로받은 데이터를 실제 수량에 추가한다
item.VisionData.QTY0 = item.VisionData.QTY;
item.VisionData.QTY = cnt.ToString();
if (mainjob) PUB.log.Add($"서버수량업데이트 RID:{item.VisionData.RID} 구:{item.VisionData.QTY},신:{cnt}");
}
else
{
if (mainjob) PUB.log.AddE($"수량업데이트 실패 rID:{item.VisionData.RID},Message={msg}");
NeedConfirm = true;
if (mainjob) item.VisionData.bcdMessage.Add("수량 업데이트 실패");
}
}
}
//수량입력 210708
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_UserQtyRQ])
{
if (item.VisionData.QTYRQ && item.VisionData.QTY.isEmpty() == false)
{
//RQ값이 이전 값이 오기도 하니 바코드 목록에서 값을 다시 써준다. 210825
var rqBcd = PUB.Result.ItemDataC.VisionData.barcodelist.Where(t => t.Value.Data.StartsWith("RQ")).FirstOrDefault();
if (rqBcd.Value != null)
{
var newqty = rqBcd.Value.Data.Substring(2).Trim();
if (mainjob) PUB.log.Add($"수량업데이트(01) {item.VisionData.QTY}->{newqty}");
item.VisionData.QTY = newqty;
if (mainjob) PUB.log.AddI("수량수동입력상태이나 RQ값이 확인되어 사용자 확인을 하지 않음");
}
else
{
if (mainjob) item.VisionData.bcdMessage.Add("RQ값 오류 (자동불가)");
NeedConfirm = true;
}
}
else
{
if (mainjob) item.VisionData.bcdMessage.Add("수량 수동 입력 필요");
NeedConfirm = true;
}
}
//SID 존재여부 확인
if (OPT_BYPASS == false && item.VisionData.SID_Trust && VAR.BOOL[eVarBool.Opt_CheckSIDExist])
{
//ECS목록에 데이터가 업다면 오류로 처리한다
var SID = item.VisionData.SID;
var MCName = VAR.BOOL[eVarBool.Use_Conveyor] ? "IB" : SETTING.Data.McName;
var ta = new DataSet1TableAdapters.QueriesTableAdapter();
var exist = ta.CheckSIDExist(MCName, SID) > 0;
PUB.log.Add($"SID 존재여부 검사 KEY:{MCName},SID:{item.VisionData.SID},Result={exist}");
if (exist == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOSIDINFOFROMDB, eNextStep.PAUSE, SID);
return;
}
}
//sid변환기능확인
var SIDOK = false;
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_SIDConvert])
{
//변환된 정보가 없다면 변환을 진행한다
if (item.VisionData.SID0.isEmpty() && item.VisionData.SID_Trust && item.VisionData.SID.isEmpty() == false)
{
//현재SID가 정상 시드라면 변환을 시작한다
//_SM_RUN_VISION_SIDCONV(item);
}
//시드값이 유효한지 확인한다.
SIDOK = item.VisionData.SID_Trust && item.VisionData.SID0.isEmpty() == false && item.VisionData.SID.isEmpty() == false;
}
else SIDOK = item.VisionData.SID_Trust; //시드변환을 사용하지 않으므로 시드값여부에따라 다르다
//사용자확인이 필요한 옵션이라면 사용한다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_UserConfim])
{
if (NeedConfirm == false)
{
if (mainjob) item.VisionData.bcdMessage.Add("사용자 확인 필요");
//if (mainjob) PUB.log.Add($"사용자 확인 옵션으로 인해 창을 표시 합니다{Source}");
NeedConfirm = true;
}
}
//처음작업이면 반드시 확인을 한다
if (OPT_BYPASS == false && PUB.Result.JobFirst)
{
//사용자확인이 필요없는 상태라면 활성화해준다
if (NeedConfirm == false)
{
//프린트를 하지 않는다면 처리하지 않는다.
if (VAR.BOOL[eVarBool.Opt_DisablePrinter] == false)
{
if (mainjob) item.VisionData.bcdMessage.Add("첫번째 릴 확인 필요");
//if (mainjob) PUB.log.Add($"처음 작업이므로 사용자 확인창을 표시 합니다{Source}");
NeedConfirm = true;
}
}
}
//변환작업인데 원본 값이 없다.
//혹은 변환값과 원본이 같다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Opt_SIDConvert] && (item.VisionData.SID0.isEmpty() == true || item.VisionData.SID0 == item.VisionData.SID))
{
if (NeedConfirm == false)
{
if (mainjob) item.VisionData.bcdMessage.Add("SID변환값 확인 필요");
NeedConfirm = true;
}
}
//프린트위치확인
if (item.VisionData.PrintPositionData.isEmpty() == true || item.VisionData.PrintPositionCheck == false)
{
if (OPT_BYPASS)
{
//바이패스해야하는 경우라면 프린트위치를 임의로 한다
if (item.VisionData.PrintPositionData.isEmpty())
{
item.VisionData.PrintPositionData = "1";
item.VisionData.PrintPositionCheck = true;
PUB.log.AddI($"바이패스SID({item.VisionData.SID})로 인해 인쇄위치 임의지정");
}
}
else
{
//기록된 현재작업의 인쇄위치 정보에서 찾는다 231005
if (PUB.Result.PrintPostionList.ContainsKey(item.VisionData.SID))
{
var preprnpos = PUB.Result.PrintPostionList[item.VisionData.SID];
item.VisionData.PrintPositionData = preprnpos;
item.VisionData.PrintPositionCheck = true;
PUB.log.AddI($"현 작업정보에서 프린트위치 찾음 SID:{item.VisionData.SID},값={preprnpos}");
}
else
{
if (NeedConfirm == false)
{
//현작업내에서의 정보를 찾아서 적용한다 231005
//if (mainjob) PUB.log.AddAT("프린트 위치 결정이 완료되지 않아. 사용자 선택화면을 팝업합니다");
if (mainjob) item.VisionData.bcdMessage.Add("부착위치 없음");
NeedConfirm = true;
}
}
}
}
//바이패스모드에서 벤더네임이지정(101시드에 벤더네임이 없다)
if (OPT_BYPASS)
{
if (item.VisionData.VNAME_Trust == false)
{
item.VisionData.VNAME = "BYPASS";
item.VisionData.VNAME_Trust = true;
}
}
//데이터의 신뢰성을 확인하고 모두 입력되었다면 자동 확정을 진행한다
if (item.VisionData.MFGDATE_Trust &&
item.VisionData.PARTNO_Trust &&
item.VisionData.QTY_Trust &&
item.VisionData.RID_Trust &&
SIDOK && item.VisionData.VLOT_Trust &&
item.VisionData.VNAME_Trust)
{
//데이터를 확정짓는다 다만 화면을 표시하지 않아야하는 경우에만 처리해준다
if (NeedConfirm == false)
{
if (OPT_BYPASS)
{
PUB.log.Add("데이터가 모두 확인되어 자동 확정을 진행 합니다(bypassmode)");
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
item.VisionData.ConfirmBypass = true;
}
else if (item.VisionData.ConfirmAuto == false)
{
PUB.log.Add("데이터가 모두 확인되어 자동 확정을 진행 합니다");
if (item.VisionData.bcdMessage.Count > 0) item.VisionData.bcdMessage.Clear();
item.VisionData.ConfirmAuto = true;
}
}
}
else if (item.VisionData.QRInputRaw.isEmpty() == false)
{
if (NeedConfirm == false)
{
if (mainjob)
{
NeedConfirm = true;
PUB.log.AddAT($"데이터가 완료되지 않았으나 QR을 읽은 상태이므로 바로 확인창을 띄운다");
}
}
}
//확인창을 띄우기 위해 Timeout 오류를 발생시킨다.
VAR.BOOL[eVarBool.Need_UserConfirm_Data] = NeedConfirm;
if (NeedConfirm)
{
if (mainjob)
{
var newtime = DateTime.Now.AddMilliseconds(-AR.SETTING.Data.Timeout_VisionProcessL);
VAR.TIME.Set(eVarTime.KEYENCEWAIT, newtime);
}
}
else
{
////ecs on 컨베이어때만 사용한다
//bool warndata = false;
//if (SETTING.Data.ECSSkip == false && CVMode)
//{
// //모두 찾은상태에서는 활성화여부를 추가 확인한다.
// var sid = item.VisionData.SID;
// var bat = item.VisionData.BATCH;
// //현 시점의 활성화 목록을 가져온다
// var activelist = PUB.GetECSActiveSIDList();
// //해당sid+bat 가 활성화된것인지 확인한다.
// bool active = false;
// string active_sid = "";
// string active_bat = "";
// var sidorder = 0;
// var sidx = 0;
// foreach (var actItem in activelist)
// {
// if (actItem.Item4)
// {
// if(active_sid.isEmpty())
// {
// active_sid = actItem.Item1;
// active_bat = actItem.Item2;
// }
// }
// if (actItem.Item1.Equals(sid) && actItem.Item2.Equals(bat))
// {
// active = actItem.Item4;
// sidorder = sidx; //순서를 저장한다. 0부터 시작하는값이다.
// }
// if (actItem.Item3 == SETTING.Data.McName)
// sidx += 1;
// }
// //활성화된 sid가 아니다
// if (active == false)
// {
// if (sidorder > 1) //2번째는 무조건 에러
// {
// PUB.log.AddE($"active sid 아니고 {sidorder + 1}번 항목이므로 오류 처리한다.");
// warndata = true;
// }
// else
// {
// //활성sid의 작업데이터가있으면 ok
// var qa = new DataSet1TableAdapters.QueriesTableAdapter();
// var existreadat = qa.GetIBResultCountBySIDBatch(DateTime.Now.AddHours(-6), active_sid, active_sid) > 0;
// //활성sid의 작업데이터가있으면 ok
// if (existreadat)
// {
// PUB.log.AddAT($"active sid 는 아니지만 활성sid({active_sid}{active_sid}) 의 기록이 있어 진행 합니다");
// warndata = false;
// }
// else
// {
// PUB.log.AddE($"active sid 아니고 활성sid({active_sid}{active_sid}) 의 기록이 없어 진행 불가");
// warndata = true;
// }
// //없으면 ng
// }
// }
// //오류발생조건이나, 이미 발생했다면 처리하지 않는다.
// if (warndata)
// {
// if (warninactivelist.Contains(sid + bat) == false)
// {
// warninactivelist.Add(sid + bat);
// }
// else
// {
// PUB.log.AddAT($"이미 경고한 sid+bqt이므로 넘어갑니다({sid}{bat})");
// warndata = false;
// }
// }
//}
//if (warndata)
//{
// PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOECSDATAACTIVE, eNextStep.PAUSE, item.VisionData.SID, item.VisionData.BATCH);
// return;
//}
//else
//{
if (PUB.Result.ItemDataC.VisionData.ConfirmAuto == false)
{
PUB.logDbg.Add($"비젼 자동 확정 처리 {Source}");
PUB.Result.ItemDataC.VisionData.ConfirmAuto = true;
}
//}
}
}
List<string> warninactivelist = new List<string>();
private void SetDryrunData()
{
var item = PUB.Result.ItemDataC;
PUB.log.AddAT("드라이런 기본 데이터 입력");
if (item.VisionData.QTY.isEmpty()) item.VisionData.QTY = DateTime.Now.ToString("HHmm");
if (item.VisionData.MFGDATE.isEmpty()) item.VisionData.MFGDATE = DateTime.Now.ToString("yy-MM-dd");
if (item.VisionData.SID.isEmpty()) item.VisionData.SID = "108" + "0" + DateTime.Now.ToString("HH").PadLeft(2, '0') + DateTime.Now.ToString("fff").PadLeft(3, '0');
if (item.VisionData.VLOT.isEmpty()) item.VisionData.VLOT = "SUPNAME" + DateTime.Now.ToString("fff");
if (item.VisionData.PARTNO.isEmpty()) item.VisionData.PARTNO = "PARTNO" + DateTime.Now.ToString("yyyyMMddHHmmss.fff");
if (item.VisionData.RID.isEmpty())
{
var rid = Amkor.RestfulService.Allocation_Unique_ReelID_AmkorSTD("1234", "4", "A", out string err);
if (rid.isEmpty()) item.VisionData.SetRID("RID" + DateTime.Now.ToString("yyyyMMddHHmmss.fff"), "DRY");
else item.VisionData.SetRID(rid, "DRY");
}
if (item.VisionData.PrintPositionData.isEmpty()) item.VisionData.PrintPositionData = "2";
item.VisionData.PrintPositionCheck = true;
item.VisionData.ConfirmAuto = true;
}
}
}

View File

@@ -0,0 +1,278 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PICKER_ON(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 iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] 피커 ON 작업시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### ON 위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
var PosZ = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.log.Add($"[{target}] 피커 ON X,Y 준비위치 확인");
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PortRDY = PUB.flag.get(eVarBool.FG_RDY_PORT_PC);
if (PortRDY == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.PICKON);
var PosMatch = MOT.getPositionMatch(Pos);
//var PortRDY = PUB.flag.get(eVarBool.RDY_PORT_PC);
//if (PosMatch==false ) return false;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
VAR.I32[eVarInt32.PickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.flag.set(eVarBool.FG_PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린트부착위치가 상/하가 아니라면 추가적인 회전이 필요하다 - 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var vData = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData : PUB.Result.ItemDataR.VisionData;
if (vData.PrintPositionData == "4") // 왼쪽찍기
{
if (vData.ReelSize == eCartSize.Inch7)
{
vData.NeedCylinderForward = false;
double targerPos = 0.0;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = -90; //90도 회전한다
}
else
{
vData.PositionAngle = -90;
}
}
else
{
//13inch
vData.NeedCylinderForward = true;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = -180;
}
else
{
vData.PositionAngle = 0;
}
}
}
else if (vData.PrintPositionData == "6") //오른쪽찍기
{
if (vData.ReelSize == eCartSize.Inch7)
{
vData.NeedCylinderForward = false;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = 90; //90도 회전한다
}
else
{
vData.PositionAngle = 90; //90도 회전한다
}
}
else
{
//13inch
vData.NeedCylinderForward = true;
double targerPos = 0.0;
if (target == eWorkPort.Left) //left printer
{
vData.PositionAngle = 0;
}
else
{
vData.PositionAngle = 180;
}
}
}
else
{
vData.NeedCylinderForward = false; //상하에 붙이는건 실린더를 원위치해야함
vData.PositionAngle = 0;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 바코드에의한 자동 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var thpos = MOT.GetPTPos(ePTLoc.READY);
// Baseangle 값으로 변경 210126 - qr의 각도가잇다면 그것이 기준이됨
double baseAngle = 0;
string baseSource = "F";
var vdata = target == eWorkPort.Left ? PUB.Result.ItemDataL.VisionData : PUB.Result.ItemDataR.VisionData;
if (vdata.BaseAngle(out string msg, out Class.KeyenceBarcodeData bcd))
{
baseAngle = bcd.Angle;
baseSource = bcd.barcodeSource; //230504 각도
PUB.log.AddI($"[{target}] 각도산출내용:{msg},바코드:{bcd.Data},ID:{vdata.RID}"); //210602
}
else if (PUB.Result.DryRun)
{
PUB.log.AddAT($"[{target}] 드라이런으로 인해 각도를 적용하지 않음");
}
else
{
PUB.log.AddE($"[{target}] base ange error : {msg},ID:{vdata.RID}");
}
var addangle = baseSource == "R" ? SETTING.Data.RearBarcodeRotate : SETTING.Data.FrontBarcodeRotate;
var rotAngle = baseAngle + addangle + vdata.PositionAngle;
PUB.log.AddI($"[{target}]-소스:{baseSource} 회전값(Base:{baseAngle}+추가:{addangle}+비젼:{vdata.PositionAngle}={rotAngle})");
int dir = -1;
while (true)
{
if (rotAngle > 360.0)
rotAngle = rotAngle - 360.0; //한반퀴 더 도는것은 역 처리한다
else break;
}
//rotAngle += 90; //비젼이 90도 돌아가잇으니 다시 적용필요함 //상단이위로가도록 함
if (rotAngle > 180)
{
rotAngle = 360 - rotAngle;
dir = 1;
}
PUB.log.AddI($"[{target}] 회전(최종) [{rotAngle}도,방향:{dir}],RID:{vdata.RID}");
if (target == eWorkPort.Left)
PUB.Result.ItemDataL.VisionData.ApplyAngle = rotAngle; //회전각도를 넣는다
else
PUB.Result.ItemDataR.VisionData.ApplyAngle = rotAngle; //회전각도를 넣는다
var curtheta = PUB.mot.GetActPos((int)eAxis.Z_THETA);
var newPos = curtheta + (dir * rotAngle);
PUB.log.Add($"회전전 모터 위치 : {curtheta}, 대상위치:{newPos},속도:{thpos.Speed},가속:{thpos.Acc}");
if (target == eWorkPort.Left)
VAR.DBL[(int)eVarDBL.ThetaPositionL] = newPos;
else
VAR.DBL[(int)eVarDBL.ThetaPositionR] = newPos;
//if (ByPassMode == false)
//{
//바이패스에서도 추가 회전을 한다
MOT.Move(eAxis.Z_THETA, newPos, thpos.Speed, thpos.Acc, false);
//}
//else PUB.log.AddAT($"bypass 로 인해 회전을 하지 않습니다");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,244 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 키엔스가 실패했을때 재시도 하는 작업이다
/// 중앙에서 잡고 79도 틀고, 내려 놓고 피한다
/// </summary>
/// <param name="target"></param>
/// <param name="cmdIndex"></param>
/// <returns></returns>
public Boolean PICKER_RETRY(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 iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
var PickerRetryCount = AR.VAR.I32[(int)eVarInt32.PickOnRetry];
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] 피커 RETRY 작업시작({PickerRetryCount}/{AR.SETTING.Data.RetryPickOnMaxCount})");
//기존자료를 모두 삭제 한다 221102
if (PUB.Result.ItemDataC != null && PUB.Result.ItemDataC.VisionData != null && PUB.Result.ItemDataC.VisionData.barcodelist != null)
{
lock (PUB.Result.ItemDataC.VisionData.barcodelist)
{
PUB.Result.ItemDataC.VisionData.Clear(funcName, true);
}
}
AR.VAR.BOOL[eVarBool.JOB_PickON_Retry] = true;
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
PUB.sm.seq.Update(cmdIndex);
DIO.SetPickerVac(false);
return false;
}
//####################################################
//### Z를 먼저 Ready 로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### X를 픽온위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
var Pos = MOT.GetPXPos(ePXLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축 내리기 조건확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PortRDY = PUB.flag.get(eVarBool.FG_RDY_PORT_PC);
if (PortRDY == false) return false;
DIO.SetPickerVac(true);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.PICKON);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
VAR.I32[eVarInt32.PickOnCount] += 1;
//PUB.flag.set(eVarBool.PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 100ms 대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
//PUB.flag.set(eVarBool.PK_ITEMON, true, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 현재위치에서 79도 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = PUB.mot.GetActPos((int)eAxis.Z_THETA) + AR.SETTING.Data.RetryPickOnAngle;
VAR.DBL[(int)eVarDBL.ThetaPosition] = Pos.Position;
MOT.Move(Pos);
//if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 현재위치에서 79도 회전
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//속도값만 취한다
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = VAR.DBL[(int)eVarDBL.ThetaPosition];
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z를 pick on 위치로 1/3 지점으로 이동한다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var PosS = MOT.GetPZPos(ePZLoc.READY);
var PosT = MOT.GetPZPos(ePZLoc.PICKON);
var offset = (int)(Math.Abs(PosT.Position - PosS.Position) * 0.7f);
PosS.Position += offset; //시작위치에서 절반만 이동한다
if (MOT.CheckMotionPos(seqTime, PosS, funcName) == false) return false;
DIO.SetPickerVac(false); //릴을 내려 놓는다
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
DIO.SetPickerVac(false); //백큠을 꺼서 원복한다
hmi1.arVar_Port[1].AlignReset(); //231013
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 키엔스를 읽어야 하므로 피해준다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
sPositionData Pos;
if (target == eWorkPort.Left) Pos = MOT.GetPXPos(ePXLoc.READYL);
else Pos = MOT.GetPXPos(ePXLoc.READYR);
//theta모터 위치 초기화
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.log.AddAT($"###### 재시도 작업 회피 이동 완료({target})");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 비젼데이터를 초기화 해준다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"retry 완료로 비젼데이터를 삭제 합니다");
PUB.Result.ItemDataC.VisionData.Clear(funcName, true);
AR.VAR.BOOL[eVarBool.JOB_PickON_Retry] = false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//일련번호 초기화 해준다
PUB.sm.seq.Clear(cmdIndex);
return true;
}
}
}

View File

@@ -0,0 +1,458 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PICKER_OFF(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 ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = PUB.OPT_BYPASS();
var iLockX = PUB.iLock[(int)eAxis.PX_PICK];
var iLockZ = PUB.iLock[(int)eAxis.PZ_PICK];
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveX = PUB.mot.IsMotion((int)eAxis.PX_PICK);
Boolean MotMoveZ = PUB.mot.IsMotion((int)eAxis.PZ_PICK);
if (iLockX.IsEmpty() == false && MotMoveX)
{
var locklistX = MOT.GetActiveLockList(eAxis.PX_PICK, iLockX);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)eAxis.PX_PICK);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(eAxis.PZ_PICK, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)eAxis.PZ_PICK);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//컨베이어모드에서는 센서가 감지되면 내려놓지 않게 한다
if (CVMode)
{
if (target == eWorkPort.Left)
{
if (DIO.GetIOInput(eDIName.L_CONV1)) return false;
if (VAR.I32[eVarInt32.LEFT_ITEM_COUNT] > 0) return false;
}
else if (target == eWorkPort.Right)
{
if (DIO.GetIOInput(eDIName.R_CONV1)) return false;
if (VAR.I32[eVarInt32.RIGT_ITEM_COUNT] > 0) return false;
}
PUB.log.Add($"CVMODE에서 컨베이어 비어있음");
}
PUB.log.Add($"[{target}] 피커 OFF 작업시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Y축안전확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//PUB.log.Add($"[{target}] 프린터 Y축 위치 확인");
var Pos = target == eWorkPort.Left ? MOT.GetLMPos(eLMLoc.READY) : MOT.GetRMPos(eRMLoc.READY);
if (MOT.getPositionMatch(Pos) == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.POSITION_ERROR, eNextStep.PAUSE, "프린터 Y축이 준비위치에 있지 않습니다");
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### OFF 위치로 이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockX.IsEmpty() == false) return false;
sPositionData PosX;
if (PUB.flag.get(eVarBool.FG_RUN_LEFT))
{
PosX = MOT.GetPXPos(ePXLoc.PICKOFFL);
}
else
{
PosX = MOT.GetPXPos(ePXLoc.PICKOFFR);
}
if (MOT.CheckMotionPos(seqTime, PosX, funcName) == false) return false;
//컨베이어모드라면 컨베이어를 멈추게한다
if (CVMode)
{
if (target == eWorkPort.Left)
PUB.iLockCVL.set((int)eILockCV.BUSY, true, funcName);
else
PUB.iLockCVR.set((int)eILockCV.BUSY, true, funcName);
}
else
{
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;
}
////####################################################
////### 프린트부착위치가 상/하가 아니라면 추가적인 회전이 필요하다 - 210207
////####################################################
//if (PUB.sm.seq.Get(cmdIndex) == idx++)
//{
// var vData = item.VisionData;
// if (vData.PrintPositionData == "4") // 왼쪽찍기
// {
// if (vData.ReelSize == eCartSize.Inch7)
// {
// vData.NeedCylinderForward = false;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 90; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 90;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// else
// {
// //13inch
// vData.NeedCylinderForward = true;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 180; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 0;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// }
// else if (vData.PrintPositionData == "6") //오른쪽찍기
// {
// if (vData.ReelSize == eCartSize.Inch7)
// {
// vData.NeedCylinderForward = false;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle - 90; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle - 90;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// else
// {
// //13inch
// vData.NeedCylinderForward = true;
// double targerPos = 0.0;
// if (target == eWorkShuttle.Left) //left printer
// {
// targerPos = vData.ApplyAngle + 0; //90도 회전한다
// }
// else
// {
// targerPos = vData.ApplyAngle + 180;
// }
// //if (vData.ApplyAngle > 180.0) targerPos = vData.ApplyAngle - 180.0;
// //else targerPos = vData.ApplyAngle + 180.0;
// //추가보정
// if (targerPos > 360.0) targerPos = targerPos - 360.0;
// if (targerPos < -360.0) targerPos = targerPos + 360.0;
// //지정값대로 추가 회전을 한다
// var basePosInfo = MOT.GetPTPos(ePTLoc.READY);
// basePosInfo.Position = targerPos;
// if (MOT.CheckMotionPos(seqTime, basePosInfo, funcName) == false) return false;
// }
// }
// else vData.NeedCylinderForward = false; //상하에 붙이는건 실린더를 원위치해야함
// PUB.sm.seq.Update(cmdIndex);
// return false;
//}
//####################################################
//### 사용자회전적용
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (item.VisionData.ApplyOffset == false)
{
//적용옵셋
var OffsetAngle = target == eWorkPort.Left ? AR.SETTING.Data.AngleOffsetL : AR.SETTING.Data.AngleOffsetR;
if (OffsetAngle != 0f)
{
if (OPT_BYPASS == true || OPT_PrinterOff)
{
PUB.log.AddAT($"bypass 로 인해 추가 회전을 하지 않습니다");
}
else
{
//모터회전
//var thpos = MOT.GetPTPos(ePTLoc.READY); //적용할 속도값용
//MOT.Move(eAxis.Z_THETA, OffsetAngle, thpos.Speed, thpos.Acc, true);
MOT.Rotation(OffsetAngle, funcName);
double theta = 0;
if (target == eWorkPort.Left) theta = VAR.DBL[(int)eVarDBL.ThetaPositionL];
else theta = VAR.DBL[(int)eVarDBL.ThetaPositionR];
//값을 누적시켜준다
item.VisionData.ApplyAngle += OffsetAngle;
if (target == eWorkPort.Left) VAR.DBL[(int)eVarDBL.ThetaPositionL] = theta + OffsetAngle;
else VAR.DBL[(int)eVarDBL.ThetaPositionR] = theta + OffsetAngle;
if (AR.SETTING.Data.Log_Debug)
PUB.logDbg.Add($"[{target}] 모션 추가회전 :{OffsetAngle}");
}
}
item.VisionData.ApplyOffset = true;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 회전축 완료 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_BYPASS == false && OPT_PrinterOff == false)
{
var Theta = target == eWorkPort.Left ? VAR.DBL[(int)eVarDBL.ThetaPositionL] : VAR.DBL[(int)eVarDBL.ThetaPositionR];
var Pos = MOT.GetPTPos(ePTLoc.READY);
Pos.Position = Theta;
if (MOT.CheckMotionPos(seqTime, Pos, funcName, false) == false) return false;
PUB.log.Add($"[{target}] 회전축 확인 완료 위치:{Theta},모터값:{PUB.mot.GetActPos((int)eAxis.Z_THETA)} => 위치초기화함");
PUB.mot.ClearPosition((int)eAxis.Z_THETA);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 포트상태확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var PortRDY = target == eWorkPort.Left ? PUB.flag.get(eVarBool.FG_RDY_PORT_PL) : PUB.flag.get(eVarBool.FG_RDY_PORT_PR);
if (PortRDY == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
//컨베어모드라면 센서에 감지되는 것이 없어야 한다
if (OPT_BYPASS == false && VAR.BOOL[eVarBool.Use_Conveyor])
{
if (target == eWorkPort.Left)
{
//컨베이어가 움직이고 있다면 단순 대기한다
if (DIO.GetIOOutput(eDOName.LEFT_CONV) == false)
{
//놓일위치에서 센서가 감지되었다
if (DIO.GetIOInput(eDIName.L_CONV1))
{
var ssname = $"X{eDIName.L_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_REEL_DECTECT_IN, eNextStep.PAUSE, ssname);
return false;
}
}
else
{
if (seqTime.TotalSeconds > 10)
{
var ssname = $"Y{eDOName.LEFT_CONV}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.LCONVER_MOVING, eNextStep.PAUSE, ssname);
}
return false;
}
}
else
{
//컨베이어가 움직이고 있다면 단순 대기한다
if (DIO.GetIOOutput(eDOName.RIGHT_CONV) == false)
{
//놓일위치에서 센서가 감지되었다
if (DIO.GetIOInput(eDIName.R_CONV1))
{
var ssname = $"X{eDIName.R_CONV1}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_REEL_DECTECT_IN, eNextStep.PAUSE, ssname);
return false;
}
}
else
{
if (seqTime.TotalSeconds > 10)
{
var ssname = $"Y{eDOName.RIGHT_CONV}";
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.RCONVER_MOVING, eNextStep.PAUSE, ssname);
}
return false;
}
}
}
var fg = target == eWorkPort.Left ? eVarBool.FG_RUN_LEFT : eVarBool.FG_RUN_RIGHT;
var Loc = target == eWorkPort.Left ? ePZLoc.PICKOFFL : ePZLoc.PICKOFFR;
var Pos = MOT.GetPZPos(Loc);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 진공파기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
DIO.SetPickerVac(false);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z축을 올린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
// if (iLockX.IsEmpty() == false) return false;
if (iLockZ.IsEmpty() == false) return false;
var Pos = MOT.GetPZPos(ePZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
PUB.flag.set(eVarBool.FG_PK_ITEMON, false, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
IncCount(1, 1);
if (target == eWorkPort.Left)
{
if (AR.SETTING.Data.Disable_PortL == false && AR.SETTING.Data.Disable_Left == false)
{
hmi1.arVar_Port[0].AlignReset();
}
}
else
{
if (AR.SETTING.Data.Disable_PortR == false && AR.SETTING.Data.Disable_Right == false)
{
hmi1.arVar_Port[2].AlignReset();
}
}
VAR.I32[eVarInt32.PickOfCount] += 1;
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,247 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER(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 Printer = target == eWorkPort.Left ? PUB.PrinterL : PUB.PrinterR;
//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(target);
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] 프린트 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린트 모션 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
sPositionData PosY, PosZ;
if (target == eWorkPort.Left)
{
PosY = MOT.GetLMPos(eLMLoc.READY);
PosZ = MOT.GetLZPos(eLZLoc.PICKON);
}
else
{
PosY = MOT.GetRMPos(eRMLoc.READY);
PosZ = MOT.GetRZPos(eRZLoc.PICKON);
}
if (MOT.CheckMotionPos(seqTime, PosY, funcName) == false) return false;
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 인쇄데이터 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (item.VisionData.RID.isEmpty())
{
if (target == eWorkPort.Left)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPRINTLDATA, eNextStep.PAUSE);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPRINTRDATA, eNextStep.PAUSE);
}
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 인쇄데이터전송
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
string zpl, qrdata;
zpl = Printer.makeZPL_210908(new Class.Reel
{
sid = item.VisionData.SID,
lot = item.VisionData.VLOT,
manu = item.VisionData.VNAME,
qty = item.VisionData.QTY.isEmpty() ? -1 : int.Parse(item.VisionData.QTY),
id = item.VisionData.RID,
mfg = item.VisionData.MFGDATE,
partnum = item.VisionData.PARTNO,
}, AR.SETTING.Data.DrawOutbox, out qrdata);
item.VisionData.ZPL = zpl;
item.VisionData.PrintQRData = qrdata;
PUB.log.Add("PRINT", $"[{target}] 프린트");//QR=" + item.VisionData.QRData);
if (target == eWorkPort.Left)
{
var prn = Printer.Print(zpl);
//PUB.PrintSend(true, zpl); //PUB.PrintL.Write(zpl);
if (prn == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTL, eNextStep.ERROR);
return false;
}
else
{
PUB.counter.CountPrintL += 1;
item.PrintTime = DateTime.Now;
}
}
else
{
var prn = Printer.Print(zpl);
//PUB.PrintSend(false, zpl); //PUB.PrintR.Write(zpl);
if (prn == false)
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.PRINTR, eNextStep.ERROR);
return false;
}
else
{
PUB.counter.CountPrintR += 1;
item.PrintTime = DateTime.Now;
}
}
}
else PUB.log.AddAT($"[{target}] 프린터 기능 OFF(bypass or model or setting)");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var WaitMS = target == eWorkPort.Left ? AR.SETTING.Data.PrintLWaitMS : AR.SETTING.Data.PrintRWaitMS;
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < WaitMS) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 위쪽흡기 ON
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLVac(ePrintVac.inhalation);
}
else
{
DIO.SetPrintRVac(ePrintVac.inhalation);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 아래쪽 블로우
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && SETTING.Data.Disable_BottomAirBlow == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLAir(true);
}
else
{
DIO.SetPrintRAir(true);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && seqTime.TotalMilliseconds < 100) return false;
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 장비기술데이터저장
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"6.PRINT : EE-SAVE");
SaveData_EE(item, (target == eWorkPort.Left ? "L" : "R"), "","printer");
//RefreshList(); //목록업데이트
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### spare
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,224 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER_ON(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 Printer = target == eWorkPort.Left ? PUB.PrinterL : PUB.PrinterR;
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
//var ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = PUB.OPT_BYPASS();
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveM, MotMoveZ;
AR.CInterLock iLockM, iLockZ;
eAxis axisM = target == eWorkPort.Left ? eAxis.PL_MOVE : eAxis.PR_MOVE;
eAxis axisZ = target == eWorkPort.Left ? eAxis.PL_UPDN : eAxis.PR_UPDN;
if (target == eWorkPort.Left)
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PL_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PL_UPDN);
iLockM = PUB.iLock[(int)eAxis.PL_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PL_UPDN];
}
else
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PR_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PR_UPDN);
iLockM = PUB.iLock[(int)eAxis.PR_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PR_UPDN];
}
if (iLockM.IsEmpty() == false && MotMoveM)
{
var locklistX = MOT.GetActiveLockList(axisM, iLockM);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)axisM);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(axisZ, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)axisZ);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"[{target}] 프린트 ON 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 종이감지확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var = target == eWorkPort.Left ? eDIName.L_PICK_VAC : eDIName.R_PICK_VAC;
var = target == eWorkPort.Left ? AR.SETTING.Data.Detect_PrintL : AR.SETTING.Data.Detect_PrintR;
if (OPT_PrinterOff == false)
{
if ( == false)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.log.AddAT($"[{target}] 용지감지기능 OFF(3초후 진행)");
}
else
{
var ioresult = DIO.checkDigitalO(, seqTime, true, 0, false);
if (ioresult == eNormalResult.Error)
{
var errCode = target == eWorkPort.Left ? eECode.NO_PAPER_DETECT_L : eECode.NO_PAPER_DETECT_R;
PUB.Result.SetResultMessage(eResult.HARDWARE, errCode, eNextStep.PAUSE, );
return false;
}
else if (ioresult == eNormalResult.False) return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z올리기(slow)
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_BYPASS == false)
{
if (seqTime.TotalMilliseconds < 3000) return false;
sPositionData PosZ;
if (target == eWorkPort.Left)
{
PosZ = MOT.GetLZPos(eLZLoc.PICKON);
}
else
{
PosZ = MOT.GetRZPos(eRZLoc.PICKON);
}
PosZ.Position -= 10;
if (PosZ.Position < 1) PosZ.Position = 1;
PosZ.Speed = 5;
if (MOT.CheckMotionPos(seqTime, PosZ, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 종이감지확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var = target == eWorkPort.Left ? eDIName.L_PICK_VAC : eDIName.R_PICK_VAC;
var = target == eWorkPort.Left ? AR.SETTING.Data.Detect_PrintL : AR.SETTING.Data.Detect_PrintR;
if ( == false)
{
if (seqTime.TotalMilliseconds < 100) return false;
PUB.log.AddAT($"[{target}] 용지감지기능 OFF(3초후 진행)");
}
else
{
var ioresult = DIO.checkDigitalO(, seqTime, true, 0, false);
if (ioresult == eNormalResult.Error)
{
var errCode = target == eWorkPort.Left ? eECode.NO_PAPER_DETECT_L : eECode.NO_PAPER_DETECT_R;
PUB.Result.SetResultMessage(eResult.HARDWARE, errCode, eNextStep.PAUSE, );
return false;
}
else if (ioresult == eNormalResult.False) return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z올리기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_BYPASS == false)
{
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;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//air off
if (target == eWorkPort.Left)
{
DIO.SetPrintLAir(false);
if (OPT_BYPASS == false)
VAR.I32[eVarInt32.LPickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PL_ITEMON, true, funcName);
}
else
{
DIO.SetPrintRAir(false);
if (OPT_BYPASS == false)
VAR.I32[eVarInt32.RPickOnCount] += 1;
PUB.flag.set(eVarBool.FG_PR_ITEMON, true, funcName);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,574 @@

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean PRINTER_OFF(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 CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
var OPT_CameraOff = PUB.OPT_CAMERA(target);
//var OPT_BYPASS = PUB.OPT_BYPASS(target);
//####################################################
//### 인터락 확인
//####################################################
Boolean MotMoveM, MotMoveZ;
AR.CInterLock iLockM, iLockZ;
eAxis axisM = target == eWorkPort.Left ? eAxis.PL_MOVE : eAxis.PR_MOVE;
eAxis axisZ = target == eWorkPort.Left ? eAxis.PL_UPDN : eAxis.PR_UPDN;
if (target == eWorkPort.Left)
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PL_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PL_UPDN);
iLockM = PUB.iLock[(int)eAxis.PL_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PL_UPDN];
}
else
{
MotMoveM = PUB.mot.IsMotion((int)eAxis.PR_MOVE);
MotMoveZ = PUB.mot.IsMotion((int)eAxis.PR_UPDN);
iLockM = PUB.iLock[(int)eAxis.PR_MOVE];
iLockZ = PUB.iLock[(int)eAxis.PR_UPDN];
}
if (iLockM.IsEmpty() == false && MotMoveM)
{
var locklistX = MOT.GetActiveLockList(axisM, iLockM);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistX) + ")", (int)axisM);
}
if (iLockZ.IsEmpty() == false && MotMoveZ)
{
var locklistZ = MOT.GetActiveLockList(axisZ, iLockZ);
PUB.mot.MoveStop("ILock(" + string.Join(",", locklistZ) + ")", (int)axisZ);
}
//####################################################
//### 작업시작
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 피커Y축 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
var PosX = MOT.GetPXPos(ePXLoc.PICKON);
var OffX = MOT.getPositionOffset(PosX);
if (target == eWorkPort.Left)
{
if (OffX < -1) return false; //충돌조건이므로 Y축을 움직이면 안된다
}
else
{
if (OffX > 1) return false;//충돌조건이므로 Y축을 움직이면 안된다
}
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 프린터Z축 위치 확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
sPositionData Pos;
if (target == eWorkPort.Left)
{
Pos = MOT.GetLZPos(eLZLoc.READY);
}
else
{
Pos = MOT.GetRZPos(eRZLoc.READY);
}
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
//PUB.log.Add($"[{target}] 프린트 OFF 작업 시작");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Y이동
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
sPositionData Pos;
if (OPT_PrinterOff == false)
{
//릴크기없으면 오류
var reelSize = item.VisionData.ReelSize;
if (reelSize == eCartSize.None)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOREELSIZE, eNextStep.PAUSE, target);
return false;
}
//부착위치
var PrintPutPos = item.VisionData.GetPrintPutPosition();
if (PrintPutPos == ePrintPutPos.None)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.NOPUTPOSITION, eNextStep.PAUSE, target);
return false;
}
if (target == eWorkPort.Left)
{
//위에 찍을지 아래에 찍을지 위치를 결정한다
if (reelSize == eCartSize.Inch13)
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetLMPos(eLMLoc.PRINTM13);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetLMPos(eLMLoc.PRINTL13);
else Pos = MOT.GetLMPos(eLMLoc.PRINTH13);
}
else
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetLMPos(eLMLoc.PRINTM07);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetLMPos(eLMLoc.PRINTL07);
else Pos = MOT.GetLMPos(eLMLoc.PRINTH07);
}
}
else //Right Move
{
//위에 찍을지 아래에 찍을지 위치를 결정한다
if (reelSize == eCartSize.Inch13)
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetRMPos(eRMLoc.PRINTM13);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetRMPos(eRMLoc.PRINTL13);
else Pos = MOT.GetRMPos(eRMLoc.PRINTH13);
}
else
{
if (PrintPutPos == ePrintPutPos.Middle) Pos = MOT.GetRMPos(eRMLoc.PRINTM07);
else if (PrintPutPos == ePrintPutPos.Bottom) Pos = MOT.GetRMPos(eRMLoc.PRINTL07);
else Pos = MOT.GetRMPos(eRMLoc.PRINTH07);
}
}
if (iLockM.IsEmpty() == false) return false;
//if (iLockZ.IsEmpty() == false) return false;
//위치오류확인
if (Pos.isError == false)
{
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.POSITION_ERROR, eNextStep.PAUSE, "PRINTPOS");
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더 전/후진 상태를 전환한다 -- 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var Cylinder = item.VisionData.NeedCylinderForward;
if (Cylinder == true)
{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.PRINTL_FWD, true);
else
DIO.SetOutput(eDOName.PRINTR_FWD, true);
}
else
{
//전진이 필요하지 않다.
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.PRINTL_FWD, false);
else
DIO.SetOutput(eDOName.PRINTR_FWD, false);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트모드에서는 추가 실린더 down 해야한다 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (SETTING.Data.Enable_PickerCylinder)
{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, true);
else
DIO.SetOutput(eDOName.R_CYLDN, true);
}
else
{
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, false);
else
DIO.SetOutput(eDOName.R_CYLDN, false);
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트상태확인
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
eVarBool fg = target == eWorkPort.Left ? eVarBool.FG_RDY_PORT_PL : eVarBool.FG_RDY_PORT_PR;
if (PUB.flag.get(fg) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더상태확인 -- 210207
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
var Cylinder = item.VisionData.NeedCylinderForward;
if (Cylinder == true)
{
//전진이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_PICK_FW, seqTime, true) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_PICK_FW, seqTime, true) != eNormalResult.True)
return false;
}
}
else
{
//전진이 필요하지 않다.
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;
}
//####################################################
//### 피커 down 실린더상태확인 -- 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false && SETTING.Data.Enable_PickerCylinder)
{
//전진이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_CYLDN, seqTime, true, timeoutcode: eECode.PICKER_LCYL_NODOWN) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_CYLDN, seqTime, true, timeoutcode: eECode.PICKER_RCYL_NODOWN) != eNormalResult.True)
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z값을 내린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.PICKOFF);
else
Pos = MOT.GetRZPos(eRZLoc.PICKOFF);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 진공파기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
DIO.SetPrintLVac(ePrintVac.exhaust);
}
else
{
DIO.SetPrintRVac(ePrintVac.exhaust);
}
}
if (target == eWorkPort.Left)
{
VAR.BOOL[eVarBool.LEFT_ITEM_PICKOFF] = true;
VAR.TIME[eVarTime.LEFT_ITEM_PICKOFF] = DateTime.Now;
VAR.DBL[eVarDBL.LEFT_ITEM_PICKOFF] = 0;
VAR.I32[eVarInt32.LEFT_ITEM_COUNT] += 1;
}
else
{
VAR.BOOL[eVarBool.RIGT_ITEM_PICKOFF] = true;
VAR.TIME[eVarTime.RIGT_ITEM_PICKOFF] = DateTime.Now;
VAR.DBL[eVarDBL.RIGT_ITEM_PICKOFF] = 0;
VAR.I32[eVarInt32.RIGT_ITEM_COUNT] += 1;
}
PUB.log.Add($"[{target}] 릴을 내려놓습니다");
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 잠시대기
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (seqTime.TotalMilliseconds < AR.SETTING.Data.PrintVacOffPurgeMS) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 저속으로올린다
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.PICKOFF);
else
Pos = MOT.GetRZPos(eRZLoc.PICKOFF);
Pos.Position -= 30;
Pos.Speed = 30;
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 카트모드에서는 추가 실린더 down 해야한다 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//if (ByPassMode == false)
//{
// if (CVMode == false)
//{
//전진이 필요하다
if (target == eWorkPort.Left)
DIO.SetOutput(eDOName.L_CYLDN, false);
else
DIO.SetOutput(eDOName.R_CYLDN, false);
//}
// }
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### Z값 대기위치로
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (iLockZ.IsEmpty() == false) return false;
if (OPT_PrinterOff == false)
{
sPositionData Pos;
if (target == eWorkPort.Left)
Pos = MOT.GetLZPos(eLZLoc.READY);
else
Pos = MOT.GetRZPos(eRZLoc.READY);
if (MOT.CheckMotionPos(seqTime, Pos, funcName) == false) return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### AIR해제
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (target == eWorkPort.Left)
DIO.SetPrintLVac(ePrintVac.off);
else
DIO.SetPrintRVac(ePrintVac.off);
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 실린더 복귀 확인 -- 230809
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (SETTING.Data.Enable_PickerCylinder)
{
//상승이 필요하다
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_LCYL_NOUP) != eNormalResult.True)
return false;
}
else
{
if (DIO.checkDigitalO(eDIName.R_CYLUP, seqTime, true, timeoutcode: eECode.PICKER_RCYL_NOUP) != eNormalResult.True)
return false;
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (OPT_PrinterOff == false)
{
if (target == eWorkPort.Left)
{
if (DIO.checkDigitalO(eDIName.L_PICK_VAC, seqTime, false) != eNormalResult.True) return false;
VAR.I32[eVarInt32.LPickOfCount] += 1;
}
else
{
if (DIO.checkDigitalO(eDIName.R_PICK_VAC, seqTime, false) != eNormalResult.True) return false;
VAR.I32[eVarInt32.RPickOfCount] += 1;
}
//PUB.log.AddAT($"용지 떨어짐 확인 필요");
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
if (target == eWorkPort.Left)
{
PUB.flag.set(eVarBool.FG_PL_ITEMON, false, funcName);
}
else
{
PUB.flag.set(eVarBool.FG_PR_ITEMON, false, funcName);
}
//프린터 사용여부 확인
if (OPT_PrinterOff == false)
{
item.PrintAttach = true;
item.Attachtime = DateTime.Now;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,146 @@
using AR;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
delegate void savedataeehandler(Class.JobData item, string Loc, string inboundok, string reason);
public void SaveData_EE(Class.JobData item, string Loc, string inboundok, string reason)
{
if (this.InvokeRequired)
{
//이자료를 복사해서 데이터를 넘겨줘야한다.
var a = new Class.JobData(999);
item.CopyTo(ref a);
this.BeginInvoke(new savedataeehandler(SaveData_EE), a, Loc, inboundok, reason);
return;
}
var retval = false;
if (AR.SETTING.Data.OnlineMode == false)
{
PUB.log.AddAT($"[SAVE-EE] 오프라인으로 저장 하지 않음");
return;
}
DateTime savestart = DateTime.Now;
try
{
var save_month = DateTime.Now.ToString("YY") + DateTime.Now.Month.ToString("X");
var save_sn = string.Empty;
if (item.VisionData.RID.Length == 15)
{
save_month = item.VisionData.RID.Substring(8, 3); //21A 식으로 년도와 월이 나온다
save_sn = item.VisionData.RID.Substring(item.VisionData.RID.Length - 4); //뒷에서 4자리 끊는다
}
//var Jobtype = VAR.STR[eVarString.JOB_TYPE];
//var ByPassMode = Jobtype == "BP";
var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];
//option check
//var OPT_PrinterOff = PUB.OPT_PRINTEROFF(target);
//var OPT_CameraOff = PUB.OPT_CAMERA(target);
var OPT_BYPASS = SETTING.Data.SystemBypass;// PUB.OPT_BYPASS(target);
using (var taResult = new DataSet1TableAdapters.Component_Reel_ResultTableAdapter())
{
//QTY 0값은 없을 수도있다(해당 값은 서버조회여부에다라 다르다)
int? qtyorg = null;
if (int.TryParse(item.VisionData.QTY0, out int vqty0))
qtyorg = vqty0;
string remark = string.Empty;
if (item.VisionData.ConfirmAuto) remark = "[자동]" + remark; //자동확인문구
else if (item.VisionData.ConfirmUser) remark = "[확인]" + remark; //사용자 확인데이터 비고에 추가
if (OPT_BYPASS) remark = "(BYPASS)" + remark;
DataSet1.Component_Reel_ResultRow newdr = this.dataSet1.Component_Reel_Result.Where(t => t.JGUID.Equals(item.guid)).FirstOrDefault();
if (newdr == null) newdr = this.dataSet1.Component_Reel_Result.NewComponent_Reel_ResultRow();
//else newdr = dt.Rows[0] as DataSet1.Component_Reel_ResultRow;
if (item.JobStart.Year != 1982) newdr.STIME = item.JobStart;
else newdr.STIME = DateTime.Now;
if (item.JobEnd.Year != 1982) newdr.ETIME = item.JobEnd;
if (item.PrintTime.Year != 1982) newdr.PTIME = item.PrintTime;
newdr.ATIME = item.Attachtime;
newdr.PDATE = save_month;
newdr.JTYPE = PUB.Result.vModel.Title;// PUB.Result.JobType2;
if (newdr.JTYPE.Length > 10) newdr.JTYPE = newdr.JTYPE.Substring(0, 9);
newdr.SID = item.VisionData.SID;
newdr.SID0 = item.VisionData.SID0;
newdr.RID = item.VisionData.RID;
newdr.RID0 = item.VisionData.RID0;
newdr.RSN = save_sn;
newdr.QR = item.VisionData.PrintQRData;
newdr.ZPL = item.VisionData.ZPL;
newdr.POS = item.VisionData.PrintPositionData;
newdr.LOC = Loc;
newdr.ANGLE = item.VisionData.ApplyAngle;
if (int.TryParse(item.VisionData.QTY, out int oqty))
newdr.QTY = oqty;
else
newdr.QTY = 0;
newdr.MFGDATE = item.VisionData.MFGDATE;//210326 날짜도 추가함
if (qtyorg != null) newdr.QTY0 = (int)qtyorg;
newdr.VNAME = item.VisionData.VNAME;
newdr.VLOT = item.VisionData.VLOT; ///210326
newdr.PRNATTACH = item.PrintAttach;
newdr.PRNVALID = item.PrintQRValid;
newdr.REMARK = remark;
if (inboundok.isEmpty() == false) newdr.iNBOUND = inboundok;//230622
newdr.MC = AR.SETTING.Data.McName;
newdr.PARTNO = item.VisionData.PARTNO;
newdr.CUSTCODE = item.VisionData.CUSTCODE;
newdr.MCN = item.VisionData.MCN;
newdr.target = item.VisionData.Target;
//220921 - batch qtymax
newdr.BATCH = item.VisionData.BATCH;
if (int.TryParse(item.VisionData.QTYMAX, out int qtymax))
newdr.qtymax = qtymax;
else newdr.qtymax = -1;
//new mode
if (newdr.RowState == System.Data.DataRowState.Detached)
{
newdr.GUID = PUB.Result.guid; //220921
newdr.JGUID = item.guid;
newdr.wdate = DateTime.Now;
this.dataSet1.Component_Reel_Result.AddComponent_Reel_ResultRow(newdr);
}
else newdr.EndEdit();
var cnt = ta.Update(newdr);
newdr.AcceptChanges();
if (cnt == 0) PUB.log.AddE("Save Error");
}
retval = true;
}
catch (Exception ex)
{
PUB.log.AddE($"[EE-SAVE] {ex.Message}");
retval = false;
}
var ts = DateTime.Now - savestart;
PUB.log.AddI($"data save time : {ts.TotalSeconds:N2}");
ListFormmatData();
}
}
}

View File

@@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
public Boolean QR_VALIDATION(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 WS = target == eWorkPort.Left ? PUB.wsL : PUB.wsR;
//####################################################
//### 작업시작
//####################################################
var CIDX = PUB.sm.seq.Get(cmdIndex);
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//작업 플래그 설정
if (target == eWorkPort.Left)
{
VAR.BOOL[eVarBool.VisionL_Retry] = false;
PUB.flag.set(eVarBool.FG_END_VISIONL, false, funcName);
PUB.flag.set(eVarBool.FG_PRC_VISIONL, true, funcName);
//PUB.iLockCVL.set((int)eILockCV.VISION, true, funcName);
}
else
{
VAR.BOOL[eVarBool.VisionR_Retry] = false;
PUB.flag.set(eVarBool.FG_END_VISIONR, false, funcName);
PUB.flag.set(eVarBool.FG_PRC_VISIONR, true, funcName);
//PUB.iLockCVR.set((int)eILockCV.VISION, true, funcName);
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//카메라 트리거 전송
var sendok = WS_Send(target, WS, item.guid, "TRIG", item.VisionData.PrintQRData);
PUB.log.Add($"바코드트리거전송({target}) = {sendok}");
if(sendok==false) //230512 전송실패시 오류로 한다
{
PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.VISION_TRIGERROR, eNextStep.PAUSE);
return false;
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//### 수신된 바코드 값을 기다린다.
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
//타임아웃시간을 넘어서면 오류처리한다
if (seqTime.TotalMilliseconds >= AR.SETTING.Data.Timeout_VisionProcessU)
{
//
if (target == eWorkPort.Left)
{
if (VAR.BOOL[eVarBool.VisionL_Retry] == false)
{
PUB.log.AddAT("비젼(L) 1회 실패로 재 시도 합니다");
VAR.BOOL[eVarBool.VisionL_Retry] = true;
PUB.sm.seq.Update(cmdIndex, -1);
return false;
}
if (item.VisionData.RID2.isEmpty() == false && item.VisionData.MatchValidation == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.QRDATAMISSMATCHL, eNextStep.PAUSE, target, item.VisionData.RID, item.VisionData.RID2);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.VISION_NORECV, eNextStep.PAUSE, target);
}
}
else
{
if (VAR.BOOL[eVarBool.VisionR_Retry] == false)
{
PUB.log.AddAT("비젼(R) 1회 실패로 재 시도 합니다");
VAR.BOOL[eVarBool.VisionR_Retry] = true;
PUB.sm.seq.Update(cmdIndex, -1);
return false;
}
if (item.VisionData.RID2.isEmpty() == false && item.VisionData.MatchValidation == false)
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.QRDATAMISSMATCHR, eNextStep.PAUSE, target, item.VisionData.RID, item.VisionData.RID2);
}
else
{
PUB.Result.SetResultMessage(eResult.OPERATION, eECode.VISION_NORECV, eNextStep.PAUSE, target);
}
}
PUB.sm.seq.Update(cmdIndex, -1); // 재시작시 트리거 전송할 수 있게 위로 옮김
return false;
}
else
{
//타임아웃되지 않은 조건
if (target == eWorkPort.Left)
{
if (PUB.flag.get(eVarBool.FG_END_VISIONL)) //종료신호가 설정되어있다면 완료된 경우다
{
PUB.log.AddI($"{target} 비젼 종료 신호로 인해 완료 처리 합니다");
item.PrintQRValid = true;
}
else if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false) //사용자가 취소했다면 넘어간다
{
PUB.log.AddAT($"{target} 사용자 취소로 QR검증을 넘김");
item.PrintQRValid = false;
}
else return false; //아직 완료전이므로 리턴한다
}
else
{
if (PUB.flag.get(eVarBool.FG_END_VISIONR))
{
PUB.log.AddI($"{target} 비젼 종료 신호로 인해 완료 처리 합니다");
item.PrintQRValid = true;
}
else if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false) //사용자가 취소했다면 넘어간다
{
PUB.log.AddAT($"{target} 사용자 취소로 QR검증을 넘김");
item.PrintQRValid = false;
}
else return false; //아직 완료전이므로 리턴한다
}
}
PUB.sm.seq.Update(cmdIndex);
return false;
}
//####################################################
//###
//####################################################
if (PUB.sm.seq.Get(cmdIndex) == idx++)
{
PUB.log.Add($"{target} 비젼 검증 완료(결과:{item.PrintQRValid})");
if (target == eWorkPort.Left)
PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, funcName);
else
PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, funcName);
PUB.sm.seq.Update(cmdIndex);
return false;
}
return true;
}
}
}

View File

@@ -0,0 +1,324 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
/// <summary>
/// 로더용 포트 조작
/// </summary>
/// <param name="idx"></param>
/// <param name="isFirst"></param>
/// <param name="StepTime"></param>
void _SM_RUN_MOT_PORT(int idx, Boolean isFirst, TimeSpan StepTime)
{
//포트 비활성 체크
eVarBool FG_RDY_PORT;
eDIName DI_LIMUP, DI_DETUP;
eDOName DO_PORTRUN;
Boolean PORT_DISABLE;
//인덱스에 맞는 플래그와 DI값 설정
if (idx == 0)
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortL || AR.SETTING.Data.Disable_Left;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PL; DI_DETUP = eDIName.PORTL_DET_UP;
DI_LIMUP = eDIName.PORTL_LIM_UP; DO_PORTRUN = eDOName.PORTL_MOT_RUN;
}
else if (idx == 1)
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortC;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PC; DI_DETUP = eDIName.PORTC_DET_UP;
DI_LIMUP = eDIName.PORTC_LIM_UP; DO_PORTRUN = eDOName.PORTC_MOT_RUN;
}
else
{
PORT_DISABLE = AR.SETTING.Data.Disable_PortR || AR.SETTING.Data.Disable_Right;
FG_RDY_PORT = eVarBool.FG_RDY_PORT_PR; DI_DETUP = eDIName.PORTR_DET_UP;
DI_LIMUP = eDIName.PORTR_LIM_UP; DO_PORTRUN = eDOName.PORTR_MOT_RUN;
}
//포트가 비활성화되어있다면 DETECT ON하고 , LIMIT는 해제한다 -201224
if (PORT_DISABLE)
{
if (PUB.flag.get(FG_RDY_PORT) == false)
PUB.flag.set(FG_RDY_PORT, true, "DISABLE PORT");
this.hmi1.arVar_Port[idx].AlignOK = 1;
hmi1.arVar_Port[idx].errorCount = 0;
return;
}
//비활성화(좌/우 기능사용여부확인)
//if (idx == 0 && COMM.SETTING.Data.Disable_Left == true)
//{
// this.hmi1.arVar_Port[idx].AlignOK = 1;
// return;
//}
//else if (idx == 2 && COMM.SETTING.Data.Disable_Right == true)
//{
// this.hmi1.arVar_Port[idx].AlignOK = 1;
// return;
//}
//오류가 일정횟수 발생하면 RDY를 풀어준다(이경우에는 오류처리를 해서 알림을 해야할듯함!)
if (hmi1.arVar_Port[idx].errorCount > 5)
{
if (hmi1.arVar_Port[idx].AlignOK != 1) hmi1.arVar_Port[idx].AlignOK = 1;
if (PUB.flag.get(FG_RDY_PORT) == true) PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
return;
}
//동작중에 X가 pICK 위치에 있다면. Z축이 홈인지 체크한다.
if (PUB.sm.Step == eSMStep.RUN)
{
var PKZ_UNSAFE = MOT.getPositionOffset(eAxis.PZ_PICK, MOT.GetPZPos(ePZLoc.READY).Position) > 2;
//var PKX_POS = MOT.GetPKX_PosName();
var BSTOP = false;
//Z축이 Ready 위치보다 낮게 있다면 멈추게한다
if (idx == 0 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFL)) && PKZ_UNSAFE) BSTOP = true;
else if (idx == 1 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKON)) && PKZ_UNSAFE) BSTOP = true;
else if (idx == 2 && MOT.getPositionMatch(MOT.GetPXPos(ePXLoc.PICKOFFR)) && PKZ_UNSAFE) BSTOP = true;
if (BSTOP)
{
if (DIO.GetIOOutput(DO_PORTRUN) == true) DIO.SetPortMotor(idx, eMotDir.CCW, false, "Z-NOTREADY");
return;
}
}
var PORTALIGN_OK = hmi1.arVar_Port[idx].AlignOK;
if (PORTALIGN_OK != 1) //align이 진행되지 않았다면 align을 잡기위해 처리를 해줘야한다
{
if (idx != 1)
{
//
}
//안전센서동작여부 확인
var BSafty = DIO.isSaftyDoorF(idx, true);
//안전이 확보된 경우에만 얼라인 ok를한다 - 임시로 해제를 한다? 상단리밋에 걸리것을 처리안하려는 코드인듯!
//if (isPortDetUp(idx) == false && isPortLimUP(idx) == true && BSafty == true) PORTALIGN_OK = 1;
if (PORTALIGN_OK == 0) //얼라인이 완료되지 않은상태라면 모터 하강
{
//모터하강시작시간
PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;
//리밋이 감지된 상태에서 작업하는거면 좀더 오래 내린다
//if (isPortLimUP(idx))
//{
if (idx == 1) PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeL;
else PUB.Result.PortAlignWaitSec[idx] = AR.SETTING.Data.PortAlignDownTimeU;
//좌우측음 좀 덜 내려간다
//}
//else Pub.Result.PortAlignWaitSec[idx] = 1.2f;
//Pub.Result.PortAlignWaitSec[idx] -= 1.0f; //1초제거 210108
//모터하강
if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");
//하강검사시작
hmi1.arVar_Port[idx].AlignOK = 2;
//Pub.log.AddAT($"포트({idx}) 얼라인(DOWN) 작업 시작");
//포트가 이제 안정화하지 않았으니 안정화를 풀어준다
PUB.flag.set(FG_RDY_PORT, false, "MOT_PORT_ALIGNSTART");
}
else if (PORTALIGN_OK == 2) //하강해서 찾는중
{
//자재감지센서가 감지안되고 일정시간이 지나면 정방향으로 전환한다
if (isPortDetUp(idx) == false)
{
var waitSec = PUB.Result.PortAlignWaitSec[idx];
var ts = new TimeSpan(DateTime.Now.Ticks - PUB.Result.PortAlignTime[idx]);
if (ts.TotalSeconds >= waitSec)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "상승전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(UP)");
hmi1.arVar_Port[idx].AlignOK = 9; //올린다
//Pub.log.AddAT($"포트({idx}) 얼라인(UP) 작업 시작");
}
}
else
{
//하강하는데 자재가 감지되고있네? - 하강상태가이면 하강한다
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CCW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CCW, false, "하강전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CCW, true, "얼라인(DN)");
PUB.log.Add("PORT", "포트를 강제로 하강 합니다");
}
//자재가 감지되면 시간을 다시 초기화해서 충분히 내려가도록 한다 210402
PUB.Result.PortAlignTime[idx] = DateTime.Now.Ticks;
}
//하단 리밋에 걸렷다면 반전시켜준다. 200708
if (isPortLimDN(idx) == true)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "리밋전환전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(LIM)");
hmi1.arVar_Port[idx].AlignOK = 9;
//Pub.log.AddAT($"포트({idx}) 얼라인(UP-LIM) 작업 시작");
}
}
else if (PORTALIGN_OK == 9) //상승해서 찾는중
{
if (isPortDetUp(idx) || isPortLimUP(idx))
{
hmi1.arVar_Port[idx].AlignOK = 1; //정렬완료로처리
//Pub.log.AddAT($"포트({idx}) 얼라인 작업 완료");
}
else if (isPortDetUp(idx) == false || isPortLimUP(idx) == false)
{
//둘다 켜지 않은 상태에서 모터가 멈춰있다면 올려준다
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "강제상승전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "MOT_PORT");
PUB.log.Add("PORT", "강제 상승(9에서 멈춰있음)");
}
}
}
else if (PORTALIGN_OK == 1)
{
//정렬완료로처리 - 201229
hmi1.arVar_Port[idx].AlignOK = 1;
}
else
hmi1.arVar_Port[idx].AlignOK = 0; //알수없는 상태이므로 처음부터 시작하게 한다
}
else
{
//여기코드는 PORT ALIGN 이 완료된상태(=1) 일 때 동작하는 코드이다
if (PUB.flag.get(FG_RDY_PORT) == false)
{
if(idx != 1)
{
}
if (hmi1.arVar_Port[idx].errorCount > 5)
{
//5회이상 오류 발생햇으니 처리하지 않음
}
else if (isPortLimUP(idx) == true)
{
//상단 리밋이 확인됨(자재가 없는 경우임)
if (idx != 1)
{
//언로더 포트는 리밋에 걸리더라도 사용해야한다(놓는것은 가능 함)
//최초 상태에서는 반드시 이 상태가 된다
PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
}
else
{
if (isPortDetUp(idx))
{
PUB.flag.set(FG_RDY_PORT, true, "MOT_PORT_UNLOADER ON");
}
}
}
else if (isPortDetUp(idx) == true)
{
//자재감지가 완료되었다?
PUB.flag.set(FG_RDY_PORT, true, "RUN_MOT_P");
}
else
{
//모터를 올리는 작업을 진행해서 P-LIMIT를 찾아야 한다
Boolean runMot = DIO.GetPortMotorDir(idx) == eMotDir.CCW;
if (runMot == false)
{
if (DIO.GetIOOutput(DO_PORTRUN) == false) runMot = true;
}
if (runMot)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#1)전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#1)");
}
}
}
else //포트가 준비되면 아무것도 안한다
{
//LIMIT이 들어와있는데 DETECT 센서도 들어와 있다면 다시 얼라인 잡게한다.
if (DIO.GetIOInput(DI_LIMUP) == true)
{
//언로더포트 0,2번은 Ready 를 풀지 않는다.
//그것은 P-LIM 상태라도 작업이 가능해야 한다
if (idx == 1)
{
if (isPortDetUp(idx) == false)
PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
}
}
//자재가 감지되지 않았는데. LIMIT 가 아니라면 up을 시켜준다.
if (DIO.GetIOInput(DI_DETUP) == false && DIO.GetIOInput(DI_LIMUP) == false)
{
//RDY를 해제 해준다
PUB.flag.set(FG_RDY_PORT, false, "RUN_MOT_P");
if (DIO.GetIOOutput(DO_PORTRUN) == false)
{
if (DIO.GetPortMotorDir(idx) != eMotDir.CW && DIO.GetPortMotorRun(idx) == true)
{
DIO.SetPortMotor(idx, eMotDir.CW, false, "얼라인(#2)전멈춤");
System.Threading.Thread.Sleep(100);
}
DIO.SetPortMotor(idx, eMotDir.CW, true, "얼라인(#2)");
}
}
}
}
if (idx == 0)
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT0);
else if (idx == 1)
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT1);
else
PUB.sm.seq.UpdateTime(eSMStep.RUN_COM_PT2);
}
}
}