using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Venus_RT.Devices; using MECF.Framework.Common.Routine; using System.Diagnostics; using System.Collections.Generic; using Venus_Core; using System; using Venus_Unity; using MECF.Framework.Common.DBCore; using System.Text; namespace Venus_RT.Modules.PMs { class GasBoxLeakCheckRoutine : PMRoutineBase, IRoutine { private enum LeakCheckStep { kPumpToBasePressure, kPumpingDelay, kLeakCheckDelay, kEnd, } public double LeakRate { get; private set; } private int _basePressure = 100; private int _leakcheckPumpTime = 180; private int _leakcheckHoldTime = 300; private double _startPressure = 0; private double _endPressure = 0; private double _leakRate = 30.0; private double _leakCheckBasePressure = 1; private List _gasLineNums = new List(); Stopwatch _leakCheckTimer = new Stopwatch(); bool isCheckVentLine; PMLeakCheckResult pMLeakCheckResult; Stopwatch _routineTimer = new Stopwatch(); StringBuilder gasLines=new StringBuilder(); public string CurrentStep; PressureType _pressureType = PressureType.mTorr; private bool _readPenningGuagePressureFlag; private double _penningGuagePressure; public GasBoxLeakCheckRoutine(JetPMBase chamber) : base(chamber) { Name = "GasBox Leakcheck"; if (chamber.ChamberType == JetChamber.Kepler2200A || chamber.ChamberType == JetChamber.Kepler2200B) { _pressureType = PressureType.Pa; } } public RState Start(params object[] objs) { if (CheckLid() && CheckSlitDoor() && CheckTurboPump()) { CurrentStep = "Pump To BasePressure"; Reset(); _basePressure = SC.GetValue($"{Module}.Pump.PumpBasePressure"); //_leakcheckPumpTime = SC.GetValue($"{Module}.Pump.LeakCheckPumpingTime"); //_leakcheckHoldTime = SC.GetValue($"{Module}.Pump.LeakCheckHoldTime"); //_leakRate = SC.GetValue($"{Module}.Pump.LeakRate"); _leakcheckPumpTime = (int)(objs[0]); _leakcheckHoldTime = (int)(objs[1]); _leakRate = (double)(objs[2]); _leakCheckBasePressure = SC.GetValue($"{Module}.Pump.LeakCheckBasePressure"); // Extract line numbers which need do Leakcheck from config file _gasLineNums.Clear(); //var lineNums = SC.GetStringValue($"{Module}.Pump.LeakCheckGasLineNums").Split(','); var lineNums = objs[3].ToString().Split(','); int nNum; int allGas=8; if (_chamber.ChamberType == JetChamber.Kepler2200A || _chamber.ChamberType == JetChamber.Kepler2200B) { allGas = 8; }else if (_chamber.ChamberType == JetChamber.VenusSE || _chamber.ChamberType == JetChamber.VenusDE) { allGas = 10; } foreach (string num in lineNums) { if(int.TryParse(num, out nNum)) { if(nNum > 0 && nNum <= allGas && !_gasLineNums.Contains(nNum)) { _gasLineNums.Add(nNum); } } } isCheckVentLine = (bool)objs[4]; pMLeakCheckResult = new PMLeakCheckResult(); pMLeakCheckResult.CheckMode = objs[5].ToString(); if (_gasLineNums.Count == 0 && isCheckVentLine==false) { Stop($"No Gasline need do LeakCheck, please check the config item{Module}.Pump.LeakCheckGasLineNums"); return RState.Failed; } gasLines.Clear(); PreSetValves(); pMLeakCheckResult.CheckDate = DateTime.Now.ToString("yyyyMMddHHmm"); _routineTimer.Restart(); Reset(); return Runner.Start(Module, Name); } return RState.Failed; } public RState Monitor() { Runner.Wait(LeakCheckStep.kPumpToBasePressure, ()=> { return _chamber.ProcessPressure <= _basePressure; }) .Run(LeakCheckStep.kPumpingDelay, LeakCheckPumping, PumpingDelay, _delay_10d) .Run(LeakCheckStep.kLeakCheckDelay, StartLeakCheck, _leakcheckHoldTime * 1000) .End(LeakCheckStep.kEnd, CalcLeakCheckResult, _delay_50ms); return Runner.Status; } public void Abort() { CloseAllValves(); } private bool LeakCheckPumping() { CurrentStep = "Check Pump"; foreach (var num in _gasLineNums) { var _MfcN2Scale = SC.GetValue($"{Module}.MfcGas{num}.MfcN2Scale"); var _MfcScaleFactor = SC.GetValue($"{Module}.MfcGas{num}.MfcScaleFactor"); var _GasFlow = _MfcN2Scale * _MfcScaleFactor; _chamber.FlowGas(num-1, _GasFlow); gasLines.Append($"Gas{num},"); } if (_gasLineNums.Contains(1)) { _chamber.OpenValve(ValveType.PV11, true); } if (_gasLineNums.Contains(2)) { _chamber.OpenValve(ValveType.PV21, true); } if (_gasLineNums.Contains(3)) { _chamber.OpenValve(ValveType.PV31, true); } if (_gasLineNums.Contains(4)) { _chamber.OpenValve(ValveType.PV41, true); } if (_gasLineNums.Contains(5)) { _chamber.OpenValve(ValveType.PV51, true); } if (_gasLineNums.Contains(6)) { _chamber.OpenValve(ValveType.PV61, true); } if (_gasLineNums.Contains(7)) { _chamber.OpenValve(ValveType.PV71, true); } if (_gasLineNums.Contains(8)) { _chamber.OpenValve(ValveType.PV81, true); } if (_gasLineNums.Contains(9)) { _chamber.OpenValve(ValveType.PV91, true); } if (_gasLineNums.Contains(10)) { _chamber.OpenValve(ValveType.PVA1, true); } if (_gasLineNums.Contains(11)) { _chamber.OpenValve(ValveType.PVB1, true); } if (_gasLineNums.Contains(12)) { _chamber.OpenValve(ValveType.PVC1, true); } //2023/04/25添加vent line漏气检测 if (isCheckVentLine == true) { _chamber.OpenValve(ValveType.PVN21, true); _chamber.OpenValve(ValveType.PVN22, true); _chamber.OpenValve(ValveType.N2, true); gasLines.Append("VentLine"); } _leakCheckTimer.Restart(); return true; } private bool PumpingDelay() { if (_leakCheckTimer.ElapsedMilliseconds > (_leakcheckPumpTime - 5) * 1000 && _readPenningGuagePressureFlag == false) { _penningGuagePressure = _chamber.PenningGuagePressure; pMLeakCheckResult.BasePressure = _penningGuagePressure; _readPenningGuagePressureFlag = true; } if (_leakCheckTimer.ElapsedMilliseconds >= _leakcheckPumpTime * 1000) { if (_chamber.ProcessPressure <= _leakCheckBasePressure) return true; else { Runner.Stop($"GasBox Leakcheck失败, 工艺压力 [{_chamber.ProcessPressure}]{_pressureType}, 高于LeakCheck Base Pressure: [{_leakCheckBasePressure}] {_pressureType}"); } } return false; } private bool StartLeakCheck() { CurrentStep = "Leak Check"; _startPressure = _chamber.ProcessPressure; pMLeakCheckResult.StartPressure = _startPressure; Notify($"PM 压力开始值 {_startPressure} {_pressureType}"); _chamber.TurnPendulumValve(false); return true; } private bool CalcLeakCheckResult() { _endPressure = _chamber.ProcessPressure; pMLeakCheckResult.EndPressure = _endPressure; LeakRate = (_endPressure - _startPressure) * 60.0 / _leakcheckHoldTime; pMLeakCheckResult.LeakRate = LeakRate; if (LeakRate < _leakRate) { Notify($"GasBox Leakcheck完成, 压力结束值: {_startPressure} {_pressureType}, 漏率:{LeakRate} {_pressureType}/min"); pMLeakCheckResult.Result = "Success"; } else { Stop($"GasBox Leakcheck失败, 腔体漏率 [{LeakRate}] {_pressureType}/min, 高于 [{_leakRate}] {_pressureType}/min"); pMLeakCheckResult.Result = "Fail"; } if (RtInstance.ConfigType == ConfigType.Kepler2200) { LeakCheckDataRecorder.AddKepler2200(_leakcheckHoldTime, pMLeakCheckResult.BasePressure, Math.Round(_startPressure, 5), Math.Round(_endPressure, 5), LeakRate, pMLeakCheckResult.Result, pMLeakCheckResult.CheckMode, _chamber.Name, gasLines.ToString()); } else { //LeakCheckDataRecorder.Add(_leakcheckHoldTime, Math.Round(_startPressure, 1), Math.Round(_endPressure, 1), LeakRate, pMLeakCheckResult.Result, "ChamberOnly", _chamber.Name); LeakCheckDataRecorder.Add(_leakcheckHoldTime, Math.Round(_startPressure, 5), Math.Round(_endPressure, 5), LeakRate, pMLeakCheckResult.Result, pMLeakCheckResult.CheckMode, _chamber.Name, gasLines.ToString()); } _chamber.StopAllGases(); _chamber.TurnPendulumValve(true); _chamber.OpenValve(ValveType.PV11, false); _chamber.OpenValve(ValveType.PV21, false); _chamber.OpenValve(ValveType.PV31, false); _chamber.OpenValve(ValveType.PV41, false); if (_gasLineNums.Contains(5)) { _chamber.OpenValve(ValveType.PV51, false); } if (_gasLineNums.Contains(6)) { _chamber.OpenValve(ValveType.PV61, false); } if (_gasLineNums.Contains(7)) { _chamber.OpenValve(ValveType.PV71, false); } if (_gasLineNums.Contains(8)) { _chamber.OpenValve(ValveType.PV81, false); } if (_gasLineNums.Contains(9)) { _chamber.OpenValve(ValveType.PV91, false); } if (_gasLineNums.Contains(10)) { _chamber.OpenValve(ValveType.PVA1, false); } if (_gasLineNums.Contains(11)) { _chamber.OpenValve(ValveType.PVB1, false); } if (_gasLineNums.Contains(12)) { _chamber.OpenValve(ValveType.PVC1, false); } if (_chamber.ChamberType==JetChamber.VenusSE|| _chamber.ChamberType == JetChamber.VenusDE) { _chamber.OpenValve(ValveType.PVN22, false); } pMLeakCheckResult.LeakCheckTime = (int)_routineTimer.ElapsedMilliseconds / 1000; //SerializeHelper.Instance.WriteToJsonFile(pMLeakCheckResult, $"LeakCheck/PM/{DateTime.Now.ToString("yyyyMMddHHmm")}.json"); return true; } private void PreSetValves() { _chamber.OpenValve(ValveType.FastPump, false); if(_chamber.ChamberType!=JetChamber.VenusDE) { _chamber.OpenValve(ValveType.SoftPump, false); } _chamber.OpenValve(ValveType.SoftPump, false); _chamber.OpenValve(ValveType.TurboPumpPumping, true); _chamber.OpenValve(ValveType.Guage, true); _chamber.OpenValve(ValveType.GasFinal, true); _chamber.TurnPendulumValve(true); _chamber.StopAllGases(); _chamber.OpenValve(ValveType.PV11, false); _chamber.OpenValve(ValveType.PV21, false); _chamber.OpenValve(ValveType.PV31, false); _chamber.OpenValve(ValveType.PV41, false); if (_gasLineNums.Contains(5)) { _chamber.OpenValve(ValveType.PV51, false); } if (_gasLineNums.Contains(6)) { _chamber.OpenValve(ValveType.PV61, false); } if (_gasLineNums.Contains(7)) { _chamber.OpenValve(ValveType.PV71, false); } if (_gasLineNums.Contains(8)) { _chamber.OpenValve(ValveType.PV81, false); } if (_gasLineNums.Contains(9)) { _chamber.OpenValve(ValveType.PV91, false); } if (_gasLineNums.Contains(10)) { _chamber.OpenValve(ValveType.PVA1, false); } if (_gasLineNums.Contains(11)) { _chamber.OpenValve(ValveType.PVB1, false); } if (_gasLineNums.Contains(12)) { _chamber.OpenValve(ValveType.PVC1, false); } } } }