PMLeakCheckRoutine.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. using System;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using VirgoCommon;
  6. using VirgoRT.Devices;
  7. namespace VirgoRT.Modules.PMs
  8. {
  9. class LeakCheckRoutine : PMRoutineBase
  10. {
  11. private enum LeakCheckStep
  12. {
  13. Loop,
  14. PumpDown,
  15. CheckDoor,
  16. CheckDryPump,
  17. CloseAllValve,
  18. OpenPumpingValve,
  19. OpenGasFinalValve,
  20. CloseGasFinalValve,
  21. OpenMfc1Valve,
  22. OpenMfc2Valve,
  23. OpenMfc3Valve,
  24. OpenMfc4Valve,
  25. OpenMfc5Valve,
  26. CloseMfc1Valve,
  27. CloseMfc2Valve,
  28. CloseMfc3Valve,
  29. CloseMfc4Valve,
  30. CloseMfc5Valve,
  31. StartFlow,
  32. StopFlow,
  33. RecordStartPressure,
  34. RecordEndPressure,
  35. PumpDownDelay,
  36. StartPressureDelay,
  37. EndPressureDelay,
  38. ClosePumpValve,
  39. LeakCheckDelay,
  40. CalcLeakCheck,
  41. End,
  42. EndLeakCheck,
  43. AbortLeakCheck,
  44. CheckPressure,
  45. EndLoop
  46. };
  47. // Fields
  48. private double _beginPressure = 0;
  49. private double _endPressure = 0;
  50. private double _leakRate;
  51. public double LeakRate { get; private set; }
  52. private int _leakCheckPumpDownTime;
  53. private int _leakCheckSCCount;
  54. private int _leakCheckWaitTime;
  55. private LeakCheckMode _mode;
  56. private bool[] _enableGasLine = new bool[5];
  57. private double[] _mfcFlow = new double[5];
  58. private readonly PumpDownRoutine _pumpdownRoutine;
  59. // Properties
  60. //
  61. public int ElapseTime => (int)(delayTimer.GetElapseTime() / 1000.0);
  62. // Constructor
  63. //
  64. public LeakCheckRoutine(JetPM chamber, PumpDownRoutine _pdRoutine) : base(chamber)
  65. {
  66. Name = "leak check";
  67. bUINotify = true;
  68. _pumpdownRoutine = _pdRoutine;
  69. }
  70. public void Terminate()
  71. {
  72. }
  73. public Result Start(params object[] objs)
  74. {
  75. // 预检查
  76. if (CheckLid() == Result.RUN &&
  77. CheckSlitDoor() == Result.RUN &&
  78. CheckDryPump() == Result.RUN)
  79. {
  80. _enableGasLine = new bool[5] { false, false, false, false, false };
  81. _mfcFlow = new double[5] { 0.0, 0.0, 0.0, 0.0, 0.0 };
  82. Reset();
  83. delayTimer.Start(0);
  84. _leakCheckSCCount = SC.GetValue<int>($"{Module}.Pump.LeakCheckSCCount");
  85. try
  86. {
  87. if (objs.Length == 0)
  88. {
  89. _leakCheckPumpDownTime = SC.GetValue<int>($"{Module}.Pump.LeakCheckPumpingTime");
  90. _leakCheckWaitTime = SC.GetValue<int>($"{Module}.Pump.LeakCheckWaitTime");
  91. _leakRate = SC.GetValue<double>($"{Module}.Pump.LeakRate");
  92. _mode = LeakCheckMode.ChamberOnly;
  93. }
  94. else
  95. {
  96. _leakCheckPumpDownTime = Convert.ToInt32(objs[0].ToString());
  97. _leakCheckWaitTime = Convert.ToInt32(objs[1].ToString());
  98. _mode = (LeakCheckMode)Enum.Parse(typeof(LeakCheckMode), objs[2].ToString());
  99. _leakRate = Convert.ToInt32(objs[3].ToString());
  100. for (int i = 0; i < 5; i++)
  101. _enableGasLine[i] = Convert.ToBoolean(objs[4 + i].ToString());
  102. }
  103. for (int i = 0; i < 5; i++)
  104. {
  105. if (_enableGasLine[i]) _mfcFlow[i] = SC.GetValue<int>($"{Module}.MfcGas{i + 1}.MfcN2Scale");
  106. }
  107. }
  108. catch (Exception ex)
  109. {
  110. LOG.Write(ex);
  111. return Result.FAIL;
  112. }
  113. return Result.RUN;
  114. }
  115. return Result.FAIL;
  116. }
  117. public Result Monitor()
  118. {
  119. try
  120. {
  121. StartLoop((int)LeakCheckStep.Loop, "根据设置开始检漏", _leakCheckSCCount, Notify, Stop);
  122. ExecuteRoutine((int)LeakCheckStep.PumpDown, _pumpdownRoutine);
  123. if (_mode == LeakCheckMode.ChamberOnly)
  124. {
  125. ;
  126. }
  127. else if (_mode == LeakCheckMode.ChamberAndGasLine)
  128. {
  129. OpenValve((int)LeakCheckStep.OpenGasFinalValve, ValveType.PROCESS, true);
  130. if (_enableGasLine[0]) OpenValve((int)LeakCheckStep.OpenMfc1Valve, ValveType.Mfc1, true);
  131. if (_enableGasLine[1]) OpenValve((int)LeakCheckStep.OpenMfc2Valve, ValveType.Mfc2, true);
  132. if (_enableGasLine[2]) OpenValve((int)LeakCheckStep.OpenMfc3Valve, ValveType.Mfc3, true);
  133. if (_enableGasLine[3]) OpenValve((int)LeakCheckStep.OpenMfc4Valve, ValveType.Mfc4, true);
  134. if (_enableGasLine[4]) OpenValve((int)LeakCheckStep.OpenMfc5Valve, ValveType.Mfc5, true);
  135. }
  136. else if (_mode == LeakCheckMode.ChamberAndGasLineAndFAC)
  137. {
  138. OpenValve((int)LeakCheckStep.OpenGasFinalValve, ValveType.PROCESS, true);
  139. if (_enableGasLine[0]) OpenValve((int)LeakCheckStep.OpenMfc1Valve, ValveType.Mfc1, true);
  140. if (_enableGasLine[1]) OpenValve((int)LeakCheckStep.OpenMfc2Valve, ValveType.Mfc2, true);
  141. if (_enableGasLine[2]) OpenValve((int)LeakCheckStep.OpenMfc3Valve, ValveType.Mfc3, true);
  142. if (_enableGasLine[3]) OpenValve((int)LeakCheckStep.OpenMfc4Valve, ValveType.Mfc4, true);
  143. if (_enableGasLine[4]) OpenValve((int)LeakCheckStep.OpenMfc5Valve, ValveType.Mfc5, true);
  144. StartFlowMFC((int)LeakCheckStep.StartFlow, _mfcFlow);
  145. }
  146. TimeDelay((int)LeakCheckStep.PumpDownDelay, _leakCheckPumpDownTime);
  147. OpenValve((int)LeakCheckStep.ClosePumpValve, ValveType.FAST_PUMP, false);
  148. if (_mode == LeakCheckMode.ChamberOnly)
  149. {
  150. ;
  151. }
  152. else if (_mode == LeakCheckMode.ChamberAndGasLine)
  153. {
  154. OpenValve((int)LeakCheckStep.CloseGasFinalValve, ValveType.PROCESS, false);
  155. if (_enableGasLine[0]) OpenValve((int)LeakCheckStep.CloseMfc1Valve, ValveType.Mfc1, false);
  156. if (_enableGasLine[1]) OpenValve((int)LeakCheckStep.CloseMfc2Valve, ValveType.Mfc2, false);
  157. if (_enableGasLine[2]) OpenValve((int)LeakCheckStep.CloseMfc3Valve, ValveType.Mfc3, false);
  158. if (_enableGasLine[3]) OpenValve((int)LeakCheckStep.CloseMfc4Valve, ValveType.Mfc4, false);
  159. if (_enableGasLine[4]) OpenValve((int)LeakCheckStep.CloseMfc5Valve, ValveType.Mfc5, false);
  160. }
  161. else if (_mode == LeakCheckMode.ChamberAndGasLineAndFAC)
  162. {
  163. OpenValve((int)LeakCheckStep.CloseGasFinalValve, ValveType.PROCESS, false);
  164. if (_enableGasLine[0]) OpenValve((int)LeakCheckStep.CloseMfc1Valve, ValveType.Mfc1, false);
  165. if (_enableGasLine[1]) OpenValve((int)LeakCheckStep.CloseMfc2Valve, ValveType.Mfc2, false);
  166. if (_enableGasLine[2]) OpenValve((int)LeakCheckStep.CloseMfc3Valve, ValveType.Mfc3, false);
  167. if (_enableGasLine[3]) OpenValve((int)LeakCheckStep.CloseMfc4Valve, ValveType.Mfc4, false);
  168. if (_enableGasLine[4]) OpenValve((int)LeakCheckStep.CloseMfc5Valve, ValveType.Mfc5, false);
  169. StopFlowMFC((int)LeakCheckStep.StopFlow);
  170. }
  171. //记录腔体Start pressure P1
  172. RecordBeginPressure((int)LeakCheckStep.RecordStartPressure);
  173. //pump down delay
  174. TimeDelay((int)LeakCheckStep.EndPressureDelay, _leakCheckWaitTime);
  175. //记录腔体End pressure P2
  176. RecordEndPressure((int)LeakCheckStep.RecordEndPressure);
  177. CalcLeakCheck((int)LeakCheckStep.CalcLeakCheck, _leakRate, _leakCheckWaitTime, 0);
  178. End((int)LeakCheckStep.End);
  179. EndLoop((int)LeakCheckStep.EndLoop, Notify, Stop);
  180. //ExecuteRoutine((int)LeakCheckStep.EndLeakCheck, _pumpDownRoutine);
  181. }
  182. catch (RoutineBreakException)
  183. {
  184. return Result.RUN;
  185. }
  186. catch (RoutineFaildException)
  187. {
  188. return Result.FAIL;
  189. }
  190. return Result.DONE;
  191. }
  192. public void DelayLeakCheck(int id, string name, double time)
  193. {
  194. bool Func()
  195. {
  196. Notify(name);
  197. return true;
  198. }
  199. Tuple<bool, Result> ret = Delay(id, Func, time * 1000);
  200. if (ret.Item1)
  201. {
  202. if (ret.Item2 == Result.RUN)
  203. {
  204. throw new RoutineBreakException();
  205. }
  206. }
  207. }
  208. public void CheckChamberPressure(int id, double target, out double pressure, int time)
  209. {
  210. bool Func()
  211. {
  212. return true;
  213. }
  214. bool? Check1()
  215. {
  216. if (_chamber.ChamberPressure < target)
  217. {
  218. Notify($"腔体压力 [{_chamber.ChamberPressure}] mt, 低于 [{target}] mt");
  219. return true;
  220. }
  221. Stop($"腔体压力 [{_chamber.ChamberPressure}], 高于 [{target}]");
  222. return false;
  223. }
  224. pressure = _chamber.ChamberPressure;
  225. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, time * 1000);
  226. if (ret.Item1)
  227. {
  228. if (ret.Item2 == Result.FAIL)
  229. {
  230. throw new RoutineFaildException();
  231. }
  232. if (ret.Item2 == Result.TIMEOUT)
  233. {
  234. throw new RoutineFaildException();
  235. }
  236. throw new RoutineBreakException();
  237. }
  238. }
  239. public void RecordBeginPressure(int id)
  240. {
  241. bool Func()
  242. {
  243. _beginPressure = _chamber.ChamberPressure;
  244. Notify($"腔体压力初始值 {_beginPressure} mt");
  245. return true;
  246. }
  247. bool? Check1()
  248. {
  249. return true;
  250. }
  251. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, 1 * 1000);
  252. if (ret.Item1)
  253. {
  254. if (ret.Item2 == Result.FAIL)
  255. {
  256. throw new RoutineFaildException();
  257. }
  258. if (ret.Item2 == Result.TIMEOUT)
  259. {
  260. throw new RoutineFaildException();
  261. }
  262. throw new RoutineBreakException();
  263. }
  264. }
  265. public void RecordEndPressure(int id)
  266. {
  267. bool Func()
  268. {
  269. _endPressure = _chamber.ChamberPressure;
  270. Notify($"腔体压力结束值 {_endPressure} mt");
  271. return true;
  272. }
  273. bool? Check1()
  274. {
  275. return true;
  276. }
  277. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, 1 * 1000);
  278. if (ret.Item1)
  279. {
  280. if (ret.Item2 == Result.FAIL)
  281. {
  282. throw new RoutineFaildException();
  283. }
  284. if (ret.Item2 == Result.TIMEOUT)
  285. {
  286. throw new RoutineFaildException();
  287. }
  288. throw new RoutineBreakException();
  289. }
  290. }
  291. public void CalcLeakCheck(int id, double target, int timeRate, int time)
  292. {
  293. bool Func()
  294. {
  295. return true;
  296. }
  297. bool? Check1()
  298. {
  299. LeakRate = (_endPressure - _beginPressure) / (timeRate / 60.0);
  300. if (LeakRate < target)
  301. {
  302. Notify($"腔体漏率 [{LeakRate}] mt/min, 低于 [{target}] mt/min");
  303. LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_endPressure, LeakRate, LeakCheckStatus.Succeed.ToString(), _mode.ToString());
  304. return true;
  305. }
  306. Stop($"腔体漏率 [{LeakRate}] mt/min, 高于 [{target}] mt/min");
  307. LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_endPressure, LeakRate, LeakCheckStatus.Failed.ToString(), _mode.ToString());
  308. return false;
  309. }
  310. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, time * 1000);
  311. if (ret.Item1)
  312. {
  313. if (ret.Item2 == Result.FAIL)
  314. {
  315. throw new RoutineFaildException();
  316. }
  317. if (ret.Item2 == Result.TIMEOUT)
  318. {
  319. throw new RoutineFaildException();
  320. }
  321. throw new RoutineBreakException();
  322. }
  323. }
  324. public void StopFlowMFC(int id)
  325. {
  326. bool Func()
  327. {
  328. _chamber.StopAllGases();
  329. return true;
  330. }
  331. bool? Check1()
  332. {
  333. return true;
  334. }
  335. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, 1 * 1000);
  336. if (ret.Item1)
  337. {
  338. if (ret.Item2 == Result.FAIL)
  339. {
  340. throw new RoutineFaildException();
  341. }
  342. if (ret.Item2 == Result.TIMEOUT)
  343. {
  344. throw new RoutineFaildException();
  345. }
  346. throw new RoutineBreakException();
  347. }
  348. }
  349. public void StartFlowMFC(int id, double[] mfcValues)
  350. {
  351. bool Func()
  352. {
  353. for (int index = 0; index < mfcValues.Length; index++)
  354. {
  355. _chamber.FlowGas(index, mfcValues[index]);
  356. }
  357. return true;
  358. }
  359. bool? Check1()
  360. {
  361. return true;
  362. }
  363. Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, 1 * 1000);
  364. if (ret.Item1)
  365. {
  366. if (ret.Item2 == Result.FAIL)
  367. {
  368. throw new RoutineFaildException();
  369. }
  370. if (ret.Item2 == Result.TIMEOUT)
  371. {
  372. throw new RoutineFaildException();
  373. }
  374. throw new RoutineBreakException();
  375. }
  376. }
  377. public void DeleteLeadCheck(object[] args)
  378. {
  379. LeakCheckResultManager.Instance.Delete(Module, args[0].ToString());
  380. }
  381. public override void Abort()
  382. {
  383. try
  384. {
  385. _chamber.CloseValves();
  386. LeakCheckResultManager.Instance.AddLeakCheck(Module, DateTime.Now, ElapseTime, (int)_beginPressure, (int)_chamber.ChamberPressure, 0, LeakCheckStatus.Aborted.ToString(), _mode.ToString());
  387. }
  388. catch (Exception ex)
  389. {
  390. LOG.Write(ex);
  391. }
  392. }
  393. }
  394. }