using SA_LTT.Info.WaferInfo; using System; using System.Collections; using System.Text; using System.Threading; using static SA_LTT.Info.WaferInfo.WaferInfoManager; namespace SA_LTT.Module { /* ======== Movement ====================== Wafer Handling -> Get Ready Get Put Ready Put Arm Motion -> Extend arm, Retract arm // 팬던트에서만 하도록. Cross Motion -> Dual arm WTR 로봇일 때 // 안하는걸로 Mapping -> Mapping motion test, Mapping Calibration, Mapping setting, Mapping Deflection check -> 블레이드 처짐 감지 , Calibration, setting, check Macro -> 무한동작 매크로 (접근 막혀있음) ==================================== ======== Teaching ====================== 이거는 팬던트에서만 하는게 맞을듯. ==================================== ======= Speed (%) ============== ex ) System 속도 50% , Jog 속도 50% -> 실제 Jog 속도 25%. System -> 전체의 동작 속도 Jog -> System 대비 jog 속도 Home -> System 대비 Home 속도 Wafer On -> System 대비 팔을 뻗고 접는 동작 Wafer Off -> System 대비 팔을 뻗고 접는 동작 Z Up -> System 대비 Z축 Up 수행시 Z Down -> System 대비 Z축 Down 수행시 ================================ ======== Monitor ====================== IO Control -> IO on/off제어, Grip on/off speed 확인 Input monitor -> 로봇 수신 input 확인. output monitor -> 로봇 수신 output 확인 Limit sensor -> Limit sensor 감지 확인 ERRLog -> 과거 발생했던 에러 확인 Serial Port -> 로봇 통신 설정 변경 ==================================== ======== Setup ====================== Zero degree set -> 모든 축의 원점 위치 현재 로봇의 위치로 설정. // 팬던트에서만 Calibration -> Z축 탈조 자동 감지 확인 칼리브레이션 수행. // 기능이 있는지 오면 확인. Soft limit -> 각축의 이동 가능 범위 재설정. // 팬던트 에서만. Motor speed -> 각 축의 Motor 최대 동작 속도 변경 100%(3000RPM) // 팬던트 에서만. Mode -> Demo mode, Interlock mode (외부 Interlock 신호시 로봇 정지 유무), retry cnt (Get, Put 동작 실패 시 재시도 횟수) 설정 Wafer size 설정, Non block (1 command 내의 구분동작 연결 속도빠르게) //안씀. Time -> 그립형/버큠형 타입의 경우 On/Off 완료 대기 딜레이 시간 조절.(ms) ==================================== ======== Jog ====================== 이거는 팬던트에서만 하는게 맞을듯. ==================================== 알람 너무 많은데... Alarm 은 하나로 해놓고 Error 내용이랑 Description만 띄우면 되지 않을까? */ public class Robot : ComPort { public enum PowerState { /// /// System initially starting up /// Starting, /// /// Power off, fatal error has occurred /// FatalError, /// /// Power off, power sequence restarting /// PowerSequencereStarting, /// /// Power being turned off, no fault condition has occurred /// PowerBeingTrunedOff, /// /// Power being turned off, a fault condition has occurred /// PowerBeingTurnedOffFault, /// /// Power is off, a fault has occurred that must be cleared /// PowerOffFault, /// /// Power is off, waiting for hardware enable power switch to be turned off /// PowerOffWaitingHardware, /// /// Power is off, waiting for enable power signal to be asserted /// PowerOffWaitingPowerSignal, /// /// Power is coming up, enabling amplifiers /// PowerComingUp, /// /// Power is on, performing motor commutation /// PowerOnPerformingMotor, /// /// Power is coming up, enabling servos and releasing brakes /// PowerComingUpEnablingServos, /// /// Power is on, waiting to execute thread or Auto Execution task /// PowerOnWaitingExecuteThread, /// /// Power is on, executing Auto Execution tas /// PowerOnExecutingAuto, } public enum StageList : int { Port1 = 1, Port2, AlignFlip, Align, Chamber, } private string _fimwareVersion; private bool _isError; private bool _isMappingError; // 0 ~ 10 서보 off 상태 11 ~ 12 서보 on 상태 private PowerState _powerStatus; private Equipment _equipment; private Thread t_statusUpdate; private double _positionT; private double _positionZ; private double _positionR; private double _positionF; private string _alarmCode; private string _alarmDescription; private bool _isWaferExist; private bool _isVacuumOn; private bool _isRun; private bool _isPutGetRun; private TimeSpan _getTactTime; private TimeSpan _putTactTime; private TimeSpan _mappingTactTime; private Thread t_PutGetSequence; public double PositionT { get { return _positionT; } set { _positionT = value; } } public double PositionZ { get { return _positionZ; } set { _positionZ = value; } } public double PositionR { get { return _positionR; } set { _positionR = value; } } public double PositionF { get { return _positionF; } set { _positionF = value; } } public string AlarmCode { get { return _alarmCode; } set { _alarmCode = value; } } public string AlarmDescription { get { return _alarmDescription; } set { _alarmDescription = value; } } public bool IsError { get { return _isError; } set { _isError = value; } } public PowerState PowerStatus { get { return _powerStatus; } private set { _powerStatus = value; } } public bool IsVacuumOn { get { return _isVacuumOn; } private set { _isVacuumOn = value; } } public bool IsRun { get { return _isRun; } set { _isRun = value; } } public bool IsWaferExist { get { return _isWaferExist; } set { _isWaferExist = value; } } public bool IsServoOn { get { if(_powerStatus == PowerState.PowerOnWaitingExecuteThread || _powerStatus == PowerState.PowerOnExecutingAuto) { return true; } else { return false; } } } public bool IsPutGetRun { get { return _isPutGetRun; } set { _isPutGetRun = value; } } public TimeSpan GetTactTime { get { return _getTactTime; } set { _getTactTime = value; } } public TimeSpan PutTactTime { get { return _putTactTime; } set { _putTactTime = value; } } public bool IsRunEnable { get { if (IsOpen && IsRun == false && (t_PutGetSequence == null || (t_PutGetSequence.ThreadState == ThreadState.Stopped))) { return true; } else { return false; } } } public TimeSpan MappingTactTime { get { return _mappingTactTime; } set { _mappingTactTime = value; } } public bool IsMappingError { get { return _isMappingError; } set { _isMappingError = value; } } public Robot(Equipment equipment) { serialPort.PortName = "COM9"; serialPort.BaudRate = 57600; serialPort.Parity = System.IO.Ports.Parity.None; serialPort.DataBits = 8; serialPort.StopBits = System.IO.Ports.StopBits.One; serialPort.ReadTimeout = 5000; ReceiveWaitSeconds = 0.05; Terminator = "\r\n"; _equipment = equipment; t_statusUpdate = new Thread(statusUpdate); t_statusUpdate.Start(); _alarmCode = "0"; } public void statusUpdate() { while (_equipment.IsDisposed == false) { try { Thread.Sleep(10); if (IsOpen) { ReadPowerState(); ReadPosition(); ReadErrorCode(); ReadWaferDetected(); ReadVacuumOn(); ReadRun(); } else { if (_equipment.alarmManager.OccurredAlarms.Exists(x => x.Code == SA_LTT.AlarmCode.AL_0052_ROBOT_DISCONNECTED)) { } else { WaferGetInterlock(StageList.Chamber, 1); if (Open() == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0052_ROBOT_DISCONNECTED); } else { Thread.Sleep(100); ReadFirmwareVersion(); } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } } } public void ReadFirmwareVersion() { if(IsOpen) { string receivedData; WriteRead("VER", out receivedData); _fimwareVersion = receivedData; } else { // 읽기 실패 알람 ? } } //=================== Movement ====================== public bool GetReady(StageList stage, int slot = 1) { if (t_PutGetSequence == null || t_PutGetSequence.ThreadState == ThreadState.Stopped) { t_PutGetSequence = new Thread(() => GetReadyThread(stage, slot)); t_PutGetSequence.Start(); return true; } else { return false; } } public void GetReadyThread(StageList stage, int slot = 1) { try { DateTime tactTime = DateTime.Now; IsPutGetRun = true; Write($"GRDY {(int)stage},{slot}"); DateTime dt = DateTime.Now; //동작 진행 확인. while (true) { if (IsRun) { break; } else { if ((DateTime.Now - dt).TotalSeconds > 5) { PutTactTime = DateTime.Now - tactTime; return; } } } //동작 진행 완료 확인 while (true) { if (IsRun == false) { break; } else { if ((DateTime.Now - dt).TotalMinutes > 3) { return; } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { IsPutGetRun = false; } } public bool Get(StageList stage, int slot = 1) { if (WaferGetInterlock(stage, slot) == false) { if (t_PutGetSequence == null || t_PutGetSequence.ThreadState == ThreadState.Stopped) { t_PutGetSequence = new Thread(() => GetThread(stage, slot)); t_PutGetSequence.Start(); return true; } else { return false; } } else { return false; } } private void GetThread(StageList stage, int slot) { try { DateTime tactTime = DateTime.Now; IsPutGetRun = true; Write($"GET {(int)stage},{slot}"); DateTime dt = DateTime.Now; //동작 진행 확인. while (true) { if (IsRun) { break; } else { if ((DateTime.Now - dt).TotalSeconds > 5) { GetTactTime = DateTime.Now - tactTime; return; } } } //동작 진행 완료 확인 while (true) { if (IsRun == false) { WaferNumbers sourceNumber; WaferInfoManager.TryParse((int)stage, slot, out sourceNumber); Thread.Sleep(100); ReadWaferDetected(); if (IsWaferExist == true) { if (stage == StageList.AlignFlip) { WaferInfo waferInfo = _equipment.waferInfoManager.GetWaferInfo(sourceNumber); waferInfo.IsFlip = !waferInfo.IsFlip; _equipment.waferInfoManager.SetWaferInfo(sourceNumber, waferInfo); } _equipment.waferInfoManager.MoveWaferInfo(sourceNumber, WaferNumbers.Robot); } else { EquipmentLogManager.Instance.WriteExceptionLog("Get Error"); } GetTactTime = DateTime.Now - tactTime; break; } else { if ((DateTime.Now - dt).TotalMinutes > 3) { //Robot 동작완료 TimeOut 3분 GetTactTime = DateTime.Now - tactTime; return; } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { IsPutGetRun = false; } } public bool PutReady(StageList stage, int slot = 1) { if (t_PutGetSequence == null || t_PutGetSequence.ThreadState == ThreadState.Stopped) { t_PutGetSequence = new Thread(() => PutReadyThread(stage, slot)); t_PutGetSequence.Start(); return true; } else { return false; } } public void PutReadyThread(StageList stage, int slot = 1) { try { DateTime tactTime = DateTime.Now; IsPutGetRun = true; Write($"PRDY {(int)stage},{slot}"); DateTime dt = DateTime.Now; //동작 진행 확인. while (true) { if (IsRun) { break; } else { if ((DateTime.Now - dt).TotalSeconds > 5) { PutTactTime = DateTime.Now - tactTime; return; } } } //동작 진행 완료 확인 while (true) { if (IsRun == false) { break; } else { if ((DateTime.Now - dt).TotalMinutes > 3) { return; } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { IsPutGetRun = false; } } public bool Put(StageList stage, int slot = 1) { if (WaferPutInterlock(stage, slot) == false) { if (t_PutGetSequence == null || t_PutGetSequence.ThreadState == ThreadState.Stopped) { t_PutGetSequence = new Thread(() => PutThread(stage, slot)); t_PutGetSequence.Start(); return true; } else { return false; } } else { return false; } } private void PutThread(StageList stage, int slot) { try { DateTime tactTime = DateTime.Now; IsPutGetRun = true; Write($"PUT {(int)stage},{slot}"); DateTime dt = DateTime.Now; //동작 진행 확인. while (true) { if (IsRun) { break; } else { if ((DateTime.Now - dt).TotalSeconds > 5) { PutTactTime = DateTime.Now - tactTime; return; } } } //동작 진행 완료 확인 while (true) { if (IsRun == false) { WaferNumbers destinationNumber; WaferInfoManager.TryParse((int)stage, slot, out destinationNumber); Thread.Sleep(100); ReadWaferDetected(); if (IsWaferExist == false) { if (stage == StageList.AlignFlip) { WaferInfo waferInfo = _equipment.waferInfoManager.GetWaferInfo(WaferNumbers.Robot); waferInfo.IsFlip = !waferInfo.IsFlip; _equipment.waferInfoManager.SetWaferInfo(WaferNumbers.Robot, waferInfo); } _equipment.waferInfoManager.MoveWaferInfo(WaferNumbers.Robot, destinationNumber); } else { EquipmentLogManager.Instance.WriteExceptionLog("Put Error"); } PutTactTime = DateTime.Now - tactTime; break; } else { if ((DateTime.Now - dt).TotalMinutes > 3) { //Robot 동작완료 TimeOut 3분 PutTactTime = DateTime.Now - tactTime; return; } } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { IsPutGetRun = false; } } public bool MappingSeq(int stage) { if (MappingInterlock(stage) == false) { if (t_PutGetSequence == null || t_PutGetSequence.ThreadState == ThreadState.Stopped) { t_PutGetSequence = new Thread(() => MappingTh(stage)); t_PutGetSequence.Start(); return true; } else { return false; } } else { return false; } } public bool WaferGetInterlock(StageList stage, int slot) { if(IsWaferExist || IsRunEnable == false || IsPutGetRun) { if(IsWaferExist) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0077_ROBOT_HAS_WAFER); } return true; } else { WaferNumbers waferNumber = WaferNumbers.A1; if(WaferInfoManager.TryParse((int)stage, slot, out waferNumber)) { if (stage == StageList.Port1) { if(_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1] == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0070_PORT1_IS_NOT_DETECTED); return true; } } if (stage == StageList.Port2) { if (_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2] == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0071_PORT2_IS_NOT_DETECTED); return true; } } if (stage == StageList.AlignFlip || stage == StageList.Align) { if (_equipment.preAligner.IsWaferExist == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0072_PREALIGNER_HAS_NOT_WAFER); return true; } if(_equipment.preAligner.IsRunEnable == false) { return true; } } if (stage == StageList.Chamber) { //Position, Gate, LiftPin Check if (_equipment.powerPmac.IsLoadPosition() == false || _equipment.crevis.DigitalInputs[Crevis.DigitalInput.CMB_GATE_CLOSE] || _equipment.crevis.DigitalInputs[Crevis.DigitalInput.WAFER_DOWN_CYLINDER]) { _equipment.SetMessageBox("Chamber position을 확인 해 주세요."); //_equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0073_CHAMBER_HAS_NOT_WAFER); return true; } } if (_equipment.waferInfoManager.GetWaferInfo(waferNumber).IsStatus == WaferInfo.WaferStatus.Exist) { return false; } else { _equipment.SetMessageBox("이미 Wafer가 존재 하지 않습니다! Wafer 정보를 확인해 주세요."); return true; } } else { return true; } } } public bool WaferPutInterlock(StageList stage, int slot) { if(IsWaferExist == false|| IsRunEnable == false || IsPutGetRun) { if (IsWaferExist == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0074_ROBOT_HAS_NOT_WAFER); } return true; } else { WaferNumbers waferNumber = WaferNumbers.A1; if (WaferInfoManager.TryParse((int)stage, slot, out waferNumber)) { if (stage == StageList.Port1) { if (_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1] == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0070_PORT1_IS_NOT_DETECTED); return true; } } if (stage == StageList.Port2) { if (_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2] == false) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0071_PORT2_IS_NOT_DETECTED); return true; } } if (stage == StageList.AlignFlip || stage == StageList.Align) { if (_equipment.preAligner.IsWaferExist) { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0075_PREALIGNER_HAS_WAFER); return true; } } if (stage == StageList.Chamber) { //Position, Gate, LiftPin Check if (_equipment.powerPmac.IsLoadPosition() == false || _equipment.crevis.DigitalInputs[Crevis.DigitalInput.CMB_GATE_CLOSE] || _equipment.crevis.DigitalInputs[Crevis.DigitalInput.WAFER_DOWN_CYLINDER]) { _equipment.SetMessageBox("Chamber position을 확인 해 주세요."); //_equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0076_CHAMBER_HAS_WAFER); return true; } } if (_equipment.waferInfoManager.GetWaferInfo(waferNumber).IsStatus == WaferInfo.WaferStatus.Empty) { return false; } else { _equipment.SetMessageBox("이미 Wafer가 존재 합니다! Wafer 정보를 확인해 주세요."); return true; } } else { return true; } } } public bool MappingInterlock(int stage) { if (stage == 1) { if(_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_1]) { return false; } else { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0070_PORT1_IS_NOT_DETECTED); return true; } } else if (stage == 2) { if (_equipment.crevis.DigitalInputs[Crevis.DigitalInput.CST_DETECTOR_2]) { return false; } else { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0071_PORT2_IS_NOT_DETECTED); return true; } } else { return true; } } private void MappingTh(int stage) { DateTime tactTime = DateTime.Now; Mapping(stage); DateTime dt = DateTime.Now; //동작 진행 확인. while (true) { if (IsRun) { break; } else { if ((DateTime.Now - dt).TotalSeconds > 5) { PutTactTime = DateTime.Now - tactTime; return; } } } while (true) { //Run 종료 후 Mapping 결과 받기 시작. if (IsRun == false) { if (stage == 1) { ReadPort1MappingResult(); } else if (stage == 2) { ReadPort2MappingResult(); } MappingTactTime = DateTime.Now - tactTime; break; } else { if ((DateTime.Now - dt).TotalMinutes > 5) { //Robot 동작완료 TimeOut 5분 MappingTactTime = DateTime.Now - tactTime; return; } } } } private void ReadPort1MappingResult() { string mappingData = _equipment.robot.ReadMappingResult(); if (mappingData.Length == 25) { IsMappingError = false; for (int i = 0; i < 25; i++) { WaferInfo info = _equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i); info.SourceNumber = WaferInfoManager.WaferNumbers.A1 + i; info.IsProcessComplete = false; if (mappingData[i] == '0') { info.IsStatus = WaferInfo.WaferStatus.Empty; } else if (mappingData[i] == '1') { info.IsStatus = WaferInfo.WaferStatus.Exist; } else if (mappingData[i] == 'C') { info.IsStatus = WaferInfo.WaferStatus.Leaning; } else if (mappingData[i] == 'D') { info.IsStatus = WaferInfo.WaferStatus.Overlap; } info.RecipeName = _equipment.port1Foup.foupRecipe.RecipeNames[i]; _equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i, info); } } else { IsMappingError = true; for (int i = 0; i < 25; i++) { WaferInfo info = _equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i); info.IsStatus = WaferInfo.WaferStatus.Empty; info.SourceNumber = WaferInfoManager.WaferNumbers.A1 + i; _equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i, info); } } } private void ReadPort2MappingResult() { string mappingData = _equipment.robot.ReadMappingResult(); if (mappingData.Length == 25) { IsMappingError = false; for (int i = 0; i < 25; i++) { WaferInfo info = _equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.B1 + i); info.SourceNumber = WaferInfoManager.WaferNumbers.B1 + i; info.IsProcessComplete = false; if (mappingData[i] == '0') { info.IsStatus = WaferInfo.WaferStatus.Empty; } else if (mappingData[i] == '1') { info.IsStatus = WaferInfo.WaferStatus.Exist; } else if (mappingData[i] == 'C') { info.IsStatus = WaferInfo.WaferStatus.Leaning; } else if (mappingData[i] == 'D') { info.IsStatus = WaferInfo.WaferStatus.Overlap; } info.RecipeName = _equipment.port2Foup.foupRecipe.RecipeNames[i]; _equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.B1 + i, info); } } else { IsMappingError = true; for (int i = 0; i < 25; i++) { WaferInfo info = _equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.B1 + i); info.IsStatus = WaferInfo.WaferStatus.Empty; info.SourceNumber = WaferInfoManager.WaferNumbers.B1 + i; _equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i, info); } } } public void Mapping(int stage) { Write($"MAP {stage}"); } public string ReadMappingResult() { string receivedData; WriteRead("MLD", out receivedData); //0 없음 1 있음 C 기울어짐 D 겹침 //000000000000000000000000000000000000000000 return receivedData; } public void Home() { Write("ORG"); } public void ServoOn() { Write("ENABLE"); } public void ServoOff() { Write("DISABLE"); } public void MoveRelative(double x, double y, double z) { Write($"LMI {x},{y},{z}"); } public void MoveAbsolute(double x, double y, double z) { Write($"LMA {x},{y},{z}"); } //==================================================== //=================== Speed ====================== public void ReadMappingSpeed() { string receivedData; WriteRead("RMPS", out receivedData); //RMPS V01=030 } public void SetMappingSpeed(int speed) { Write($"WMPS {speed}"); } /// /// /// /// 1 -> 0.001mm public void SetWaferThickness(int thickness) { Write($"WWTH {thickness}"); //100 -> 1mm } public void SetWaferCrossCheckStandard(int standard) { Write($"WSCT {standard}"); // % } public void SetWaferDoubleCheckStandard(int standard) { Write($"WSDT {standard}"); // % } //==================================================== //=================== Monitor ======================= public void ReadErrorCode() { string receivedData; if (WriteRead("ERR", out receivedData)) { AlarmCode = receivedData; if (receivedData != "0") { _equipment.alarmManager.Occur(SA_LTT.AlarmCode.AL_0200_ROBOT_ALARM_OCCURED); EquipmentLogManager.Instance.WriteProcessLog($"Robot alarm code : {receivedData}"); IsError = true; ReadErrorDescription(); } else { AlarmDescription = string.Empty; IsError = false; } } //ERR 201 } public void ReadErrorDescription() { string receivedData; WriteRead("ERD", out receivedData); AlarmDescription = receivedData; //ERD -1027*JOINT-OUT-OF-RANGE* 1:2 ORG } public void ErrorClear() { Write("DRT"); } public void ReadPowerState() { string receivedData; WriteRead("RPS", out receivedData); string[] splitData = receivedData.Split('='); PowerState powerState; if(splitData.Length == 2 && Enum.TryParse(splitData[1], out powerState)) { PowerStatus = powerState; } } public void ReadPosition() { string receivedData; WriteRead("NMPS", out receivedData); string[] splitData = receivedData.Split(','); // +0116.791,+0025.006,-0028.258,+0000.000 if (splitData.Length == 4) { PositionT = double.Parse(splitData[0]); PositionZ = double.Parse(splitData[1]); PositionR = double.Parse(splitData[2]); PositionF = double.Parse(splitData[3]); } else { } } public void EMS() { Write("AES"); } public void ReadSystemSpeed() { string receivedData; WriteRead("RSSP", out receivedData); //RSPD V01 = 100 } //==================================================== //=================== Setup ======================= public void SetSystemSpeed(int speed) { Write($"WSSP {speed}"); } public void ReadJogSpeed() { string receivedData; WriteRead("RJSS", out receivedData); //RJSS V01=030,V02=30 } public void ReadWaferDetected() { string receivedData; WriteRead("RIDI 1", out receivedData); int dec = 0; if (receivedData != string.Empty) { try { dec = Convert.ToInt32(receivedData, 16); BitArray bitarray = new BitArray(new byte[] { Convert.ToByte(dec) }); IsWaferExist = bitarray[0]; } catch(Exception e) { } } else { } } public void ReadVacuumOn() { string receivedData; WriteRead("RIDI 5", out receivedData); int dec = 0; if (receivedData != string.Empty) { try { dec = Convert.ToInt32(receivedData, 16); BitArray bitarray = new BitArray(new byte[] { Convert.ToByte(dec) }); IsVacuumOn = !bitarray[0]; } catch (Exception e) { } } else { } } public void ReadRun() { string receivedData; WriteRead("NIDO 1", out receivedData); int dec = 0; if (receivedData != string.Empty) { try { dec = Convert.ToInt32(receivedData, 16); BitArray bitarray = new BitArray(new byte[] { Convert.ToByte(dec) }); IsRun = bitarray[4]; } catch (Exception e) { } } else { } } public void SetJogSpeed(int speed) { Write($"WJSS {speed}"); } public void ReadHomeSpeed() { string receivedData; WriteRead("RHMS", out receivedData); //RHMS V01=020,V02=20 } public void SetHomeSpeed(int speed) { Write($"WHMS {speed}"); } public void ReadWaferOnSpeed() { string receivedData; WriteRead("RHIS", out receivedData); //RHIS V01=060,V02=060 } public void SetWaferOnSpeed(int speed) { Write($"WHIS {speed}"); } public void ReadWaferOffSpeed() { string receivedData; WriteRead("RLOS", out receivedData); //RLOS V01=020,V02=020 } public void SetWaferOffSpeed(int speed) { Write($"WLOS {speed}"); } public void ReadZSpeed() { string receivedData; WriteRead("RZSP", out receivedData); //RZSP V01=015,V02=015 //UP 속도 , DOWN 속도 } public void SetZSpeed(int upSpeed, int downSpeed) { Write($"WZSP {upSpeed},{downSpeed}"); } public void EmergencyStop() { Write("AES"); } public void Pause() { Write("PAUSE 1"); } public void Run() { Write("PAUSE 0"); } /// /// 지정된 채널 번호 부터 m개의 채널 값을 2자리수의 16진로 받습니다. /// 1개의 채널은 8개의 I/O bit 를 포함합니다. /// PRC Input I/O Map 은 I/O 번호가 10001 번부터 시작합니다. /// public void ReadInput() { string receivedData; WriteRead("NIDI", out receivedData); } /// /// 지정된 채널 번호 부터 m개의 채널 값을 2자리수의 16진로 받습니다. /// 1개의 채널은 8개의 I/O bit 를 포함합니다. /// PRC Output I/O Map 은 I/O 번호가 13 번부터 시작합니다 /// public void ReadOutput() { string receivedData; WriteRead("NIDO", out receivedData); } //==================================================== public new bool Write(string command) { base.Write(command + $"\r\n"); return true; } public bool WriteRead(string command, out string receivedData) { string data = base.WriteRead(command + $"\r\n"); if (data.StartsWith(command.Split(' ')[0])) { receivedData = data.Remove(0, command.Split(' ')[0].Length + 1).Replace($"\r\n", ""); return true; } else { receivedData = string.Empty; return false; } } } enum RobotAlarm { ERR_NOT_HOMED = 2, ERR_EMERGENCY = 4, ERR_MOTOR_ERROR = 12, ERR_WAIT_TIMEOUT = 190, ENCODER_RESET_TIMEOUT = 193, ERR_INTERLOCK = 194, ERR_DATA_RANGE = 201, ERR_WAFER_BEFORE_GET = 202, ERR_NO_WAFER_BEFORE_PUT = 203, ERR_NO_WAFER_AFTER_GET = 204, ERR_WAFER_AFTER_PUT = 205, ERR_NO_WAFER_DURING_GET = 206, ERR_WAFER_DURING_PUT = 207, ERR_NOT_HOMED_1 = 208, ERR_NOT_SUPPORTED_FUNC = 209, ERR_WAFER_OUT = 210, ERR_WAFER_SLIP = 211, OVER_WAFER_DURING_GET = 212, ERR_PLATE_CHECK = 213, ERR_PUSHER_SPEED_HIGH = 214, ERR_NOT_CORRECT_BLADE_POS = 241, ERR_MAPPING_IS_NOT_PERFORMED = 251, ERR_NO_MAPPING_DATA = 252, ALREADY_LATCH_BLOCKED = 253, ERR_CANNOT_UNGRIP = 300, ERR_INVALID_COMMAND = 301, ERR_INVALID_DATA = 311, ERR_INVALID_STATION = 312, ERR_INVALID_HAND = 313, ERR_INVALID_SLOT = 314, ERR_INVALID_TEACHING_INDEX = 315, ERR_INVALID_PD_INDEX = 316, ERR_INVALID_HAND_TYPE = 317, ERR_BOX_NOEXIT_ERORR = 318, ERR_INVALID_OFFSET = 319, ERR_INVALID_COORDINATE_TYPE = 321, ERR_INVALID_ARGUMENT = 331, ERR_INVALID_FORMAT = 333, ERR_INVALID_LOCATION_FORMAT = 334, ERR_INVALID_PROFILE_FORMAT = 335, ERR_WRONG_PD_COMMAND = 341, ERR_WRONG_AWC_DATA = 342, ERR_NO_AWC_STATION = 343, ERR_WRONG_LATCH_DATA = 344, ERR_NO_LATCH_DATA = 345, ERR_NO_DATA = 351, ERR_NOT_HOME = 352, ERR_CANNOT_RETRACT_ARM = 353, ERR_VACUUM_DETECTING_ERORR = 354, ERR_NO_BOX = 355, ERR_UPGRIP = 356, ERR_DOUBLEBOXCHECH = 357, ERR_ORIGINMANUALLY = 359, ERR_NOTSUPPLY_AIR = 360, ERR_NOW_ON_MOVE = 371, ERR_NOT_READYPOS = 361, Z_POSITION_ERR_DETECTED = 372, ERR_FLIP_TURN_INTERLOCK = 378, ERR_CONTROL_BOX_FAN = 380, ERR_ROBOT_FAN = 381, ERR_AIRSTOP_ERROR = 400, ERR_RECEIVEBUF_FULL = 401, ERR_SENDBUF_FULL = 402, IO_RECEIVE_ERROR = 403, } }