using SA_LTT; using SA_LTT.Info.WaferInfo; using System; using System.Drawing; using System.Threading; using System.Windows.Forms; using static SA_LTT.Info.WaferInfo.WaferInfoManager; using static SA_LTT.Module.Robot; namespace SA_LTT_UI.Viewer { public partial class RobotViewer : Form { enum MoveSteps { Wait, Get, GetWait, Put, PutWait, End } MainFrame _mainFrame; Thread t_UIUpdate; Thread t_Move; int mappingPort = 1; DateTime _tactTimeCheck = DateTime.Now; TimeSpan _mappingTime = new TimeSpan(); bool _updateCheck; private MoveSteps _moveStep; protected override CreateParams CreateParams { get { CreateParams MyCp = base.CreateParams; MyCp.ExStyle |= 0x02000000; return MyCp; } } public RobotViewer(MainFrame mainFrame) { InitializeComponent(); _mainFrame = mainFrame; StageComboBoxInit(); t_UIUpdate = new Thread(UIUpdateTh); t_UIUpdate.Start(); t_Move = new Thread(MoveThread); t_Move.Start(); } private void StageComboBoxInit() { string[] stageList = Enum.GetNames(typeof(StageList)); cbb_Stage.Items.Clear(); cbb_Stage.Items.AddRange(stageList); cbb_Stage.SelectedIndex = 0; cbb_StartStage.Items.Clear(); cbb_StartStage.Items.AddRange(stageList); cbb_StartStage.SelectedIndex = 0; cbb_EndStage.Items.Clear(); cbb_EndStage.Items.AddRange(stageList); cbb_EndStage.SelectedIndex = 0; } private void SlotComboBoxRefresh(int stageIndex) { cbb_Slot.Items.Clear(); switch(stageIndex) { case 1: { for(int i = 0; i < 25; i++) { cbb_Slot.Items.Add(WaferNumbers.A1 + i); } break; } case 2: { for (int i = 0; i < 25; i++) { cbb_Slot.Items.Add(WaferNumbers.B1 + i); } break; } default: { cbb_Slot.Items.Add(1); break; } } cbb_Slot.SelectedIndex = 0; } private void StartSlotComboBoxRefresh(int stageIndex) { cbb_StartSlot.Items.Clear(); switch (stageIndex) { case 1: { for (int i = 0; i < 25; i++) { cbb_StartSlot.Items.Add(WaferNumbers.A1 + i); } break; } case 2: { for (int i = 0; i < 25; i++) { cbb_StartSlot.Items.Add(WaferNumbers.B1 + i); } break; } default: { cbb_StartSlot.Items.Add(1); break; } } cbb_StartSlot.SelectedIndex = 0; } private void EndSlotComboBoxRefresh(int stageIndex) { cbb_EndSlot.Items.Clear(); switch (stageIndex) { case 1: { for (int i = 0; i < 25; i++) { cbb_EndSlot.Items.Add(WaferNumbers.A1 + i); } break; } case 2: { for (int i = 0; i < 25; i++) { cbb_EndSlot.Items.Add(WaferNumbers.B1 + i); } break; } default: { cbb_EndSlot.Items.Add(1); break; } } cbb_EndSlot.SelectedIndex = 0; } private void UIUpdateTh() { while (_mainFrame.equipment.IsDisposed == false) { Thread.Sleep(10); if (_updateCheck == false) { _updateCheck = true; UIUpdate(); } } } private void UIUpdate() { if (InvokeRequired) { BeginInvoke(new UIUpdateDelegate(UIUpdate)); return; } else { try { lb_PortName.Text = _mainFrame.equipment.robot.PortName; lb_PortName.BackColor = _mainFrame.equipment.robot.IsOpen ? Color.Lime : Color.Red; lb_PowerState.Text = $"Power State - {_mainFrame.equipment.robot.PowerStatus}"; lb_PowerState.BackColor = _mainFrame.equipment.robot.IsServoOn ? Color.Lime : Color.Red; tb_ErrorCode.Text = _mainFrame.equipment.robot.AlarmCode; tb_ErrorDescription.Text = _mainFrame.equipment.robot.AlarmDescription; tb_PositionT.Text = _mainFrame.equipment.robot.PositionT.ToString(); tb_PositionZ.Text = _mainFrame.equipment.robot.PositionZ.ToString(); tb_PositionR.Text = _mainFrame.equipment.robot.PositionR.ToString(); tb_PositionF.Text = _mainFrame.equipment.robot.PositionF.ToString(); lb_WaferDetected.BackColor = _mainFrame.equipment.robot.IsWaferExist ? Color.Lime : Color.Red; lb_Vacuum.BackColor = _mainFrame.equipment.robot.IsVacuumOn ? Color.Lime : Color.Red; lb_IsRun.BackColor = _mainFrame.equipment.robot.IsRun ? Color.Lime : Color.Red; lb_IsRunEnable.BackColor = _mainFrame.equipment.robot.IsRunEnable ? Color.Lime : Color.Red; tb_MappingTime.Text = $"{_mappingTime.TotalSeconds:F3} s"; tb_GetTime.Text = $"{_mainFrame.equipment.robot.GetTactTime.TotalSeconds:F3} s"; tb_PutTime.Text = $"{_mainFrame.equipment.robot.PutTactTime.TotalSeconds:F3} s"; if (_mainFrame.equipment.robot.IsRunEnable && (_mainFrame.equipment.ProcessStatus == ProcessStatus.Idle || _mainFrame.equipment.ProcessStatus == ProcessStatus.Pause)) { if (gb_Control.Enabled == false) { gb_Control.Enabled = true; } if (gb_Move.Enabled == false) { gb_Move.Enabled = true; } } else { if(gb_Control.Enabled) { gb_Control.Enabled = false; } if (gb_Move.Enabled) { gb_Move.Enabled = false; } } } catch (Exception e) { EquipmentLogManager.Instance.WriteExceptionLog(e.StackTrace); } finally { _updateCheck = false; } } } private void RobotViewer_FormClosing(object sender, FormClosingEventArgs e) { e.Cancel = true; this.Hide(); } private void btn_GetReady_Click(object sender, EventArgs e) { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_Stage.Text, out stage)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text} : {stage.ToString()} {cbb_Slot.SelectedIndex + 1}"); _mainFrame.equipment.robot.GetReady(stage, cbb_Slot.SelectedIndex + 1); } } private void btn_ErrorClear_Click(object sender, EventArgs e) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _mainFrame.equipment.robot.ErrorClear(); } private void btn_Home_Click(object sender, EventArgs e) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _mainFrame.equipment.robot.Home(); } private void btn_PutReady_Click(object sender, EventArgs e) { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_Stage.Text, out stage)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text} : {stage.ToString()} {cbb_Slot.SelectedIndex + 1}"); _mainFrame.equipment.robot.PutReady(stage, cbb_Slot.SelectedIndex + 1); } } private void MappingTh() { _tactTimeCheck = DateTime.Now; _mainFrame.equipment.robot.Mapping(mappingPort); DateTime checkTime = DateTime.Now; //Mapping 시작 후 1초 대기 or Run 확인. while(true) { if (_mainFrame.equipment.robot.IsRun) { break; } else { if ((DateTime.Now - checkTime).TotalSeconds > 1) break; } } while(true) { //Run 종료 후 Mapping 결과 받기 시작. if(_mainFrame.equipment.robot.IsRun == false) { if (mappingPort == 1) ReadPort1MappingResult(); else if (mappingPort == 2) ReadPort2MappingResult(); break; } } _mappingTime = DateTime.Now - _tactTimeCheck; } private void ReadPort1MappingResult() { string mappingData = _mainFrame.equipment.robot.ReadMappingResult(); if (mappingData.Length == 25) { for (int i = 0; i < 25; i++) { WaferInfo info = _mainFrame.equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i); info.SourceNumber = WaferInfoManager.WaferNumbers.A1 + i; 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; } _mainFrame.equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.A1 + i, info); } } } private void ReadPort2MappingResult() { string mappingData = _mainFrame.equipment.robot.ReadMappingResult(); if (mappingData.Length == 25) { for (int i = 0; i < 25; i++) { WaferInfo info = _mainFrame.equipment.waferInfoManager.GetWaferInfo(WaferInfoManager.WaferNumbers.B1 + i); info.SourceNumber = WaferInfoManager.WaferNumbers.B1 + i; 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; } _mainFrame.equipment.waferInfoManager.SetWaferInfo(WaferInfoManager.WaferNumbers.B1 + i, info); } } } private void MoveSequence() { if (InvokeRequired) { BeginInvoke(new UIUpdateDelegate(MoveSequence)); return; } else { switch (_moveStep) { case MoveSteps.Wait: { break; } case MoveSteps.Get: { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_StartStage.Text, out stage)) { if (_mainFrame.equipment.robot.Get(stage, cbb_StartSlot.SelectedIndex + 1)) { _moveStep = MoveSteps.GetWait; } else { MessageBoxPad mbp = new MessageBoxPad("Get 할 수 없는 상태 입니다."); mbp.Show(); _moveStep = MoveSteps.End; } } break; } case MoveSteps.GetWait: { if (_mainFrame.equipment.robot.IsRunEnable) { if (_mainFrame.equipment.robot.IsWaferExist) { _moveStep = MoveSteps.Put; } else { MessageBoxPad mbp = new MessageBoxPad("Wafer를 확인해 주세요 !"); mbp.Show(); _moveStep = MoveSteps.End; } } break; } case MoveSteps.Put: { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_EndStage.Text, out stage)) { if (_mainFrame.equipment.robot.Put(stage, cbb_EndSlot.SelectedIndex + 1)) { _moveStep = MoveSteps.PutWait; } else { MessageBoxPad mbp = new MessageBoxPad("Put 할 수 없는 상태 입니다."); mbp.Show(); _moveStep = MoveSteps.End; } } break; } case MoveSteps.PutWait: { if (_mainFrame.equipment.robot.IsRunEnable) { if (_mainFrame.equipment.robot.IsWaferExist == false) { _moveStep = MoveSteps.End; } else { MessageBoxPad mbp = new MessageBoxPad("Wafer를 확인해 주세요 !"); mbp.Show(); _moveStep = MoveSteps.End; } } break; } case MoveSteps.End: { _moveStep = MoveSteps.Wait; break; } } } } private void MoveThread() { while(_mainFrame.equipment.IsDisposed == false) { Thread.Sleep(50); MoveSequence(); } } private void btn_Get_Click(object sender, EventArgs e) { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_Stage.Text, out stage)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text} : {stage.ToString()} {cbb_Slot.SelectedIndex + 1}"); _mainFrame.equipment.robot.Get(stage, cbb_Slot.SelectedIndex + 1); } } private void btn_Put_Click(object sender, EventArgs e) { StageList stage = StageList.Port1; if (Enum.TryParse(cbb_Stage.Text, out stage)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text} : {stage.ToString()} {cbb_Slot.SelectedIndex + 1}"); _mainFrame.equipment.robot.Put(stage, cbb_Slot.SelectedIndex + 1); } } private void cbb_Stage_SelectedIndexChanged(object sender, EventArgs e) { SlotComboBoxRefresh(cbb_Stage.SelectedIndex + 1); } private void btn_ServoOn_Click(object sender, EventArgs e) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _mainFrame.equipment.robot.ServoOn(); } private void btn_ServoOff_Click(object sender, EventArgs e) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _mainFrame.equipment.robot.ServoOff(); } private void btn_EMO_Click(object sender, EventArgs e) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _mainFrame.equipment.robot.EMS(); } private void btn_Port1Mapping_Click(object sender, EventArgs e) { if(_mainFrame.equipment.robot.MappingSeq(1)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); } } private void btn_Port2Mapping_Click(object sender, EventArgs e) { if (_mainFrame.equipment.robot.MappingSeq(2)) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); } } private void cbb_StartStage_SelectedIndexChanged(object sender, EventArgs e) { StartSlotComboBoxRefresh(cbb_StartStage.SelectedIndex + 1); } private void cbb_EndStage_SelectedIndexChanged(object sender, EventArgs e) { EndSlotComboBoxRefresh(cbb_EndStage.SelectedIndex + 1); } //미리 인터락을 걸어 놓을까 ...? 아님 말까 private void btn_Move_Click(object sender, EventArgs e) { if (_moveStep == MoveSteps.Wait) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _moveStep = MoveSteps.Get; } else { MessageBoxPad mbp = new MessageBoxPad("Move 진행 중 입니다."); mbp.Show(); } } private void btn_MoveStop_Click(object sender, EventArgs e) { if (_moveStep != MoveSteps.Wait) { EquipmentLogManager.Instance.WriteButtonLog($"{this.Name} : {((Control)sender).Text}"); _moveStep = MoveSteps.End; } } } }