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,
}
}