VpwVacuumPrewetRoutine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using MECF.Framework.Common.Alarm;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.RecipeCenter;
  9. using MECF.Framework.Common.Routine;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using PunkHPX8_Core;
  12. using PunkHPX8_RT.Devices.AXIS;
  13. using PunkHPX8_RT.Devices.VpwCell;
  14. using PunkHPX8_RT.Devices.VpwMain;
  15. using PunkHPX8_RT.Modules.VpwMain;
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.Threading.Tasks;
  21. namespace PunkHPX8_RT.Modules.VpwCell
  22. {
  23. public class VpwVacuumPrewetRoutine : RoutineBase, IRoutine
  24. {
  25. private enum PrepareStep
  26. {
  27. OpenVacuumValve,
  28. EnableVacuumPump,
  29. CheckVacuum,
  30. CloseVacuumValve,
  31. OpenVentValve,
  32. CheckLidReleaseVacuum,
  33. ChamberDown,
  34. CloseVentValve,
  35. ChamberUp,
  36. LastOpenVacuumValve,
  37. LastCheckVacuum,
  38. DryerHoldTime,
  39. OpenCellValve,
  40. End
  41. }
  42. #region 内部变量
  43. /// <summary>
  44. /// recipe
  45. /// </summary>
  46. private VpwRecipe _recipe;
  47. /// <summary>
  48. /// 设备
  49. /// </summary>
  50. private VpwCellDevice _vpwCellDevice;
  51. /// <summary>
  52. /// Main设备
  53. /// </summary>
  54. private VpwMainDevice _mainDevice;
  55. /// <summary>
  56. /// Pump DownWarn时间
  57. /// </summary>
  58. private int _pumpDownWarningTime = 60000;
  59. /// <summary>
  60. /// Pump Down超时
  61. /// </summary>
  62. private int _pumpDownTimeOut = 80000;
  63. /// <summary>
  64. /// 开始Pump Down时间
  65. /// </summary>
  66. private DateTime _pumpDownTime=DateTime.MinValue;
  67. /// <summary>
  68. /// 是否需要重试
  69. /// </summary>
  70. private bool _isNeedRetry = false;
  71. /// <summary>
  72. /// Lid Release Pressure
  73. /// </summary>
  74. private int _lidReleasePressure = 730;
  75. /// <summary>
  76. /// Lid Release Pressure
  77. /// </summary>
  78. private int _lidReleasePressureTimeout = 10000;
  79. #endregion
  80. /// <summary>
  81. /// 构造函数
  82. /// </summary>
  83. /// <param name="module"></param>
  84. public VpwVacuumPrewetRoutine(string module) : base(module)
  85. {
  86. }
  87. /// <summary>
  88. /// 中止
  89. /// </summary>
  90. public void Abort()
  91. {
  92. Runner.Stop("Manual abort");
  93. }
  94. /// <summary>
  95. /// 监控
  96. /// </summary>
  97. /// <returns></returns>
  98. public RState Monitor()
  99. {
  100. Runner.Run(PrepareStep.OpenVacuumValve, PumpValveOn, _delay_1ms)
  101. .Run(PrepareStep.EnableVacuumPump, PumpEnable, _delay_1ms)
  102. .Wait(PrepareStep.CheckVacuum, CheckVacuumValue, _pumpDownTimeOut + 1000)
  103. .RunIf(PrepareStep.CloseVacuumValve, _isNeedRetry, PumpValveOff, _delay_1ms)
  104. .RunIf(PrepareStep.OpenVentValve, _isNeedRetry, OpenVentValve, _delay_1ms)
  105. .WaitIf(PrepareStep.CheckLidReleaseVacuum, _isNeedRetry, CheckLidReleaseVacuum, _lidReleasePressureTimeout)
  106. .RunIf(PrepareStep.ChamberDown, _isNeedRetry, ChamberDown, CheckChamberOpened, _delay_10s)
  107. .RunIf(PrepareStep.CloseVentValve, _isNeedRetry, CloseVentValve, _delay_1ms)
  108. .RunIf(PrepareStep.ChamberUp, _isNeedRetry, ChamberUp, CheckChamberClosed, _delay_10s)
  109. .RunIf(PrepareStep.LastOpenVacuumValve, _isNeedRetry, PumpValveOn, _delay_1ms)
  110. .WaitIf(PrepareStep.LastCheckVacuum, _isNeedRetry,LastCheckVacuumValue, _pumpDownTimeOut)
  111. .Delay(PrepareStep.DryerHoldTime,_recipe.DryHoldTime*1000)
  112. .Run(PrepareStep.OpenCellValve,OpenCellValve,_delay_1ms)
  113. .End(PrepareStep.End,NullFun,_delay_1ms);
  114. return Runner.Status;
  115. }
  116. /// <summary>
  117. /// pump valve on
  118. /// </summary>
  119. /// <returns></returns>
  120. private bool PumpValveOn()
  121. {
  122. bool result = _vpwCellDevice.VacuumValveOn();
  123. if (!result)
  124. {
  125. NotifyError(eEvent.ERR_VPW, "pump valve on failed", 0);
  126. }
  127. return result;
  128. }
  129. /// <summary>
  130. /// Pump valve off
  131. /// </summary>
  132. /// <returns></returns>
  133. private bool PumpValveOff()
  134. {
  135. bool result = _vpwCellDevice.VacuumValveOff();
  136. if (!result)
  137. {
  138. NotifyError(eEvent.ERR_VPW, "pump valve off failed", 0);
  139. }
  140. return result;
  141. }
  142. /// <summary>
  143. /// Pump Enable
  144. /// </summary>
  145. /// <returns></returns>
  146. private bool PumpEnable()
  147. {
  148. bool result =_mainDevice.VacuumPumpEnable();
  149. if (!result)
  150. {
  151. NotifyError(eEvent.ERR_VPW, "pump enable failed", 0);
  152. }
  153. else
  154. {
  155. _pumpDownTime = DateTime.Now;
  156. }
  157. return result;
  158. }
  159. /// <summary>
  160. /// 检验真空
  161. /// </summary>
  162. /// <returns></returns>
  163. private bool CheckVacuumValue()
  164. {
  165. double vacuumValue = _vpwCellDevice.CommonData.VacuumPressure;
  166. if (vacuumValue >= _recipe.VacuumTarget)
  167. {
  168. return true;
  169. }
  170. if (DateTime.Now.Subtract(_pumpDownTime).TotalMilliseconds >= _pumpDownWarningTime)
  171. {
  172. AlarmListManager.Instance.AddWarn(Module, "vacuum value", $"vacuum value {vacuumValue} is less than {_recipe.VacuumTarget}");
  173. }
  174. if (DateTime.Now.Subtract(_pumpDownTime).TotalMilliseconds >= _pumpDownTimeOut)
  175. {
  176. _isNeedRetry = true;
  177. }
  178. return false;
  179. }
  180. /// <summary>
  181. /// 检验Lid Release真空数值
  182. /// </summary>
  183. /// <returns></returns>
  184. private bool CheckLidReleaseVacuum()
  185. {
  186. double vacuumValue = _vpwCellDevice.CommonData.VacuumPressure;
  187. return vacuumValue >= _lidReleasePressure;
  188. }
  189. /// <summary>
  190. /// open vent valve
  191. /// </summary>
  192. /// <returns></returns>
  193. private bool OpenVentValve()
  194. {
  195. bool result = _vpwCellDevice.VentValveOn();
  196. if (!result)
  197. {
  198. NotifyError(eEvent.ERR_VPW, "open vent valve failed", 0);
  199. }
  200. return result;
  201. }
  202. /// <summary>
  203. /// close vent valve
  204. /// </summary>
  205. /// <returns></returns>
  206. private bool CloseVentValve()
  207. {
  208. bool result = _vpwCellDevice.VentValveOff();
  209. if (!result)
  210. {
  211. NotifyError(eEvent.ERR_VPW, "close vent valve failed", 0);
  212. }
  213. return result;
  214. }
  215. /// <summary>
  216. /// Chamber down
  217. /// </summary>
  218. /// <returns></returns>
  219. private bool ChamberDown()
  220. {
  221. bool result= _mainDevice.ChamberDown();
  222. if (!result)
  223. {
  224. NotifyError(eEvent.ERR_VPW, "chamber down failed",0);
  225. }
  226. return result;
  227. }
  228. /// <summary>
  229. /// 检验Chamber是否打开
  230. /// </summary>
  231. /// <returns></returns>
  232. private bool CheckChamberOpened()
  233. {
  234. return _mainDevice.CommonData.ChamberOpened && !_mainDevice.CommonData.ChamberClosed;
  235. }
  236. /// <summary>
  237. /// Chamber up
  238. /// </summary>
  239. /// <returns></returns>
  240. private bool ChamberUp()
  241. {
  242. bool result = _mainDevice.ChamberUp();
  243. if (!result)
  244. {
  245. NotifyError(eEvent.ERR_VPW, "chamber up failed", 0);
  246. }
  247. return result;
  248. }
  249. /// <summary>
  250. /// 检验Chamber是否关闭
  251. /// </summary>
  252. /// <returns></returns>
  253. private bool CheckChamberClosed()
  254. {
  255. return !_mainDevice.CommonData.ChamberOpened && _mainDevice.CommonData.ChamberClosed;
  256. }
  257. /// <summary>
  258. /// 检验真空
  259. /// </summary>
  260. /// <returns></returns>
  261. private bool LastCheckVacuumValue()
  262. {
  263. double vacuumValue = _vpwCellDevice.CommonData.VacuumPressure;
  264. if (vacuumValue >= _recipe.VacuumTarget)
  265. {
  266. return true;
  267. }
  268. if (DateTime.Now.Subtract(_pumpDownTime).TotalMilliseconds >= _pumpDownWarningTime)
  269. {
  270. AlarmListManager.Instance.AddWarn(Module, "vacuum value", $"vacuum value {vacuumValue} is less than {_recipe.VacuumTarget}");
  271. }
  272. return false;
  273. }
  274. /// <summary>
  275. /// 打开相应的cell valve
  276. /// </summary>
  277. /// <returns></returns>
  278. private bool OpenCellValve()
  279. {
  280. int count = 0;
  281. int enableCount = 0;
  282. if (_recipe.VacuumPrewetDripEnable)
  283. {
  284. count += _vpwCellDevice.FlowDripOn()?1:0;
  285. enableCount++;
  286. }
  287. if (_recipe.VacuumPrewetLargeEnable)
  288. {
  289. count += _vpwCellDevice.FlowLargeOn() ? 1 : 0;
  290. enableCount++;
  291. }
  292. if (_recipe.VacuumPrewetSmallEnable)
  293. {
  294. count += _vpwCellDevice.FlowSmallOn() ? 1 : 0;
  295. enableCount++;
  296. }
  297. bool result = StartRotation();
  298. if (!result)
  299. {
  300. NotifyError(eEvent.ERR_VPW, "start rotation failed", 0);
  301. return false;
  302. }
  303. result= count == enableCount;
  304. if (!result)
  305. {
  306. NotifyError(eEvent.ERR_VPW, "open cell valve failed", 0);
  307. }
  308. return result;
  309. }
  310. /// <summary>
  311. /// 同时旋转
  312. /// </summary>
  313. /// <returns></returns>
  314. private bool StartRotation()
  315. {
  316. int targetPosition = 0;
  317. int maxSpeed = 0;
  318. int second = 0;
  319. foreach(var item in _recipe.VacuumRinseStep)
  320. {
  321. second += item.DurationSeconds;
  322. int speed = item.RotationSpeed;
  323. if (maxSpeed < speed)
  324. {
  325. maxSpeed = speed;
  326. }
  327. }
  328. foreach(var item in _recipe.VentRinseStep)
  329. {
  330. second += item.DurationSeconds;
  331. int speed = item.RotationSpeed;
  332. if (maxSpeed < speed)
  333. {
  334. maxSpeed = speed;
  335. }
  336. }
  337. foreach(var item in _recipe.ExtendCleanRinseStep)
  338. {
  339. second += item.DurationSeconds;
  340. int speed = item.RotationSpeed;
  341. if (maxSpeed < speed)
  342. {
  343. maxSpeed = speed;
  344. }
  345. }
  346. targetPosition = maxSpeed * (second + 60 * 1000);//按最大速度*(时间+多出一分钟)
  347. _vpwCellDevice.SetRotationSpeed(_recipe.VacuumRinseStep[0].RotationSpeed / 6);
  348. return _vpwCellDevice.RotationProfilePosition(targetPosition);
  349. }
  350. /// <summary>
  351. /// 启动
  352. /// </summary>
  353. /// <param name="objs"></param>
  354. /// <returns></returns>
  355. public RState Start(params object[] objs)
  356. {
  357. _recipe=(VpwRecipe)objs[0];
  358. _vpwCellDevice = DEVICE.GetDevice<VpwCellDevice>(Module);
  359. _mainDevice = DEVICE.GetDevice<VpwMainDevice>(ModuleName.VPWMain1.ToString());
  360. _pumpDownWarningTime = SC.GetValue<int>($"{Module}.PumpDownWarningTime")*1000;
  361. _pumpDownTimeOut = SC.GetValue<int>($"{Module}.PumpDownTimeout")*1000;
  362. _lidReleasePressure = SC.GetValue<int>($"{Module}.LidReleasePressure");
  363. _lidReleasePressureTimeout = SC.GetValue<int>($"{Module}.LidReleasePressureTimeout");
  364. _isNeedRetry = false;
  365. return Runner.Start(Module, $"{Module} prepare");
  366. }
  367. /// <summary>
  368. /// 重试
  369. /// </summary>
  370. /// <param name="step"></param>
  371. public RState Retry(int step)
  372. {
  373. if (_recipe == null)
  374. {
  375. NotifyError(eEvent.ERR_RINSE, "recipe is null", -1);
  376. return RState.Failed;
  377. }
  378. List<Enum> preStepIds = new List<Enum>();
  379. return Runner.Retry(PrepareStep.OpenVacuumValve, preStepIds, Module, "Vacuum Prewet Retry");
  380. }
  381. }
  382. }