265 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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();
 | |
|         }
 | |
|         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.CART_MAG0) == 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.CART_MAG0) == true)
 | |
|             {
 | |
|                 PUB.flag.set(eVarBool.FG_WAT_MAGNET0, false, "SPS-MAGOFF");
 | |
|             }
 | |
| 
 | |
|             if (PUB.flag.get(eVarBool.FG_WAT_MAGNET1) && DIO.GetIOOutput(eDOName.CART_MAG1) == 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.CART_MAG1) == true)
 | |
|             {
 | |
|                 PUB.flag.set(eVarBool.FG_WAT_MAGNET1, false, "SPS-MAGOFF");
 | |
|             }
 | |
| 
 | |
| 
 | |
|             if (PUB.flag.get(eVarBool.FG_WAT_MAGNET2) && DIO.GetIOOutput(eDOName.CART_MAG2) == 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.CART_MAG2) == 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 한다.
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | 
