using System; using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using SA_LTT.Module; using System.Threading; using SA_LTT_UI.Viewer; using SA_LTT; using System.IO; using System.Text; namespace SA_LTT_UI.Screen { public partial class ScreenLaser : UserControl { private enum EnergyMeasurementSteps { Wait, PowerMeterInitialize, InitializeWait, MoveCenterPosition, CheckCenterPosition, MovePowerMeterPosition, CheckPowerMeterPosition, AttenuatorSet, CheckAttenuator, LaserOn, MeasurementStart, Measurement, MeasurementEnd, End, } // 여기에 따로 Attenuator Cal 만들지 ,, 아님 Sequecne에 있는거 땡겨 쓸지 ... MainFrame _mainFrame; Thread t_EnergyMeasurement; private float _energyMeasurementAngle = 0; private double _energyMeasurementTime = 0; private SequenceTimer _measurementTimer = new SequenceTimer(); private EnergyMeasurementSteps energyMeasurmentStep = EnergyMeasurementSteps.Wait; public ScreenLaser(MainFrame mainFrame) { InitializeComponent(); _mainFrame = mainFrame; InitializeChart(); _mainFrame.equipment.powerMeter.EnergyMeasured += PowerMeter_EnergyMeasured; t_EnergyMeasurement = new Thread(EnergyMeasurement); t_EnergyMeasurement.Start(); } private void EnergyMeasurement() { while (_mainFrame.IsDisposed == false) { Thread.Sleep(100); if (CheckEnergyMeasurementInterlock() == false) { EnergyMeasurementSequence(); } } } private bool CheckEnergyMeasurementInterlock() { bool isInterlock = false; if(energyMeasurmentStep < EnergyMeasurementSteps.MeasurementEnd) { if(_mainFrame.equipment.powerMeter.IsOpen == false) { //isInterlock = true; } if(_mainFrame.equipment.ProcessStatus != SA_LTT.ProcessStatus.Idle) { isInterlock = true; } } if(isInterlock) { if (energyMeasurmentStep != EnergyMeasurementSteps.Wait && energyMeasurmentStep < EnergyMeasurementSteps.MeasurementEnd) { energyMeasurmentStep = EnergyMeasurementSteps.MeasurementEnd; isInterlock = false; } } return isInterlock; } private void EnergyMeasurementSequence() { switch (energyMeasurmentStep) { case EnergyMeasurementSteps.Wait: { lb_EnergyMeasurementPowerMeterInitialize.BackColor = Color.Green; lb_EnergyMeasurementCenterPositionMove.BackColor = Color.Green; lb_EnergyMeasurementPowerMeterPositionMove.BackColor = Color.Green; lb_EnergyMeasurementAttenuatorSet.BackColor = Color.Green; lb_EnergyMeasurementLaserOn.BackColor = Color.Green; lb_EnergyMeasurementPowerMeasure.BackColor = Color.Green; lb_EnergyMeasurementLaserOff.BackColor = Color.Green; lb_EnergyMeasurementComplete.BackColor = Color.Green; break; } case EnergyMeasurementSteps.PowerMeterInitialize: { lb_EnergyMeasurementPowerMeterInitialize.BackColor = Color.Lime; lb_EnergyMeasurementCenterPositionMove.BackColor = Color.Green; lb_EnergyMeasurementPowerMeterPositionMove.BackColor = Color.Green; lb_EnergyMeasurementAttenuatorSet.BackColor = Color.Green; lb_EnergyMeasurementLaserOn.BackColor = Color.Green; lb_EnergyMeasurementPowerMeasure.BackColor = Color.Green; lb_EnergyMeasurementLaserOff.BackColor = Color.Green; lb_EnergyMeasurementComplete.BackColor = Color.Green; _measurementTimer.ReStart(); _mainFrame.equipment.powerMeter.ResetEnergyMeter(); energyMeasurmentStep = EnergyMeasurementSteps.InitializeWait; break; } case EnergyMeasurementSteps.InitializeWait: { if(_mainFrame.equipment.powerMeter.Enable && _mainFrame.equipment.powerMeter.CurrentMeasurementMode == PowerMeter.MeasurementMode.Energy) { if (_mainFrame.equipment.chamber.IsInposition) { if (_mainFrame.equipment.chamber.IsPowerMeterPosition) { lb_EnergyMeasurementPowerMeterPositionMove.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.AttenuatorSet; } else { energyMeasurmentStep = EnergyMeasurementSteps.MoveCenterPosition; } } } else { if (_measurementTimer.Seconds > 20) { MessageBox.Show("Measurement 초기화가 되지 않았습니다. energy meter를 확인 후 다시 시작해 주세요."); energyMeasurmentStep = EnergyMeasurementSteps.MeasurementEnd; } } break; } case EnergyMeasurementSteps.MoveCenterPosition: { if (_mainFrame.equipment.chamber.MoveCenterPosition()) { energyMeasurmentStep = EnergyMeasurementSteps.CheckCenterPosition; } break; } case EnergyMeasurementSteps.CheckCenterPosition: { if (_mainFrame.equipment.chamber.IsInposition) { if (_mainFrame.equipment.chamber.IsCenterPosition) { lb_EnergyMeasurementCenterPositionMove.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.MovePowerMeterPosition; } else { energyMeasurmentStep = EnergyMeasurementSteps.MoveCenterPosition; } } break; } case EnergyMeasurementSteps.MovePowerMeterPosition: { if (_mainFrame.equipment.chamber.MovePowerMeterPosition()) { energyMeasurmentStep = EnergyMeasurementSteps.CheckPowerMeterPosition; } break; } case EnergyMeasurementSteps.CheckPowerMeterPosition: { if (_mainFrame.equipment.chamber.IsInposition) { if (_mainFrame.equipment.chamber.IsPowerMeterPosition) { lb_EnergyMeasurementPowerMeterPositionMove.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.AttenuatorSet; } else { energyMeasurmentStep = EnergyMeasurementSteps.MovePowerMeterPosition; } } break; } case EnergyMeasurementSteps.AttenuatorSet: { _mainFrame.equipment.attenuator.MoveAbsolute(_energyMeasurementAngle); energyMeasurmentStep = EnergyMeasurementSteps.CheckAttenuator; break; } case EnergyMeasurementSteps.CheckAttenuator: { if (_mainFrame.equipment.attenuator.MotorState == Attenuator.MotorRunState.Stopped) { if (_mainFrame.equipment.attenuator.IsAttenuatorAngleCorrect(_energyMeasurementAngle)) { lb_EnergyMeasurementAttenuatorSet.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.LaserOn; } else { energyMeasurmentStep = EnergyMeasurementSteps.AttenuatorSet; } } break; } case EnergyMeasurementSteps.LaserOn: { if(_mainFrame.equipment.chamber.IsPowerMeterPosition) { _mainFrame.equipment.scanner.LaserOn(); _measurementTimer.ReStart(); lb_EnergyMeasurementLaserOn.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.MeasurementStart; } break; } case EnergyMeasurementSteps.MeasurementStart: { if(_mainFrame.equipment.scanner.IsLaserOn) { if (_measurementTimer.Seconds > _mainFrame.equipment.settingParameterManager.SettingParameter.EnergyMeterHeatingTime) { _mainFrame.equipment.powerMeter.ResetMeasurementsEnergy(); _measurementTimer.ReStart(); lb_EnergyMeasurementPowerMeasure.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.Measurement; } } else { energyMeasurmentStep = EnergyMeasurementSteps.LaserOn; } break; } case EnergyMeasurementSteps.Measurement: { lb_EnergyMeasurementPowerMeasure.BackColor = lb_EnergyMeasurementPowerMeasure.BackColor == Color.Lime ? Color.Green : Color.Lime; if (_measurementTimer.Seconds > _energyMeasurementTime || _mainFrame.equipment.chamber.IsPowerMeterPosition == false) { lb_EnergyMeasurementPowerMeasure.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.MeasurementEnd; } break; } case EnergyMeasurementSteps.MeasurementEnd: { _mainFrame.equipment.scanner.LaserOff(); lb_EnergyMeasurementLaserOff.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.End; break; } case EnergyMeasurementSteps.End: { lb_EnergyMeasurementComplete.BackColor = Color.Lime; energyMeasurmentStep = EnergyMeasurementSteps.Wait; break; } } } private void PowerMeter_EnergyMeasured(double energy) { if (energyMeasurmentStep <= EnergyMeasurementSteps.MeasurementStart) return; if (InvokeRequired) { BeginInvoke(new EnergyMeasuredEvent(PowerMeter_EnergyMeasured), energy); } else { Series Se_MeasurementPower = chart_EnergyMeasure.Series.FindByName("MeasurementPower"); int i = Se_MeasurementPower.Points.Count; double[] points = _mainFrame.equipment.powerMeter.MeasurementsEnergyPerUnitArea.ToArray(); for (; i < points.Length; i++) { double point = points[i]; if (point > chart_EnergyMeasure.ChartAreas[0].AxisY.Maximum) chart_EnergyMeasure.ChartAreas[0].AxisY.Maximum = point + (point * 0.1); if (point < chart_EnergyMeasure.ChartAreas[0].AxisY.Minimum) chart_EnergyMeasure.ChartAreas[0].AxisY.Minimum = point - (point * 0.1); Se_MeasurementPower.Points.AddXY(i, point); } tb_Count.Text = $"{Se_MeasurementPower.Points.Count}"; tb_Power.Text = $"{energy:F4}"; tb_Average.Text = $"{_mainFrame.equipment.powerMeter.MeasurementAverageEnergyPerUnitArea:F4}"; tb_Max.Text = $"{_mainFrame.equipment.powerMeter.MeasurementMaxEnergyPerUnitArea:F4}"; tb_Min.Text = $"{_mainFrame.equipment.powerMeter.MeasurementMinEnergyPerUnitArea:F4}"; } } private void InitializeChart() { chart_EnergyMeasure.Series.Clear(); chart_EnergyMeasure.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount; chart_EnergyMeasure.ChartAreas[0].AxisY.MajorGrid.Enabled = false; chart_EnergyMeasure.ChartAreas[0].AxisY.Maximum = -1; chart_EnergyMeasure.ChartAreas[0].AxisY.Minimum = 99; Series Se_LeakBeamPower = chart_EnergyMeasure.Series.Add("MeasurementPower"); Se_LeakBeamPower.ChartType = SeriesChartType.Line; Se_LeakBeamPower.Color = Color.LightGreen; Se_LeakBeamPower.MarkerSize = 1; } private void btn_AttenuatorCalSave_Click(object sender, EventArgs e) { } private void btn_AttenuatorCalReset_Click(object sender, EventArgs e) { } private void btn_EnergyMeasurementStart_Click(object sender, EventArgs e) { if (CheckEnergyMeasurementInterlock() == false && energyMeasurmentStep == EnergyMeasurementSteps.Wait) { if (_mainFrame.equipment.piLaser.CurrentPiLaserStatus.EnableLdd == false || _mainFrame.equipment.piLaser.CurrentPiLaserStatus.EnableShutter == false || _mainFrame.equipment.piLaser.CurrentPiLaserStatus.SetCurrent != _mainFrame.equipment.piLaser.CurrentPiLaserStatus.MaxCurrent) { string message = string.Empty; if (_mainFrame.equipment.piLaser.CurrentPiLaserStatus.EnableLdd == false) { message += "LDD가 닫혀있습니다. \r\n"; } if (_mainFrame.equipment.piLaser.CurrentPiLaserStatus.EnableShutter == false) { message += "Shutter가 닫혀있습니다. \r\n"; } if (_mainFrame.equipment.piLaser.CurrentPiLaserStatus.SetCurrent != _mainFrame.equipment.piLaser.CurrentPiLaserStatus.MaxCurrent) { message += $"Set current가 {_mainFrame.equipment.piLaser.CurrentPiLaserStatus.MaxCurrent}이 아닙니다. \r\n \r\n"; } if (MessageBox.Show(message + "진행 하시겠습니까?", "확인", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } } tb_Count.Text = "0"; tb_Power.Text = "0"; tb_Average.Text = "0"; tb_Max.Text = "0"; tb_Min.Text = "0"; InitializeChart(); energyMeasurmentStep = EnergyMeasurementSteps.PowerMeterInitialize; } else { Viewer.MessageBoxPad mbp = new Viewer.MessageBoxPad("Process status 가 Idle 일 때 진행할 수 있습니다."); mbp.Show(); } } private void btn_EnergyMeasurementStop_Click(object sender, EventArgs e) { if (CheckEnergyMeasurementInterlock() == false) { energyMeasurmentStep = EnergyMeasurementSteps.MeasurementEnd; } else { Viewer.MessageBoxPad mbp = new Viewer.MessageBoxPad("Process status 가 Idle 일 때 진행할 수 있습니다."); mbp.Show(); } } private void btn_SetEnergyMeasurementAttenuatorAngle_Click(object sender, EventArgs e) { float angle; float.TryParse(tb_SetEnergyMeasurementAttenuatorAngle.Text, out angle); tb_EnergyMeasurementAttenuatorAngle.Text = angle.ToString("F2"); _energyMeasurementAngle = angle; } private void btn_SetEnergyMeasurementMeasurementTime_Click(object sender, EventArgs e) { double time; double.TryParse(tb_SetEnergyMeasurementTime.Text, out time); tb_EnergyMeasurementTime.Text = time.ToString("F2"); _energyMeasurementTime = time; } private void btn_EnergyMeasurementSave_Click(object sender, EventArgs e) { SaveFileDialog dialog = new SaveFileDialog(); dialog.Title = "파일 저장하기"; dialog.Filter = "CSV 파일|*.csv|Text 파일|*.txt"; dialog.InitialDirectory = "D:\\"; dialog.FileName = $"EnergyMeasurementResult"; if (dialog.ShowDialog() != DialogResult.OK) return; string selectPath = dialog.FileName; try { using (StreamWriter outPutFile = new StreamWriter(selectPath, false, Encoding.Default)) { int i = 1; foreach (double energy in _mainFrame.equipment.powerMeter.MeasurementsEnergyPerUnitArea) { outPutFile.WriteLine($"{i},{energy}", Encoding.Default); i++; } } } catch(Exception ex) { } } } }