PMMfcVerificationRoutine.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.Routine;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using MECF.Framework.Common.DBCore;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using Aitex.Core.RT.Device.Unit;
  14. using JetVirgoPM.Devices;
  15. using MECF.Framework.Common.Routine;
  16. namespace JetVirgoPM.PMs.Routines
  17. {
  18. public enum VerifyMode
  19. {
  20. OnePoint,
  21. TenPoint,
  22. }
  23. class PMMfcVerificationRoutine : PMRoutineBase, IStepRoutine
  24. {
  25. enum RoutineStep
  26. {
  27. CheckNeedPumpDown1,
  28. CheckNeedPumpDown2,
  29. RunPumpRoutine1,
  30. RunPumpRoutine2,
  31. RunPumpRoutine3,
  32. CheckThrottleValveStatus,
  33. ClosePumpValve,
  34. GetBeginPressure,
  35. SetGasFlow,
  36. CalcMfcCalibration,
  37. Delay1,
  38. Delay2,
  39. StopGasFlow,
  40. CheckFinished,
  41. Loop,
  42. EndLoop,
  43. CheckFlowStable,
  44. End,
  45. }
  46. private readonly PumpDownRoutine _pumpdownRoutine;
  47. private int _paramContinuePumpTime;
  48. private double _beginPressure;
  49. private double _endPressure;
  50. private double _elapsedTime;
  51. private DeviceTimer _verificationDeviceTimer = new DeviceTimer();
  52. private int _mfcIndex;
  53. private float _mfcFlow;
  54. private double _flowTime;
  55. private double _mfcActualFlow;
  56. private double _getBeginPressureDelayTime;
  57. private double _maxPressure;
  58. private MfcBase1 _mfcDevice;
  59. private VerifyMode _paramMode;
  60. private Dictionary<int, float> _paramFlowSet = new Dictionary<int, float>();
  61. private Dictionary<float, Tuple<float, float>> _calibrationResult = new Dictionary<float, Tuple<float, float>>();
  62. private bool _isPumpDownNeed;
  63. private float _pressureStableTolerance = 2;//2mTorr
  64. private float _flowStableTolerance = 0.02f;//2%
  65. private int _stableTime = 1;//1s
  66. private double _chamberVolume;
  67. private double _gasTemperature;
  68. private double _leakRate;
  69. private double _maxDeviation;
  70. public PMMfcVerificationRoutine(JetDualPM chamber, PumpDownRoutine pumpDownRoutine) : base(chamber)
  71. {
  72. Name = "MFC Verification";
  73. bUINotify = true;
  74. _pumpdownRoutine = pumpDownRoutine;
  75. }
  76. internal void Init(string mfc, double flow, int flowCount)
  77. {
  78. int.TryParse(mfc.Replace("MFC",""), out _mfcIndex);
  79. _mfcDevice = DEVICE.GetDevice<MfcBase1>($"{Module}.MfcGas{_mfcIndex}");
  80. _mfcIndex -= 1;//start from 0
  81. _mfcFlow = (float)flow;
  82. if (flowCount == 10)
  83. _paramMode = VerifyMode.TenPoint;
  84. else
  85. _paramMode = VerifyMode.OnePoint;
  86. }
  87. public RState Start(params object[] objs)
  88. {
  89. Reset();
  90. if(CheckLid() != RState.Running)
  91. {
  92. return RState.Failed;
  93. }
  94. if (CheckSlitDoor1() != RState.Running)
  95. {
  96. return RState.Failed;
  97. }
  98. if (CheckSlitDoor2() != RState.Running)
  99. {
  100. return RState.Failed;
  101. }
  102. if (CheckDryPump() != RState.Running)
  103. {
  104. return RState.Failed;
  105. }
  106. _calibrationResult.Clear();
  107. _paramFlowSet.Clear();
  108. _chamberVolume = SC.GetValue<double>($"{Module}.MFCVerification.ChamberVolume");
  109. _gasTemperature = SC.GetValue<double>($"{Module}.MFCVerification.GasTemperature");
  110. _flowTime = SC.GetValue<double>($"{Module}.MFCVerification.GasFlowTime");
  111. _maxDeviation = SC.GetValue<double>($"{Module}.MFCVerification.MaxDeviation");
  112. _paramContinuePumpTime = 20;//20s
  113. _getBeginPressureDelayTime = 2;//2s
  114. _pressureStableTolerance = (float)SC.GetValue<double>($"{Module}.MFCVerification.PressureStableTolerance");
  115. _flowStableTolerance = (float)(SC.GetValue<double>($"{Module}.MFCVerification.FlowStableTolerance") / 100.0);
  116. _stableTime = 1;//1s
  117. _maxPressure = SC.GetValue<double>($"{Module}.MFCVerification.TargetPressure");
  118. if (_paramMode == VerifyMode.TenPoint)
  119. {
  120. for (int i = 0; i < 10; i++)
  121. {
  122. _paramFlowSet.Add(i, (float)_mfcDevice.Scale * (i + 1) / 10);
  123. }
  124. }
  125. else
  126. {
  127. if (_mfcFlow <= 0 || _mfcFlow > _mfcDevice.Scale)
  128. {
  129. EV.PostWarningLog(Module, $"MFC set value {_mfcFlow} not valid");
  130. return RState.Failed;
  131. }
  132. _paramFlowSet.Add(0, _mfcFlow);
  133. }
  134. _mfcDevice.ResetVerificationData();
  135. _isPumpDownNeed = true;
  136. _leakRate = 0;
  137. var dbData = DataQuery.Query($"SELECT * FROM \"leak_check_data\" where \"module_name\" = '{Module}' order by \"operate_time\" DESC;");
  138. if (dbData != null && dbData.Rows.Count > 0 && !dbData.Rows[0]["leak_rate"].Equals(DBNull.Value))
  139. {
  140. _leakRate = Convert.ToDouble(dbData.Rows[0]["leak_rate"]);
  141. }
  142. return Runner.Start(_chamber.Module.ToString(), Name);
  143. }
  144. public RState Monitor()
  145. {
  146. Runner.Run(RoutineStep.RunPumpRoutine1, StartPump, CheckPump)
  147. .Run(RoutineStep.CheckThrottleValveStatus, FullOpenTV, CheckFullOpenTV, _delay_20s)
  148. .LoopStart(RoutineStep.CheckNeedPumpDown1, "", _paramFlowSet.Count, CheckNeedPumpDown, _delay_50ms) //抽到底压
  149. .LoopRun(RoutineStep.RunPumpRoutine2, StartPump, CheckPump)
  150. .LoopRun(RoutineStep.SetGasFlow, SetGasFlow, _delay_50ms) //流气
  151. .LoopDelay(RoutineStep.Delay1, _paramContinuePumpTime * 1000) //等待,稳定一下
  152. .LoopRun(RoutineStep.CheckFlowStable, FlowStable, CheckFlowStable, _stableTime * 2 * 1000) //检查Stable
  153. .LoopRun(RoutineStep.ClosePumpValve, ClosePumpValve, CheckClosePumpValve, 500) //关闭抽气阀
  154. .LoopDelay(RoutineStep.Delay2, (int)_getBeginPressureDelayTime * 1000) //稳压
  155. .LoopRun(RoutineStep.GetBeginPressure, GetBeginPressure, _delay_50ms)
  156. .LoopRun(RoutineStep.CheckFinished, ChamberPressure, CheckChamberPressure, (int)_flowTime * 2 * 1000) //等待,流气时间或者压力到设定值
  157. .LoopRun(RoutineStep.CalcMfcCalibration, CalcMfcCalibration, _delay_50ms) //计算Flow
  158. .LoopRun(RoutineStep.StopGasFlow, StopGasFlow, _delay_1s)
  159. .LoopEnd(RoutineStep.EndLoop, NullFun, _delay_1s)
  160. .Run(RoutineStep.CheckNeedPumpDown2, CheckNeedPumpDown, _delay_50ms)
  161. .Run(RoutineStep.RunPumpRoutine3, StartPump, CheckPump)
  162. .End(RoutineStep.End, NullFun, _delay_50ms);
  163. if (Runner.Status == RState.Failed)
  164. {
  165. _verificationDeviceTimer.Stop();
  166. _chamber.StopAllGases();
  167. _chamber.OpenValve(ValveType.PROCESS, false);
  168. _chamber.OpenValve(ValveType.PURGE, false);
  169. _mfcDevice.ResetVerificationData();
  170. }
  171. return Runner.Status;
  172. }
  173. public bool StartPump()
  174. {
  175. if(!_isPumpDownNeed)
  176. {
  177. return true;
  178. }
  179. return _pumpdownRoutine.Start() == RState.Running;
  180. }
  181. bool CheckPump()
  182. {
  183. if (!_isPumpDownNeed)
  184. {
  185. Notify($"{_chamber.Name} 无需设置 Pump ");
  186. return true;
  187. }
  188. var result = _pumpdownRoutine.Monitor();
  189. if (result == RState.Failed || result == RState.Timeout)
  190. {
  191. Runner.Stop($"设置 Pump {_chamber.Name} failed ");
  192. return true;
  193. }
  194. return result == RState.End;
  195. }
  196. private bool ClosePumpValve()
  197. {
  198. _chamber.OpenValve(ValveType.FAST_PUMP, false);
  199. Notify($"关闭 {ValveType.FAST_PUMP} 阀");
  200. return true;
  201. }
  202. private bool CheckClosePumpValve()
  203. {
  204. return !_chamber.IsFastPumpOpened;
  205. }
  206. public new void Abort()
  207. {
  208. _verificationDeviceTimer.Stop();
  209. _chamber.StopAllGases();
  210. _chamber.OpenValve(ValveType.PROCESS, false);
  211. _chamber.OpenValve(ValveType.PURGE, false);
  212. _mfcDevice.ResetVerificationData();
  213. }
  214. private bool CheckNeedPumpDown()
  215. {
  216. Notify($"Check {Module} need pump down");
  217. _isPumpDownNeed = _chamber.ChamberPressure > SC.GetValue<int>($"{Module}.Pump.PumpBasePressure");
  218. return true;
  219. }
  220. private bool SetGasFlow()
  221. {
  222. var flow = _paramMode == VerifyMode.TenPoint ? _paramFlowSet[Runner.LoopCounter] : _mfcFlow;
  223. Notify($"Set gas {_mfcIndex} flow to {flow} sccm");
  224. _chamber.OpenValve(ValveType.PROCESS, true);
  225. if (!_chamber.IsPlus)
  226. _chamber.OpenValve(ValveType.PURGE, true);
  227. if (!_chamber.FlowGas(_mfcIndex, flow))
  228. {
  229. return false;
  230. }
  231. return true;
  232. }
  233. private bool StopGasFlow()
  234. {
  235. Notify($"Stop gas {_mfcIndex} flow");
  236. _chamber.OpenValve(ValveType.PROCESS, false);
  237. _chamber.OpenValve(ValveType.PURGE, false);
  238. if (!_chamber.FlowGas(_mfcIndex, 0))
  239. {
  240. return false;
  241. }
  242. return true;
  243. }
  244. private bool CalcMfcCalibration()
  245. {
  246. var flow = _paramMode == VerifyMode.TenPoint ? _paramFlowSet[Runner.LoopCounter] : _mfcFlow;
  247. _mfcActualFlow = 273.15 * _chamberVolume / ((273.15 + _gasTemperature) * 760000) * ((_endPressure - _beginPressure) / _elapsedTime - _leakRate);
  248. EV.PostInfoLog(Module, $"Calculate flow: calculate flow={_mfcActualFlow}, setpoint={flow}, begin pressure(torr)={_beginPressure:f3}, end pressure(torr)={_endPressure:f3}," +
  249. $"elapsed time(minute)={_elapsedTime:f3}");
  250. double deviation = (Math.Abs(_mfcActualFlow) - Math.Abs(flow)) / Math.Abs(flow) * 100;
  251. bool isOk = Math.Abs(deviation) <= Math.Abs(_maxDeviation);
  252. if (!isOk)
  253. {
  254. EV.PostWarningLog(Module, $"MFC {_mfcDevice.DisplayName} verify failed, deviation is {deviation}%, exceed max tolerance {_maxDeviation}%");
  255. }
  256. if (_paramMode == VerifyMode.TenPoint)
  257. {
  258. _calibrationResult[flow] = Tuple.Create((float)_mfcActualFlow, (float)_elapsedTime);
  259. _mfcDevice.SetVerificationResult((float)flow, (float)_mfcActualFlow, _calibrationResult.Count == 10, _elapsedTime * 60, deviation, isOk);
  260. }
  261. else
  262. {
  263. _mfcDevice.SetVerificationResult((float)flow, (float)_mfcActualFlow, true, _elapsedTime * 60, deviation, isOk);
  264. }
  265. return true;
  266. }
  267. private bool GetBeginPressure()
  268. {
  269. Notify($"Get begin pressure {_chamber.ChamberPressure.ToString("f1")}");
  270. _beginPressure = _chamber.ChamberPressure;
  271. _verificationDeviceTimer.Start(0);
  272. return true;
  273. }
  274. private bool FlowStable()
  275. {
  276. Notify($"Check {_mfcDevice.Name} flow stable");
  277. _verificationDeviceTimer.Start(0);
  278. _beginPressure = _chamber.ChamberPressure;
  279. return true;
  280. }
  281. bool CheckFlowStable()
  282. {
  283. if (_verificationDeviceTimer.GetElapseTime() > _stableTime * 1000 && Math.Abs(_chamber.ChamberPressure - _beginPressure) <= _pressureStableTolerance &&
  284. Math.Abs(_mfcDevice.SetPoint - _mfcDevice.FeedBack) / _mfcDevice.SetPoint < _flowStableTolerance)
  285. {
  286. return true;
  287. }
  288. return false;
  289. }
  290. private bool ChamberPressure()
  291. {
  292. Notify($"Check finished one point");
  293. return true;
  294. }
  295. bool CheckChamberPressure()
  296. {
  297. if (_verificationDeviceTimer.GetElapseTime() > _flowTime * 1000 || _chamber.ChamberPressure / 1000 > _maxPressure)
  298. {
  299. _endPressure = _chamber.ChamberPressure;//mTorr
  300. _elapsedTime = _verificationDeviceTimer.GetElapseTime() / (1000 * 60);//unit minutes
  301. return true;
  302. }
  303. return false;
  304. }
  305. }
  306. }