123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Routine;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using MECF.Framework.Common.DBCore;
- using System;
- using System.Collections.Generic;
- using VirgoRT.Devices;
- using VirgoRT.Devices.IODevices;
- namespace VirgoRT.Modules.PMs
- {
- public enum VerifyMode
- {
- OnePoint,
- TenPoint,
- }
- class PMMfcVerificationRoutine : PMRoutineBase, IRoutine
- {
- enum RoutineStep
- {
- CheckNeedPumpDown1,
- CheckNeedPumpDown2,
- RunPumpRoutine1,
- RunPumpRoutine2,
- RunPumpRoutine3,
- CheckThrottleValveStatus,
- ClosePumpValve,
- GetBeginPressure,
- SetGasFlow,
- CalcMfcCalibration,
- Delay1,
- Delay2,
- StopGasFlow,
- CheckFinished,
- Loop,
- EndLoop,
- CheckFlowStable,
- }
- private readonly PumpDownRoutine _pumpdownRoutine;
- private int _paramContinuePumpTime;
- private double _beginPressure;
- private double _endPressure;
- private double _elapsedTime;
- private DeviceTimer _verificationDeviceTimer = new DeviceTimer();
- private int _mfcIndex;
- private float _mfcFlow;
- private double _flowTime;
- private double _mfcActualFlow;
- private double _getBeginPressureDelayTime;
- private double _maxPressure;
- private MfcBase1 _mfcDevice;
- private VerifyMode _paramMode;
- private Dictionary<int, float> _paramFlowSet = new Dictionary<int, float>();
- private Dictionary<float, Tuple<float, float>> _calibrationResult = new Dictionary<float, Tuple<float, float>>();
- private bool _isPumpDownNeed;
- private float _pressureStableTolerance = 2;//2mTorr
- private float _flowStableTolerance = 0.02f;//2%
- private int _stableTime = 1;//1s
- private double _chamberVolume;
- private double _gasTemperature;
- private double _leakRate;
- private double _maxDeviation;
- public PMMfcVerificationRoutine(JetPM chamber, PumpDownRoutine pumpDownRoutine) : base(chamber)
- {
- Name = "MFC Verification";
- bUINotify = true;
- _pumpdownRoutine = pumpDownRoutine;
- }
- internal void Init(string mfc, double flow, int flowCount)
- {
- int.TryParse(mfc.Replace("MFC", ""), out _mfcIndex);
- _mfcDevice = DEVICE.GetDevice<MfcBase1>($"{Module}.MfcGas{_mfcIndex}");
- _mfcIndex -= 1;//start from 0
- _mfcFlow = (float)flow;
- if (flowCount == 10)
- _paramMode = VerifyMode.TenPoint;
- else
- _paramMode = VerifyMode.OnePoint;
- }
- public Result Start(params object[] objs)
- {
- Reset();
- if (CheckLid() != Result.RUN)
- {
- return Result.FAIL;
- }
- if (CheckSlitDoor() != Result.RUN)
- {
- return Result.FAIL;
- }
- if (CheckDryPump() != Result.RUN)
- {
- return Result.FAIL;
- }
- _calibrationResult.Clear();
- _paramFlowSet.Clear();
- _chamberVolume = SC.GetValue<double>($"{Module}.MFCVerification.ChamberVolume");
- _gasTemperature = SC.GetValue<double>($"{Module}.MFCVerification.GasTemperature");
- _flowTime = SC.GetValue<double>($"{Module}.MFCVerification.GasFlowTime");
- _maxDeviation = SC.GetValue<double>($"{Module}.MFCVerification.MaxDeviation");
- _paramContinuePumpTime = 20;//20s
- _getBeginPressureDelayTime = 2;//2s
- _pressureStableTolerance = (float)SC.GetValue<double>($"{Module}.MFCVerification.PressureStableTolerance");
- _flowStableTolerance = (float) (SC.GetValue<double>($"{Module}.MFCVerification.FlowStableTolerance") / 100.0);
- _stableTime = 1;//1s
- _maxPressure = SC.GetValue<double>($"{Module}.MFCVerification.TargetPressure");
- if (_paramMode == VerifyMode.TenPoint)
- {
- for (int i = 0; i < 10; i++)
- {
- _paramFlowSet.Add(i, (float)_mfcDevice.Scale * (i + 1) / 10);
- }
- }
- else
- {
- if (_mfcFlow <= 0 || _mfcFlow > _mfcDevice.Scale)
- {
- EV.PostWarningLog(Module, $"MFC set value {_mfcFlow} not valid");
- return Result.FAIL;
- }
- _paramFlowSet.Add(0, _mfcFlow);
- }
- _mfcDevice.ResetVerificationData();
- _isPumpDownNeed = true;
- _leakRate = 0;
- var dbData = DataQuery.Query($"SELECT * FROM \"leak_check_data\" where \"module_name\" = '{Module}' order by \"operate_time\" DESC;");
- if (dbData != null && dbData.Rows.Count > 0 && !dbData.Rows[0]["leak_rate"].Equals(DBNull.Value))
- {
- _leakRate = Convert.ToDouble(dbData.Rows[0]["leak_rate"]);
- }
- return Result.RUN;
- }
- public Result Monitor()
- {
- try
- {
- if (_isPumpDownNeed)
- {
- ExecuteRoutine((int)RoutineStep.RunPumpRoutine1, _pumpdownRoutine);
- }
- CheckThrottleValveFullOpen((int)RoutineStep.CheckThrottleValveStatus);
- StartLoop((int)RoutineStep.Loop, "", _paramFlowSet.Count, Notify, Stop);
- //抽到底压
- CheckNeedPumpDown((int)RoutineStep.CheckNeedPumpDown1);
- if (_isPumpDownNeed)
- {
- ExecuteRoutine((int)RoutineStep.RunPumpRoutine2, _pumpdownRoutine);
- }
- //流气
- SetGasFlow((int)RoutineStep.SetGasFlow, _mfcIndex, _paramMode == VerifyMode.TenPoint ? _paramFlowSet[LoopCounter] : _mfcFlow);
- //等待,稳定一下
- Delay((int)RoutineStep.Delay1, _paramContinuePumpTime);
- //检查Stable
- CheckFlowStable((int)RoutineStep.CheckFlowStable, _mfcDevice, _flowStableTolerance, _pressureStableTolerance, _stableTime);
- //关闭抽气阀
- SetValve((int)RoutineStep.ClosePumpValve, ValveType.FAST_PUMP, false);
- //稳压
- Delay((int)RoutineStep.Delay2, _getBeginPressureDelayTime);
- //得到初始压力值
- GetBeginPressure((int)RoutineStep.GetBeginPressure);
- //等待,流气时间或者压力到设定值
- CheckFinished((int)RoutineStep.CheckFinished, _flowTime, _maxPressure);
- //计算Flow
- CalcMfcCalibration((int)RoutineStep.CalcMfcCalibration, _paramMode == VerifyMode.TenPoint ? _paramFlowSet[LoopCounter] : _mfcFlow);
- StopGasFlow((int)RoutineStep.StopGasFlow, _mfcIndex);
- EndLoop((int)RoutineStep.EndLoop, Notify, Stop);
- CheckNeedPumpDown((int)RoutineStep.CheckNeedPumpDown2);
- if (_isPumpDownNeed)
- {
- ExecuteRoutine((int)RoutineStep.RunPumpRoutine3, _pumpdownRoutine);
- }
- }
- catch (RoutineBreakException)
- {
- return Result.RUN;
- }
- catch (RoutineFaildException)
- {
- _verificationDeviceTimer.Stop();
- _chamber.StopAllGases();
- _chamber.SetValveOnOff(ValveType.PROCESS, false);
- _mfcDevice.ResetVerificationData();
- return Result.FAIL;
- }
- return Result.DONE;
- }
- public new void Abort()
- {
- _verificationDeviceTimer.Stop();
- _chamber.StopAllGases();
- _chamber.SetValveOnOff(ValveType.PROCESS, false);
- _mfcDevice.ResetVerificationData();
- }
- private void CheckNeedPumpDown(int id)
- {
- string reason = string.Empty;
- Tuple<bool, Result> ret = Execute(id, () =>
- {
- Notify($"Check {Module} need pump down");
- _isPumpDownNeed = _chamber.ChamberPressure > SC.GetValue<int>($"{Module}.Pump.PumpBasePressure");
- return true;
- });
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- throw (new RoutineFaildException());
- }
- else
- throw (new RoutineBreakException());
- }
- }
- private void SetGasFlow(int id, int mfcId, double flow)
- {
- string reason = string.Empty;
- Tuple<bool, Result> ret = Execute(id, () =>
- {
- Notify($"Set gas {mfcId} flow to {flow} sccm");
- _chamber.SetValveOnOff(ValveType.PROCESS, true);
- if (!_chamber.FlowGas(mfcId, flow))
- {
- return false;
- }
- return true;
- });
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- Stop($"Set gas {mfcId} flow to {flow} sccm failed, for {reason}");
- throw (new RoutineFaildException());
- }
- else
- throw (new RoutineBreakException());
- }
- }
- private void StopGasFlow(int id, int mfcId)
- {
- string reason = string.Empty;
- Tuple<bool, Result> ret = Execute(id, () =>
- {
- Notify($"Stop gas {mfcId} flow");
- _chamber.SetValveOnOff(ValveType.PROCESS, false);
- if (!_chamber.FlowGas(mfcId, 0))
- {
- return false;
- }
- return true;
- });
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- Stop($"Stop gas {mfcId} flow failed, for {reason}");
- throw (new RoutineFaildException());
- }
- else
- throw (new RoutineBreakException());
- }
- }
- private void CalcMfcCalibration(int id, float flow)
- {
- Tuple<bool, Result> ret = Execute(id, () =>
- {
- _mfcActualFlow = 273.15 * _chamberVolume / ((273.15 + _gasTemperature) * 760000) * ((_endPressure - _beginPressure) / _elapsedTime - _leakRate);
- EV.PostInfoLog(Module, $"Calculate flow: calculate flow={_mfcActualFlow}, setpoint={flow}, begin pressure(torr)={_beginPressure:f3}, end pressure(torr)={_endPressure:f3}," +
- $"elapsed time(minute)={_elapsedTime:f3}");
- double deviation = (Math.Abs(_mfcActualFlow) - Math.Abs(flow)) / Math.Abs(flow) * 100;
- bool isOk = Math.Abs(deviation) <= Math.Abs(_maxDeviation);
- if (!isOk)
- {
- EV.PostWarningLog(Module, $"MFC {_mfcDevice.DisplayName} verify failed, deviation is {deviation}%, exceed max tolerance {_maxDeviation}%");
- }
- if (_paramMode == VerifyMode.TenPoint)
- {
- _calibrationResult[flow] = Tuple.Create((float)_mfcActualFlow, (float)_elapsedTime);
- _mfcDevice.SetVerificationResult((float)flow, (float)_mfcActualFlow, _calibrationResult.Count == 10, _elapsedTime*60, deviation, isOk);
- }
- else
- {
- _mfcDevice.SetVerificationResult((float)flow, (float)_mfcActualFlow, true, _elapsedTime*60, deviation, isOk);
- }
- return true;
- });
- }
- private void GetBeginPressure(int id)
- {
- Tuple<bool, Result> ret = Execute(id, () =>
- {
- Notify($"Get begin pressure {_chamber.ChamberPressure.ToString("f1")}");
- _beginPressure = _chamber.ChamberPressure;
- _verificationDeviceTimer.Start(0);
- return true;
- });
- }
- private void CheckFlowStable(int id, MfcBase1 mfc, float flowStable, float pressureStable, int time)
- {
- Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
- {
- Notify($"Check {mfc.Name} flow stable");
- _verificationDeviceTimer.Start(0);
- _beginPressure = _chamber.ChamberPressure;
- return true;
- }, () =>
- {
- if (_verificationDeviceTimer.GetElapseTime() > time * 1000 && Math.Abs(_chamber.ChamberPressure - _beginPressure) <= pressureStable &&
- Math.Abs(mfc.SetPoint - mfc.FeedBack) / mfc.SetPoint < flowStable)
- {
- return true;
- }
- return false;
- }, time * 2 * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- Stop($"Check {mfc.Name} flow {mfc.SetPoint} stable failed.");
- throw (new RoutineFaildException());
- }
- else if (ret.Item2 == Result.TIMEOUT) //timeout
- {
- Stop($"Check {mfc.Name} flow stable timeout in {time * 2} seconds");
- throw (new RoutineFaildException());
- }
- else
- throw (new RoutineBreakException());
- }
- }
- private void CheckFinished(int id, double flowTime, double maxPressure)
- {
- Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
- {
- Notify($"Check finished one point");
- return true;
- }, () =>
- {
- if (_verificationDeviceTimer.GetElapseTime() > flowTime * 1000 || _chamber.ChamberPressure / 1000 > maxPressure)
- {
- _endPressure = _chamber.ChamberPressure;//mTorr
- _elapsedTime = _verificationDeviceTimer.GetElapseTime() / (1000 * 60);//unit minutes
- return true;
- }
- return false;
- }, flowTime * 2 * 1000);
- if (ret.Item1)
- {
- if (ret.Item2 == Result.FAIL)
- {
- throw (new RoutineFaildException());
- }
- else if (ret.Item2 == Result.TIMEOUT) //timeout
- {
- Stop($"Check finished one point can not finished in {flowTime * 2} seconds");
- throw (new RoutineFaildException());
- }
- else
- throw (new RoutineBreakException());
- }
- }
- }
- }
|