initial commit

This commit is contained in:
2025-11-25 20:14:41 +09:00
commit 5cb1ff372c
559 changed files with 149800 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;
namespace Project
{
public partial class FMain
{
private void SM_StateProgress(object sender, AR.StateMachine.StateProgressEventArgs e)
{
arCtl.arLabel lbl = lbMsg;
lbl.BeginInvoke(new Action(() =>
{
var title = e.Message;
var max = e.MaxProgress;
var value = e.Progress;
if (lbl.ProgressEnable == false) lbl.ProgressEnable = true;
if (lbl.ProgressValue != value) lbl.ProgressValue = (float)value;
if (lbl.Text != title) lbl.Text = title;
if (max != 0)
{
if (lbl.ProgressMax != max) lbl.ProgressMax = (float)max;
}
if (e.ForeColor != null)
{
if (lbl.ProgressForeColor != e.ForeColor) lbl.ProgressForeColor = (Color)e.ForeColor;
}
if (e.ShadowColor != null)
{
if (lbl.ShadowColor != e.ShadowColor) lbl.ShadowColor = (Color)e.ShadowColor;
}
if (e.ProgressBackColor1 != null)
{
if (lbl.ProgressColor1 != e.ProgressBackColor1) lbl.ProgressColor1 = (Color)e.ProgressBackColor1;
}
if (e.ProgressBackColor2 != null)
{
if (lbl.ProgressColor2 != e.ProgressBackColor2) lbl.ProgressColor1 = (Color)e.ProgressBackColor2;
}
if (e.BackColor1 != null)
{
if (lbl.BackColor != e.BackColor1) lbl.BackColor = (Color)e.BackColor1;
}
if (e.BackColor2 != null)
{
if (lbl.BackColor2 != e.BackColor2) lbl.BackColor2 = (Color)e.BackColor2;
}
}));
}
private void SM_StepCompleted(object sender, EventArgs e)
{
PUB.log.Add($"Step completed({PUB.sm.Step})");
//초기화가 완료되면 컨트롤 글자를 변경 해준다.
if (PUB.sm.Step == eSMStep.INIT)
SM_InitControl(null, null);
}
private void SM_StepStarted(object sender, EventArgs e)
{
switch (PUB.sm.Step)
{
case eSMStep.IDLE:
//IDLE의 시작작업이 완료되었다면 각 버튼을 사용할 수 있도록 한다
this.Invoke(new Action(() =>
{
btStart.Enabled = true;
btStop.Enabled = true;
btReset.Enabled = true;
}));
break;
}
}
private void SM_InitControl(object sender, EventArgs e)
{
//작업시작전 컨트롤 초기화 코드
var mc = PUB.Result.mModel;
var mv = PUB.Result.vModel;
this.Invoke(new Action(() =>
{
//진행 중 표시되는 상태값 초기화
lbCntRight.ProgressValue = 0;
lbCntRight.Text = "--";
lbCntLeft.Text = "--";
}));
}
void SM_Message(object sender, StateMachine.StateMachineMessageEventArgs e)
{
//상태머신에서 발생한 메세지
PUB.log.Add(e.Header, e.Message);
}
void SM_StepChanged(object sender, StateMachine.StepChangeEventArgs e)
{
var o = (eSMStep)e.Old;
var n = (eSMStep)e.New;
PUB.log.AddI($"Step transition({o} >> {n})");
//230313
//EEMStatus.AddStatusSQL(n);
}
}
}

View File

@@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using arDev;
using AR;
namespace Project
{
public partial class FMain
{
DateTime lastDeleteTime = DateTime.Now;
DateTime HomeSuccessTime;
DateTime HomeChkTime;
void SM_Loop(object sender, StateMachine.RunningEventArgs e)
{
//main loop
var step = (eSMStep)e.Step;
var obj = this.GetType();
var stepName = step.ToString();
var methodName = $"_STEP_{stepName}";
var methodNameStart = $"_STEP_{stepName}_START";
var runMethodName = $"_{stepName}";
var method = obj.GetMethod(methodName);
var methodS = obj.GetMethod(methodNameStart);
switch (step)
{
case eSMStep.NOTSET:
PUB.log.Add("S/M Initialize Start");
PUB.sm.SetNewStep(eSMStep.INIT);
break;
case eSMStep.WAITSTART:
if (e.isFirst) PUB.log.Add("EVENT WAITSTART");
break;
case eSMStep.PAUSE:
case eSMStep.EMERGENCY:
case eSMStep.ERROR:
if (e.isFirst)
_SM_MAIN_ERROR(e.isFirst, (eSMStep)e.Step, e.StepTime);
break;
default:
if (e.isFirst)
{
//시작명령은 반드시 구현할 필요가 없다
if (methodS != null) methodS.Invoke(this, new object[] { step });
else
{
hmi1.ClearMessage();
PUB.log.Add($"Undefined STEP({step}) started");
}
if (step == eSMStep.HOME_QUICK || step == eSMStep.HOME_FULL || PUB.sm.getOldStep == eSMStep.IDLE || PUB.sm.getOldStep == eSMStep.FINISH)
{
PUB.sm.seq.ClearData(step);
PUB.sm.seq.Clear(step);
}
PUB.sm.seq.ClearTime();
PUB.sm.RaiseStepStarted();
}
if (PUB.popup.needClose) System.Threading.Thread.Sleep(10);
else
{
//스텝번호값 보정 220313
if (PUB.sm.seq.Get(step) < 1) PUB.sm.seq.Update(step, 1);
if (method == null)
{
var runMethod = obj.GetMethod(runMethodName);
if (runMethod == null)
{
PUB.log.AddE($"The following command is not implemented {methodName}/{runMethodName}");
PUB.Result.SetResultMessage(eResult.DEVELOP, eECode.NOFUNCTION, eNextStep.ERROR, methodName, runMethodName);
}
else
{
var stepName2 = step.ToString();
//실행코드는 있으니 처리한다.
if (PUB.popup.needClose) System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
else
{
//실행가능여부를 확인 합니다
if (CheckSystemRunCondition() == true)
{
//동작상태가 아니라면 처리하지 않는다.
if (PUB.sm.Step == step && PUB.sm.getNewStep == step)
{
var param = new object[] { step };
var rlt = (bool)runMethod.Invoke(this, param);
if (rlt == true)
{
PUB.log.AddI("User step(automatic) execution completed, switching to idle state");
PUB.sm.SetNewStep(eSMStep.IDLE, true);
}
}
}
}
}
}
else
{
var param = new object[] { step, e.StepTime, PUB.sm.seq.GetTime(step) };
var rlt = (StepResult)method.Invoke(this, param);
if (rlt == StepResult.Complete) PUB.sm.RaiseStepCompleted();
else
{
//사용자 스텝이 설정되어있다면 자동으로 멈춘다 220223
if (rlt == StepResult.Error)
{
if (PUB.sm.getNewStep != eSMStep.ERROR)
PUB.sm.SetNewStep(eSMStep.ERROR);
}
if (PUB.flag.get(eVarBool.FG_USERSTEP) == true)
{
if (PUB.sm.Step >= eSMStep.RUN && PUB.sm.getNewStep >= eSMStep.RUN &&
PUB.sm.Step < eSMStep.FINISH && PUB.sm.getNewStep < eSMStep.FINISH)
{
//유저스텝에 걸려있지 않다면 자동으로 멈춘다
if (LockUserL.WaitOne(10) && LockUserR.WaitOne(10))
{
//Pub.Result.SetResultMessage(eResult.OPERATION, eECode.USER_STOP)
PUB.Result.ResultMessage = string.Empty;
PUB.sm.SetNewStep(eSMStep.PAUSE);
}
}
}
}
}
}
break;
}
}
void DeleteFile(string path)
{
var basetime = DateTime.Now.AddDays(-1 * AR.SETTING.Data.AutoDeleteDay);
var di = new System.IO.DirectoryInfo(path);
if (di.Exists)
{
var dirYear = di.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirYear != null)
{
var dirMon = dirYear.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirMon != null)
{
var dirDay = dirMon.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirDay != null)
{
var curDay = DateTime.Parse(string.Format("{0}-{1}-{2} 00:00:00", dirYear.ToString(), dirMon.ToString(), dirDay.ToString()));
if (curDay < basetime)
{
var dirLot = dirDay.GetDirectories().OrderBy(t => t.Name).FirstOrDefault();
if (dirLot != null)
{
var delfile = dirLot.GetFiles().FirstOrDefault();
if (delfile != null)
{
try
{
PUB.log.AddI("Remove Fle : " + delfile.FullName + ",time=" + delfile.LastWriteTime.ToString());
delfile.Delete();
}
catch (Exception ex)
{
PUB.log.AddE("deleete error : " + ex.Message);
}
}
else
{
string delpath = dirLot.FullName;
try
{
dirLot.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 폴더아래에 다른 폴더가 하나도 없다 즉 비어 있따.
string delpath = dirDay.FullName;
try
{
dirDay.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
}
else
{
//날짜에 해당하는 폴더가 하나도 없다. 월 폴더를 제거한다.
string delpath = dirMon.FullName;
try
{
dirMon.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
else
{
//이 달에 해당하는 데이터가 없다. 이 년도를 삭제한다.
string delpath = dirYear.FullName;
try
{
dirYear.Delete(true);
}
catch (Exception ex)
{
PUB.log.AddE("remove dir" + ex.Message + "," + delpath);
}
}
}
//년도별폴더목록을 정리함
//가장작은 년도를 기준으로 파일을 검색해서 1개씩 삭제함
}
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
namespace Project
{
public partial class FMain
{
private void Dio_IOValueChanged(object sender, arDev.DIO.IOValueEventArgs e)
{
if (e.Direction == arDev.DIO.eIOPINDIR.INPUT)
{
var diPin = DIO.Pin.input.Where(t=>t.terminalno == e.ArrIDX).FirstOrDefault();
if(diPin == null)
{
PUB.log.AddE($"No terminal target found for DI INDEX:{e.ArrIDX}");
}
else
{
var pin = (eDIName)diPin.idx;
if (AR.SETTING.Data.Log_DI)
{
PUB.log.Add("DIO", String.Format("DI:IDX={0},DIR={1},VAL={2},NM={3}", e.ArrIDX, e.Direction, e.NewValue, diPin));
}
var value = DIO.GetIOInput(pin);
_DIO_INPUT_VALUE_CHANGED(pin, value);
}
}
else
{
var doPin = DIO.Pin.output.Where(t => t.terminalno == e.ArrIDX).FirstOrDefault();
if (doPin == null)
{
PUB.log.AddE($"No terminal target found for DO INDEX:{e.ArrIDX}");
}
else
{
var pin = (eDOName)doPin.idx;
if (AR.SETTING.Data.Log_DO)
{
//타워램프는 제외하낟.
if (e.ArrIDX != (byte)eDOName.TWR_GRNF &&
e.ArrIDX != (byte)eDOName.TWR_REDF &&
e.ArrIDX != (byte)eDOName.TWR_YELF &&
e.ArrIDX != (byte)eDOName.BUT_STARTF &&
e.ArrIDX != (byte)eDOName.BUT_STOPF &&
e.ArrIDX != (byte)eDOName.BUT_RESETF)
PUB.log.Add("DIO", String.Format("DO:IDX={0},DIR={1},VAL={2}", e.ArrIDX, e.Direction, e.NewValue));
}
_DIO_OUTPUT_VALUE_CHANGED(pin, e.NewValue);
}
}
}
void _DIO_IOMessage(object sender, arDev.DIO.MessageEventArgs e)
{
if (e.IsError)
{
if (e.Message.ToLower().IndexOf("inposi") != -1 || e.Message.ToLower().IndexOf("동일위치") != -1)
{
PUB.log.AddAT("DIO:" + e.Message);
}
else
{
PUB.log.AddE("DIO:" + e.Message);
}
}
else PUB.log.Add("DIO:" + e.Message);
}
//void IO_SaftySensor_Changed(eDIName pin, eFlag flag, eVar_Date varDt_On, eVar_Date varDt_Off, bool value)
//{
// //안전센서는 일정 시간 동작하는것을 체크한다
// Pub.log.AddAT(string.Format("{0} Sensor : {1}", pin, value));
// if (value) Pub.Var_dateTime[(int)varDt_On] = DateTime.Now;
// else Pub.Var_dateTime[(int)varDt_Off] = DateTime.Now;
//}
void IncCount(int seq, int port, int value = 1)
{
if (SETTING.Counter.DateStr != DateTime.Now.ToShortDateString())
{
if (port == 0) SETTING.Counter.CountDP1 = value;
if (port == 1) SETTING.Counter.CountDP2 = value;
if (port == 2) SETTING.Counter.CountDP3 = value;
if (port == 3) SETTING.Counter.CountDP4 = value;
SETTING.Counter.DateStr = DateTime.Now.ToShortDateString();
}
else
{
if (port == 0) SETTING.Counter.CountDP1 += value;
if (port == 1) SETTING.Counter.CountDP2 += value;
if (port == 2) SETTING.Counter.CountDP3 += value;
if (port == 3) SETTING.Counter.CountDP4 += value;
}
//각 포트별 수량은 차수별 작업이므로 차수가 변경되면 리셋됨
//리셋되는 코드 필요함
if (port == 0) SETTING.Counter.CountP0 += value;
if (port == 1) SETTING.Counter.CountP1 += value;
if (port == 2) SETTING.Counter.CountP2 += value;
if (port == 3) SETTING.Counter.CountPrintR += value;
else
{
PUB.log.AddAT(string.Format("[{0}] Cannot increase quantity as it is an unspecified port", seq));
}
//Pub.log.AddI("수량정보가 저장 되었습니다");
SETTING.Counter.Save();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
namespace Project
{
public partial class FMain
{
#region "Common Utility"
/// <summary>
/// 지정된 시간만큼 대기하며 완료되면 true를 반환합니다.
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
Boolean WaitForSeconds(eWaitType wait, double timems)
{
var idx = (byte)wait;
if (PUB.Result.WaitForVar[idx] == null || PUB.Result.WaitForVar[idx].Year == 1982)
{
PUB.Result.WaitForVar[idx] = PUB.Result.WaitForVar[idx] = DateTime.Now;
//Pub.log.Add(string.Format("Wait for [{0}], Wait Time:{1}ms", wait, timems));
}
var ts = DateTime.Now - PUB.Result.WaitForVar[idx];
if (ts.TotalSeconds >= timems) return true;
else return false;
}
void ResetWaitForSeconds(eWaitType wait)
{
var idx = (byte)wait;
PUB.Result.WaitForVar[idx] = DateTime.Parse("1982-11-23");
}
#endregion
}//cvass
}

View File

@@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
void SM_SPS(object sender, EventArgs e)
{
//명령어 가져오기 7:3개의 데이터 확인
if (PUB.plc != null && PUB.plc.Init)
{
if (PUB.plc.ReadBytes(0, 16, out byte[] plcbuffer))
{
//내부버퍼에 상태를 기록한다
Array.Copy(plcbuffer, 0, PUB.swPLCBuffer, 0, plcbuffer.Length);
}
}
//인터락설정(공용)
Set_InterLock();
//230905
hmi1.CVLeftBusy = PUB.iLockCVL.get((int)eILockCV.BUSY);
hmi1.CVLeftReady = PUB.iLockCVL.get((int)eILockCV.EXTBUSY);
hmi1.CVRightBusy = PUB.iLockCVR.get((int)eILockCV.BUSY);
hmi1.CVRightReady = PUB.iLockCVR.get((int)eILockCV.EXTBUSY);
//XMOVE 시에 RESET 키를 이용한 장치 초기화 작업
if (PUB.sm.Step == eSMStep.IDLE)
if (PUB.mot.HasHomeSetOff == true)
if (DIO.GetIOInput(eDIName.BUT_RESETF) == true)
if (DIO.GetIOInput(eDIName.PICKER_SAFE) == true)
if (PUB.Result.ResetButtonDownTime.Year != 1982)
if ((DateTime.Now - PUB.Result.ResetButtonDownTime).TotalSeconds >= 5)
Func_sw_initialize();
//비상정지체크
if (PUB.dio.IsInit == true)
{
if (DIO.IsEmergencyOn() == true)
{
//모터에 비상정지신호를 바로 전송한다
//Util_DO.SetMotEmergency(true);
DIO.SetMotPowerOn(false);
DIO.SetMotEmergency(true);
if (PUB.sm.Step > eSMStep.IDLE)
{
string EmgButtonState = string.Empty;
if (DIO.GetIOInput(eDIName.BUT_EMGF)) EmgButtonState = "EMG-FRONT";
if (PUB.sm.Step != eSMStep.EMERGENCY &&
PUB.sm.getNewStep != eSMStep.EMERGENCY)
{
PUB.mot.MoveStop("EmgBut", true); //모든 축 강제정지 (물리시그널에 의해 미리 정지 된 상태임)
//비상상태가 아니라면 비상으로 전환해준다.
PUB.Result.ResultCode = eResult.EMERGENCY;
PUB.Result.ResultMessage = string.Format("EMERGENCY\n" +
"Emergency stop button ({0}) has been pressed\n" +
"All motions are forced to stop\n" +
"Please check the emergency stop button and initialize the system", EmgButtonState);
PUB.log.AddI("SPS:Reserve Emergency Step");
PUB.sm.SetNewStep(eSMStep.EMERGENCY);
}
}
}
else
{
//이머전시가 해제되었으므로 파워를 복원한다.
DIO.SetMotPowerOn(true);
DIO.SetMotEmergency(false);
}
}
//룸조명(자동)
if (PUB.dio.IsInit)
Func_AutoRoomLight();
//부저확인
if (PUB.dio.IsInit)
Func_BuzzerControl();
//충돌검사()
if (PUB.dio.IsInit && PUB.mot.IsInit)
CheckCollision();
//포트의 UP/DN 모터
PortZMotorAutoOff();
//포트의 마그넷 작동
PortMagnet();
//동작중에 데이터가 reset 되는 코드 임시로 모니터링한다.
if (PUB.sm.Step != eSMStep.IDLE && PUB.sm.Step != eSMStep.HOME_FULL && PUB.sm.Step != eSMStep.HOME_QUICK)
{
var currid = PUB.Result.ItemDataC.VisionData.RID;
if (currid.Equals(lastridv1) == false)
{
PUB.AddDebugLog("[SPS] RID값 변경 감지 :" + currid);
lastridv1 = currid;
}
}
//process barcode
BarcodeProcess();
AutoOutConveyor();
}
string lastridv1 = string.Empty;
System.Diagnostics.Stopwatch UnloaderWatch = new System.Diagnostics.Stopwatch();
void PortMagnet()
{
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET0) && DIO.GetIOOutput(eDOName.PORTL_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET0];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet0)
{
DIO.SetPortMagnet(0, true); //Util_DO.SetOutput(eDOName.CART_MAG0, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET0) == true && DIO.GetIOOutput(eDOName.PORTL_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SPS-MAGOFF");
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET1) && DIO.GetIOOutput(eDOName.PORTC_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET1];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet1)
{
DIO.SetPortMagnet(1, true); // Util_DO.SetOutput(eDOName.CART_MAG1, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET1) == true && DIO.GetIOOutput(eDOName.PORTC_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SPS-MAGOFF");
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET2) && DIO.GetIOOutput(eDOName.PORTR_MAGNET) == false)
{
var ts = DateTime.Now - VAR.TIME[(int)eVarTime.MAGNET2];
if (ts.TotalMilliseconds > AR.SETTING.Data.WaitTime_Magnet2)
{
DIO.SetPortMagnet(2, true); // Util_DO.SetOutput(eDOName.CART_MAG2, true);
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, false, "SPS-MAGON");
}
}
if (PUB.flag.get(eVarBool.FG_WAT_MAGNET2) == true && DIO.GetIOOutput(eDOName.PORTR_MAGNET) == true)
{
PUB.flag.set(eVarBool.FG_WAT_MAGNET2, false, "SPS-MAGOFF");
}
}
int intlockcnt = 0;
/// <summary>
/// 이 기능은 DIO 에서도 처리된다. - 해당 위치가 더 빠를듯 하여 ,그곳에서도 처리되고 이곳에서도 추가 처리를 한다
/// </summary>
private void PortZMotorAutoOff()
{
//dir 이 켜져있다면 Up/ 꺼져있다면 down
var P0DirUp = DIO.GetPortMotorDir(0) == eMotDir.CW;
var P1DirUp = DIO.GetPortMotorDir(1) == eMotDir.CW;
var P2DirUp = DIO.GetPortMotorDir(2) == eMotDir.CW;
var P0Run = DIO.GetIOOutput(eDOName.PORTL_MOT_RUN);
var P1Run = DIO.GetIOOutput(eDOName.PORTC_MOT_RUN);
var P2Run = DIO.GetIOOutput(eDOName.PORTR_MOT_RUN);
var P0LimUp = DIO.GetIOInput(eDIName.PORTL_LIM_UP);
var P1LimUp = DIO.GetIOInput(eDIName.PORTC_LIM_UP);
var P2LimUp = DIO.GetIOInput(eDIName.PORTR_LIM_UP);
var P0DetUp = DIO.GetIOInput(eDIName.PORTL_DET_UP);
var P1DetUp = DIO.GetIOInput(eDIName.PORTC_DET_UP);
var P2DetUp = DIO.GetIOInput(eDIName.PORTR_DET_UP);
var P0LimDn = DIO.GetIOInput(eDIName.PORTL_LIM_DN);
var P1LimDn = DIO.GetIOInput(eDIName.PORTC_LIM_DN);
var P2LimDn = DIO.GetIOInput(eDIName.PORTR_LIM_DN);
//현재 출력중이고, 상단이 켜져있는데 상단 센서가 들어와잇다면 OFF 한다
if (P0Run && P0DirUp && (P0LimUp || P0DetUp)) DIO.SetPortMotor(0, eMotDir.CCW, false, "SPS");
if (P1Run && P1DirUp && (P1LimUp || P1DetUp)) DIO.SetPortMotor(1, eMotDir.CCW, false, "SPS");
if (P2Run && P2DirUp && (P2LimUp || P2DetUp)) DIO.SetPortMotor(2, eMotDir.CCW, false, "SPS");
//현재 출력중이고, 하단이 켜져있는데. 하단 센서가 들어와 있다면 Off 한다
if (P0Run && P0DirUp == false && P0LimDn) DIO.SetPortMotor(0, eMotDir.CW, false, "SPS");
if (P1Run && P1DirUp == false && P1LimDn) DIO.SetPortMotor(1, eMotDir.CW, false, "SPS");
if (P2Run && P2DirUp == false && P2LimDn) DIO.SetPortMotor(2, eMotDir.CW, false, "SPS");
//작업이 종료되어서 포트가 내려가고 있다면 5초뒤에 멈춘다 - 210405
if (PUB.flag.get(eVarBool.FG_PORT1_ENDDOWN) && AR.SETTING.Data.Port1FisnishDownTime > 0)
{
var runtime = DateTime.Now - VAR.TIME[(int)eVarTime.PORT1];
if (runtime.TotalMilliseconds >= AR.SETTING.Data.Port1FisnishDownTime)
{
if (P1Run && PUB.sm.isRunning == false && DIO.GetPortMotorDir(1) == eMotDir.CCW)
{
DIO.SetPortMotor(1, eMotDir.CW, false, "SPS");
}
PUB.flag.set(eVarBool.FG_PORT1_ENDDOWN, false, "SPS");
VAR.TIME.Update(eVarTime.PORT1);
}
}
}
DateTime CollCheckTime = DateTime.Now;
private void CheckCollision()
{
//충돌검검사 (홈 이 완료안된 모터에는 처리하지 않는다)
if (PUB.sm.Step != eSMStep.RUN || PUB.sm.getNewStep != eSMStep.RUN) return;
//초당 20번 검사하게 함
var ts = DateTime.Now - CollCheckTime;
if (ts.TotalMilliseconds < 50) return;
//현재 시간으로 설정
CollCheckTime = DateTime.Now;
}
private void Func_AutoRoomLight()
{
if (AR.SETTING.Data.Enable_AutoLight == false) return;
}
private void Func_BuzzerControl()
{
//if (AR.SETTING.Data.Disable_Buzzer == false) return;
if (PUB.BuzzerTime.Year == 1982) return; //시간설정이없으면 out
if (DIO.GetIOOutput(eDOName.BUZZER) == false) return; //부저가 꺼져있다면 out
if (AR.SETTING.Data.buzz_run_ms != 0) //시간이 설정된 경우에만 작동190509
{
if (PUB.BuzzerTime.Year == 1982) PUB.BuzzerTime = DateTime.Now;
else
{
var ts = DateTime.Now - PUB.BuzzerTime;
if (ts.TotalMilliseconds >= AR.SETTING.Data.buzz_run_ms) //지정시간이 초과된경우에만 OFF
{
PUB.log.Add("Auto Buzzer Off by SPS");
DIO.SetBuzzer(false); //지정시간초과로 부저를 OFF 한다.
}
}
}
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
//컨베이어 배출신호를 자동 해제한다.(지정시간-초)
DateTime AutoConvOutTimeL = new DateTime(1982, 11, 23);
DateTime AutoConvOutTimeR = new DateTime(1982, 11, 23);
void AutoOutConveyor()
{
//동작중에만 사용한다
if (PUB.sm.Step != eSMStep.RUN) return;
//컨베이어 사용시에만.
if (VAR.BOOL[eVarBool.Use_Conveyor] == false) return;
//모델정보 필수
if (PUB.Result.vModel == null || PUB.Result.isSetvModel == false) return;
//자동 해제 시간확인 (0=비활성)
var AutoReleaseSecond = PUB.Result.vModel.AutoOutConveyor;
if (AutoReleaseSecond < 1) return;
//현재 모델의 사용여부 확인 (UI상단에서 버튼으로 클릭가능하다)
if (PUB.Result.AutoReelOut == false) return;
//외부신호 대기중일때만 사용
if (PUB.iLockCVL.get((int)eILockCV.EXTBUSY) && DIO.GetIOInput(eDIName.L_CONV4))
{
if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] == false)
{
if (AutoConvOutTimeL.Year == 1982) AutoConvOutTimeL = DateTime.Now;
var ts = DateTime.Now - AutoConvOutTimeL;
if (ts.TotalSeconds > AutoReleaseSecond)
{
PUB.log.AddI($"Auto Conveyor(L) Output - On");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] = true;
AutoConvOutTimeL = DateTime.Now;
}
}
}
else if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] == true)
{
var ts = DateTime.Now - AutoConvOutTimeL;
if (ts.TotalSeconds > SETTING.Data.Timeout_AutoOutConvSignal)
{
PUB.log.Add($"Auto Conveyor(L) Output - Off");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVL] = false;
AutoConvOutTimeL = new DateTime(1982, 11, 23);
}
}
//외부신호 대기중일때만 사용
if (PUB.iLockCVR.get((int)eILockCV.EXTBUSY) && DIO.GetIOInput(eDIName.R_CONV4))
{
if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] == false)
{
if (AutoConvOutTimeR.Year == 1982) AutoConvOutTimeR = DateTime.Now;
var ts = DateTime.Now - AutoConvOutTimeR;
if (ts.TotalSeconds > AutoReleaseSecond)
{
PUB.log.AddI($"Auto Conveyor(R) Output - On");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] = true;
AutoConvOutTimeR = DateTime.Now;
}
}
}
else if (VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] == true)
{
var ts = DateTime.Now - AutoConvOutTimeR;
if (ts.TotalSeconds > SETTING.Data.Timeout_AutoOutConvSignal)
{
PUB.log.Add($"Auto Conveyor(R) Output - Off");
VAR.BOOL[eVarBool.FG_AUTOOUTCONVR] = false;
AutoConvOutTimeR = new DateTime(1982, 11, 23);
}
}
}
}
}

View File

@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using AR;
namespace Project
{
public partial class FMain
{
Tuple<int, List<string>> BarcodeRegExProcess(
List<Class.RegexPattern> patterns,
List<Class.RegexPattern> patternsEx,
Class.VisionData vdata, string barcodeSymbol,
string bcd, out bool IgnoreBarcode, out bool findregex)
{
//var patterns = PUB.Result.BCDPattern;
IgnoreBarcode = false;
findregex = false;
if (barcodeSymbol == "6") barcodeSymbol = "11"; //250930
//get : same symbol data
List<Class.RegexPattern> pats;
if (patterns != null)
{
if (barcodeSymbol.isEmpty() == false) pats = patterns.Where(t => t.IsEnable == true && (string.IsNullOrEmpty(t.Symbol) || t.Symbol == barcodeSymbol)).OrderBy(t => t.Seq).ToList();
else pats = patterns.Where(t => t.IsEnable == true).OrderBy(t => t.Seq).ToList();
}
else pats = new List<Class.RegexPattern>();
List<Class.RegexPattern> patsEx;
if (patternsEx == null) patsEx = new List<Class.RegexPattern>();
else
{
if (barcodeSymbol.isEmpty() == false) patsEx = patternsEx.Where(t => string.IsNullOrEmpty(t.Symbol) || t.Symbol == barcodeSymbol).OrderBy(t => t.Seq).ToList();
else patsEx = patternsEx.Where(t => t.IsEnable == true).OrderBy(t => t.Seq).ToList();
}
//모델정보의 허용 심볼인지 확인한다 221017
var vm = PUB.Result.vModel;
if (vm != null)
{
if (vm.BCD_DM == false && barcodeSymbol == "2")
{
PUB.log.AddAT($"Inactive in model Symbol Setting(DM):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
else if (vm.BCD_1D == false && (barcodeSymbol == "6" || barcodeSymbol == "11"))
{
PUB.log.AddAT($"Inactive in model Symbol Setting(1D):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
else if (vm.BCD_QR == false && (barcodeSymbol == "1"))
{
PUB.log.AddAT($"Inactive in model Symbol Setting(QR):{bcd}");
IgnoreBarcode = true;
return new Tuple<int, List<string>>(0, new List<string>());
}
}
//check barcode pattern
if (pats.Any() == false)
{
PUB.log.AddAT($"No registered pattern(SYM={barcodeSymbol}) Model:{vm.Title}");
return new Tuple<int, List<string>>(0, new List<string>());
}
//이 바코드가 무시바코드에 있는지 먼저 검사한다 220718
foreach (var pt in patsEx)
{
//skip disable item
if (pt.IsEnable == false) continue;
//check regex
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 10));
if (regx.IsMatch(bcd))
{
PUB.log.AddAT($"Ignore barcode:{bcd},PAT:{pt.Pattern},SYM:{pt.Symbol}");
IgnoreBarcode = true;
break;
}
}
if (IgnoreBarcode)
{
return new Tuple<int, List<string>>(0, new List<string>());
}
//동작중에 들어오는 바코드의 자동처리코드 추가 250926
if (PUB.sm.Step == eSMStep.RUN || PUB.sm.Step == eSMStep.PAUSE || PUB.sm.Step == eSMStep.WAITSTART)
{
var OPT_PrinterOff = VAR.BOOL[eVarBool.Opt_DisablePrinter];
var OPT_CameraOff = PUB.OPT_CAMERA();
var OPT_BYPASS = PUB.OPT_BYPASS();
if (OPT_BYPASS == false)
{
//기본 벤더이름
if (PUB.Result.vModel.Def_Vname.isEmpty() == false)
{
if (vdata.VNAME.Equals(PUB.Result.vModel.Def_Vname) == false)
{
vdata.VNAME = PUB.Result.vModel.Def_Vname;
vdata.VNAME_Trust = true;
PUB.log.Add($"Defaul V.Name Set to {PUB.Result.vModel.Def_Vname}");
}
}
//기본 MFG
if (PUB.Result.vModel.Def_MFG.isEmpty() == false)
{
if (vdata.MFGDATE.Equals(PUB.Result.vModel.Def_MFG) == false)
{
vdata.MFGDATE = PUB.Result.vModel.Def_MFG;
vdata.MFGDATE_Trust = true;
PUB.log.Add($"Defaul MFGDATE Set to {PUB.Result.vModel.Def_MFG}");
}
}
//파트넘버무시
if (PUB.Result.vModel.IgnorePartNo)
{
vdata.PARTNO_Trust = true;
}
//배치무시
if (PUB.Result.vModel.IgnoreBatch)
{
}
//프린트를 하지 않는 경우에는 프린트 위치를 자동으로 처리한다.
if (OPT_PrinterOff == true)
{
vdata.PrintPositionData = "0";
vdata.PrintPositionCheck = true;
}
}
else
{
if (vdata.VNAME_Trust == false)
{
vdata.VNAME = "BYPASS";
vdata.VNAME_Trust = true;
}
}
}
var ValueApplyCount = 0;
ValueApplyCount = 0;
List<string> list = new List<string>();
findregex = false;
foreach (var pt in pats)
{
//skip disable item
if (pt.IsEnable == false) continue;
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 5));
try
{
if (regx.IsMatch(bcd))
{
findregex = true;
//find data
var matchs = regx.Matches(bcd);
foreach (System.Text.RegularExpressions.Match mat in matchs)
{
if (vdata == null) ValueApplyCount += 1;
else
{
foreach (var matchdata in pt.Groups)
{
if (matchdata.GroupNo <= mat.Groups.Count)
{
var data = mat.Groups[matchdata.GroupNo];
if (PUB.SetBCDValue(vdata, matchdata.TargetPos, data.Value, pt.IsTrust))
ValueApplyCount += 1;
}
}
}
}
if (vdata != null && pt.IsAmkStd)// && bcdObj.barcodeSymbol == "1")
{
vdata.QRInputRaw = bcd;
}
if (vdata != null)
PUB.log.AddI($"[{pt.Description}]=>{bcd}");
list.Add(pt.Customer + "|" + pt.Description);
}
else
{
//PUB.log.AddAT($"(X)Match ({pt.Pattern}) Data={bcd}");
}
}
catch (Exception ex)
{
PUB.log.AddE($"BarcodeRegEx Error : {ex.Message}");
}
}
return new Tuple<int, List<string>>(ValueApplyCount, list);
}
/// <summary>
/// barcod eprocess
/// </summary>
void BarcodeProcess()
{
var itemC = PUB.Result.ItemDataC;
var vdata = itemC.VisionData;
//No Run - Confirm Data
if (vdata.Confirm) return;
var vm = PUB.Result.vModel;
lock (vdata.barcodelist)
{
foreach (var item in vdata.barcodelist)
{
//var src = item.Value.barcodeSource;
var bcd = item.Value.Data;
var bcdObj = item.Value;
//already checked
if (bcdObj.RegExConfirm) continue;
lock (PUB.Result.BCDPatternLock)
{
var ValueApplyCount = BarcodeRegExProcess(PUB.Result.BCDPattern, PUB.Result.BCDIgnorePattern, vdata, bcdObj.barcodeSymbol, bcd, out bool IgnoreBcd, out bool findregex);
bcdObj.Ignore = IgnoreBcd;
//기타바코드 무시기능 적용 221018
if (vm != null && vm.IgnoreOtherBarcode == true && findregex == false)
bcdObj.Ignore = true;
bcdObj.RefExApply = (ValueApplyCount?.Item1 ?? 0);
bcdObj.RegExConfirm = true;
}
}
}
//all process sequence
if (BCDProcess_ALL(itemC, "SPS", PUB.sm.Step == eSMStep.RUN) != EResultKeyence.Nothing)
{
//nothing : multisid condition
}
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
namespace Project
{
public partial class FMain
{
bool RecvQRProcess(List<string> qrdatas, eWorkPort vIdx)
{
//데이터가없으면 처리하지 않는다.
if (qrdatas == null || qrdatas.Count < 1) return false;
bool FindData = false;
var idata = vIdx == eWorkPort.Left ? PUB.Result.ItemDataL : PUB.Result.ItemDataR;
//표준바코드라면 그 값을 표시해준다
lock (PUB.Result.BCDPatternLock)
{
var patterns = PUB.Result.BCDPattern;
foreach (var datas in qrdatas)
{
// JSON 구조에서 "data" 필드 추출
string barcodeData = datas;
try
{
var jobj = JObject.Parse(datas);
if (jobj["data"] != null)
{
barcodeData = jobj["data"].ToString();
}
}
catch
{
// JSON 파싱 실패 시 원본 데이터 사용
barcodeData = datas;
}
//원본자료를 체크한다
if (barcodeData.Equals(idata.VisionData.PrintQRData))
{
//인쇄한 자료와 동일한 자료이다
FindData = true;
}
//표준 바코드 형태만 취한다
var pats = patterns.Where(t => t.IsAmkStd && t.IsEnable).OrderBy(t => t.Seq).ToList();
if (pats.Any())
{
//패턴을 확인하여 값을 표시해준다
//var ValueApplyCount = 0;
foreach (var pt in pats)
{
var regx = new Regex(pt.Pattern, RegexOptions.IgnoreCase, new TimeSpan(0, 0, 10));
if (regx.IsMatch(barcodeData)) //패턴이 일치하다면 이것만 사용한다
{
//find data
var matchs = regx.Matches(barcodeData);
foreach (System.Text.RegularExpressions.Match mat in matchs)
{
foreach (var matchdata in pt.Groups)
{
if (matchdata.GroupNo <= mat.Groups.Count)
{
var data = mat.Groups[matchdata.GroupNo];
switch (matchdata.TargetPos.ToUpper())
{
case "SID":
idata.VisionData.SID2 = data.Value;
break;
case "RID":
idata.VisionData.RID2 = data.Value;
break;
case "VLOT":
idata.VisionData.VLOT2 = data.Value;
break;
case "VNAME":
idata.VisionData.VNAME2 = data.Value;
break;
case "MFG":
idata.VisionData.MFGDATE2 = data.Value;
break;
case "QTY":
idata.VisionData.QTY2 = data.Value;
break;
case "PART":
idata.VisionData.PARTNO2 = data.Value;
break;
}
}
}
}
break;
}
}
}
}
}
//자료는 있었지만 바코드검증이 실패된 경우이다
//타임아웃까지 기다리지 않고 바로 오류처리를 한다.
if (FindData == true)
{
//데이터를 찾았다면 완료처리를 해준다
idata.VisionData.Complete = true;
//PUB.Result.ItemData[vIdx].VisionData.Complete = true;
return true;
}
return false;
//else
//{
// var item = Pub.Result.ItemData[vIdx];
// var tsGrab = DateTime.Now - Pub.GetVarTime(VAR_LIVEVIEW);
// var timeoutVision = vIdx == 1 ? COMM.SETTING.Data.Timeout_VisionProcessL : COMM.SETTING.Data.Timeout_VisionProcessU;
// if (tsGrab.TotalMilliseconds >= timeoutVision)
// {
// //다음 바코드가 있다면 추가 진행을 위해서 남겨준다
// _SM_SAVEIMAGE(vIdx, DateTime.Now, "Images(QRValid)");
// WS_Send((idx == 0 ? 0 : 1), Pub.wsL, Pub.Result.ItemData[idx].guid, "OFF");
// var barcodepos = vIdx == 0 ? "LEFT" : "RIGHT";
// Pub.log.AddE("(" + barcodepos + ")바코드를 검증했지만 일치하지 않습니다");
// Pub.Result.SetResultMessage(eResult.OPERATION, eECode.BARCODEVALIDERR, eNextStep.pause,
// vIdx, Pub.Result.ItemData[vIdx].VisionData.RID, Pub.Result.ItemData[vIdx].VisionData.RID2,
// Pub.Result.ItemData[vIdx].VisionData.QTY, Pub.Result.ItemData[vIdx].VisionData.QTY2,
// Pub.Result.ItemData[vIdx].VisionData.SID, Pub.Result.ItemData[vIdx].VisionData.SID2,
// Pub.Result.ItemData[vIdx].VisionData.MFGDATE, Pub.Result.ItemData[vIdx].VisionData.MFGDATE2,
// barcodepos);
// return;
// }
//}
}
}
}