Sic10/Modules/SicModules/LLs/LoadLockLeakCheckRoutine.cs

321 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Diagnostics;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.Equipment;
using SicModules.Devices;
namespace SicModules.LLs
{
public class LoadLockLeakCheckRoutine : LoadLockBaseRoutine
{
enum RoutineStep
{
SlowPump,
CloseSlowValve,
FastPump,
PumpDelay,
CloseFastValve,
CheckDoor,
RunPumpRoutine,
ContinuePump,
ClosePumpValve,
DoLeakCheck,
DoLeakCheckDelay,
CalcLeakCheck,
StartLoop,
LoopVent,
LoopPump,
StopLoop,
SlowPumpP, FastPumpP, PumpDelayP, CloseFastValveP, CloseSlowValveP, SlowVentV, CloseFastVentValveV, VentDelayV,
TimeDelay1,
TimeDelay2
}
private LoadLockPumpRoutine _pumpRoutine;
private LoadLockVentRoutine _ventRoutine;
private int _paramContinuePumpTime;
private int _paramLeakCheckTime;
private double _beginPressure;
private double _pumpBasePressure;
private double _pumpSwitchPressure;
private int _pumpTimeout;
private int _ventTimeout;
private int _routineTimeOut;
private double _leakSpec;
private int _purgeCount;
private double _beginTime;
private int _calTimes; //第几次计算LeakCheck的值每60秒计算一次
private double _ventBasePressure;
private int _pumpDelayTime;
private int _ventDelayTime;
private IoInterLockEx _tmIoInterLock;
private Stopwatch _swTimer = new Stopwatch();
public int ElapsedTime
{
get { return _swTimer.IsRunning ? (int)(_swTimer.ElapsedMilliseconds / 1000) : 0; }
}
public LoadLockLeakCheckRoutine(ModuleName module)
{
Module = module.ToString();
Name = "LeakCheck";
_tmIoInterLock = DEVICE.GetDevice<IoInterLockEx>("TM.IoInterLock");
_pumpRoutine = new LoadLockPumpRoutine(module);
_ventRoutine = new LoadLockVentRoutine(module);
}
internal void Init(int pumpTime, int leakCheckTime)
{
_paramContinuePumpTime = pumpTime;
_paramLeakCheckTime = leakCheckTime;
}
internal void Init()
{
_paramContinuePumpTime = SC.GetValue<int>("LoadLock.LeakCheck.PumpDelayTime");
_paramLeakCheckTime = SC.GetValue<int>("LoadLock.LeakCheck.LeakCheckDelayTime");
}
public override Result Start(params object[] objs)
{
Reset();
_swTimer.Restart();
_pumpRoutine.Init();
_ventRoutine.Init();
string reason;
if (!LoadLockDevice.SetFastVentValve(false, out reason) || !LoadLockDevice.SetSlowVentValve(false, out reason))
{
EV.PostAlarmLog(Module, $"Can not turn off valves, {reason}");
return Result.FAIL;
}
bool isAtmMode = SC.GetValue<bool>("System.IsATMMode");
_pumpSwitchPressure = SC.GetValue<double>("LoadLock.Pump.SlowFastPumpSwitchPressure");
_pumpBasePressure = SC.GetValue<double>("LoadLock.LeakCheck.PumpBasePressure");
_ventBasePressure = SC.GetValue<double>("LoadLock.LeakCheck.VentBasePressure");
_routineTimeOut = SC.GetValue<int>("LoadLock.LeakCheck.RoutineTimeOut");
_leakSpec = SC.GetValue<double>("LoadLock.LeakCheck.LeakSpec");
_purgeCount= SC.GetValue<int>("LoadLock.LeakCheck.CyclePurgeCount");
_pumpTimeout = SC.GetValue<int>("LoadLock.Pump.RoutineTimeOut");
_ventTimeout = SC.GetValue<int>("LoadLock.Vent.RoutineTimeOut");
_pumpDelayTime = SC.GetValue<int>("LoadLock.Pump.PumpDelayTime");
_ventDelayTime = SC.GetValue<int>("LoadLock.Vent.VentDelayTime");
if (isAtmMode)
{
EV.PostInfoLog(Module, $"system in atm mode, {Module} pump skipped");
return Result.DONE;
}
if (!LoadLockDevice.CheckLidClose())
{
EV.PostAlarmLog(Module, $"Can not leakCheck, lid is open");
return Result.FAIL;
}
if (!TMDevice.SetFastPumpValve(false, out reason))
{
EV.PostAlarmLog(Module, $"can not leakCheck, TM fast pump value can not close");
return Result.FAIL;
}
if (!TMDevice.CheckSlitValveClose(ModuleName.LoadLock))
{
EV.PostAlarmLog(Module, $"Can not leakCheck, slit valve is open");
return Result.FAIL;
}
if (!_tmIoInterLock.SetLLLeakCheckRoutineRunning(true, out reason))
{
EV.PostAlarmLog(Module, $"can not LeakCheck,{reason}");
return Result.FAIL;
}
Notify("Start");
return Result.RUN;
}
public override Result Monitor()
{
try
{
CheckRoutineTimeOut();
Loop((int)RoutineStep.StartLoop, _purgeCount);
SlowPump((int)RoutineStep.SlowPumpP, _pumpSwitchPressure, _pumpTimeout);
FastPump((int)RoutineStep.FastPumpP, _pumpBasePressure, _pumpTimeout);
TimeDelay((int)RoutineStep.PumpDelayP, _pumpDelayTime);
CloseFastPumpValve((int)RoutineStep.CloseFastValveP);
CloseSlowPumpValve((int)RoutineStep.CloseSlowValveP);
TimeDelay((int)RoutineStep.TimeDelay1, 1);
SlowVent((int)RoutineStep.SlowVentV, _ventBasePressure, _ventTimeout);
TimeDelay((int)RoutineStep.VentDelayV, _ventDelayTime);
CloseVentValveAndWait((int)RoutineStep.CloseFastVentValveV);
TimeDelay((int)RoutineStep.TimeDelay2, 1);
EndLoop((int)RoutineStep.StopLoop);
SlowPump((int)RoutineStep.SlowPump, _pumpSwitchPressure, _pumpTimeout);
FastPump((int)RoutineStep.FastPump, _pumpBasePressure, _pumpTimeout);
TimeDelay((int)RoutineStep.PumpDelay, _paramContinuePumpTime);
CloseFastPumpValve((int)RoutineStep.CloseFastValve);
CloseSlowPumpValve((int)RoutineStep.CloseSlowValve);
DoLeakCheck((int)RoutineStep.DoLeakCheck, _paramLeakCheckTime);
//CalcLeackCheckPerMinute(_paramLeakCheckTime);
TimeDelay((int)RoutineStep.DoLeakCheckDelay, _paramLeakCheckTime);
CalcLeakCheck((int)RoutineStep.CalcLeakCheck, _paramLeakCheckTime);
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
_tmIoInterLock.DoLLLeakCheckRoutineRunning = false;
_swTimer.Stop();
return Result.DONE;
}
public override void Abort()
{
Notify($"{Module} leak check aborted");
_tmIoInterLock.DoLLLeakCheckRoutineRunning = false;
_swTimer.Stop();
LeakCheckDataRecorder.Add((int)_swTimer.ElapsedMilliseconds / 1000, _beginPressure, TMDevice.ChamberPressure, 0, Result.FAIL.ToString(), "", Module);
base.Abort();
}
private void CheckRoutineTimeOut()
{
if (_routineTimeOut > 10)
{
if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
{
EV.PostAlarmLog(Module, $"Routine TimeOut! over {_routineTimeOut} s");
throw (new RoutineFaildException());
}
}
}
public void DoLeakCheck(int id, double time)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
Notify($"Keep pressure for {time} seconds");
_beginTime = _swTimer.ElapsedMilliseconds;
_beginPressure = LoadLockDevice.ChamberPressure;
_calTimes = 1;
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
public void CalcLeackCheckPerMinute(int time)
{
//大于LeakCheck时间,
if ((int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000) >= time)
{
int leakSecond = (int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000);
double endPressure = LoadLockDevice.ChamberPressure;
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (leakSecond / 60.0);
if (leakRate > _leakSpec)
{
LeakCheckDataRecorder.Add(time, (int)_beginPressure, (int)endPressure, leakRate, Result.FAIL.ToString(), Module, Module);
EV.PostInfoLog(Module, $"Leak check result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2}mbar, end: {endPressure:F2}mbar, using {time} seconds, leak rate: {leakRate:F2}");
}
else
{
LeakCheckDataRecorder.Add(time, (int)_beginPressure, (int)endPressure, leakRate, Result.Succeed.ToString(), Module, Module);
EV.PostInfoLog(Module, $"Leak check result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2}mbar, end: {endPressure:F2}mbar, using {time} seconds, leak rate: {leakRate:F2}");
}
}
else
{
if ((int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000) >= 60 * _calTimes)
{
_calTimes++;
int leakSecond = (int)((_swTimer.ElapsedMilliseconds - _beginTime) / 1000);
double endPressure = LoadLockDevice.ChamberPressure;
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (leakSecond / 60.0);
if (leakRate > _leakSpec)
{
EV.PostInfoLog(Module, $"Leak check Failed Count {_calTimes - 1}: using {leakSecond} seconds, leak rate: {leakRate:F2} ,Rate over {_leakSpec}");
throw (new RoutineFaildException());
}
EV.PostInfoLog(Module, $"Leak check Count {_calTimes - 1}: using {leakSecond} seconds, leak rate: {leakRate:F2}");
}
throw (new RoutineBreakException());
}
}
public void CalcLeakCheck(int id, int time)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
double endPressure = LoadLockDevice.ChamberPressure ; //
double leakSpan = endPressure - _beginPressure;
double leakRate = (endPressure - _beginPressure) / (time / 60.0);
if (leakRate > _leakSpec)
{
LeakCheckDataRecorder.Add(time, _beginPressure, endPressure, leakRate, Result.FAIL.ToString(), "", Module);
EV.PostInfoLog(Module,$"{Module} leakcheck result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2} mbar, end: {endPressure:F2} mbar, using {time} seconds, leak rate: {leakRate:F2}");
return false;
}
else
{
LeakCheckDataRecorder.Add(time, _beginPressure, endPressure, leakRate, Result.Succeed.ToString(), "", Module);
EV.PostInfoLog(Module,$"{Module} leakcheck result: end at {DateTime.Now.ToString("HH:mm:ss")}, start: {_beginPressure:F2} mbar, end: {endPressure:F2} mbar, using {time} seconds, leak rate: {leakRate:F2}");
return true;
}
});
}
}
}