using Aitex.Core.RT.Device.Devices; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Equipment; using SicModules.PMs.Routines.Base; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using SicModules.PMs.Utilities; namespace SicModules.PMs.Routines { public class PMMfcRorRoutine : PMBaseRoutine { private enum RoutineStep { TimeDelay1, TimeDelay2, TimeDelay3, TimeDelay4, TimeDelay5, TimeDelay6, TimeDelay7, TimeDelay8, TimeDelay9, SetEPV2_1, SetEPV2_2, SetTVEnable_1, SetTVEnable_2, SetTVPressMode_1, SetTVPressMode_2, SetTV_1, SetTV_2, WaitTV_1, WaitTV_2, SetM2toM40, SetTVCloseMode_1, SetTVCloseMode_2, CloseTV_1, CloseTV_2, SetMfcFlow_1, SetMfcFlow_2, SetPressure1, SetPressure2, SetPressure3, SetPressure4, CalStandardMfc, CalTestMfc, } private ModuleName moduleName; private PMModule _pmModule; private MfcRorData _mfcData; private Stopwatch _swTimer = new Stopwatch(); //摩尔气体常数 private const double R = 8.314; //气体摩尔体积 private const double Vm = 22.414; private IoThrottleValve2 _IoThrottle; private int _IoValueTimeout = 10; private double _pressureMaxDiff; private int _throttleTimeout; private double _ventBasePressure; private double _pumpBasePressure; public PMMfcRorRoutine(ModuleName module, PMModule pm) : base(module, pm) { moduleName = module; _pmModule = pm; Name = "MfcRor"; _IoThrottle = DEVICE.GetDevice($"{Module}.TV"); } public override Result Start(params object[] objs) { Reset(); _mfcData = (MfcRorData)objs[0]; _pressureMaxDiff = SC.GetValue($"PM.{Module}.ThrottlePressureMaxDiff"); _throttleTimeout = SC.GetValue($"PM.{Module}.ThrottlePressureTimeout"); _swTimer.Restart(); Notify($"Start MfcRor"); return Result.RUN; } public override Result Monitor() { try { //CheckRoutineTimeOut(); if(_IoThrottle.PressureFeedback > _mfcData.BasePressure) { //打开EPV2 SetIoValueByGroup((int)RoutineStep.SetEPV2_1, IoGroupName.EPV2, true, _IoValueTimeout); //设置蝶阀Enable SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable_1, _IoThrottle, 5); //设置蝶阀为压力模式 SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode_1, _IoThrottle, 5); //伺服压力设定值到0mbar SetThrottlePressureAndWaitSetPoint((int)RoutineStep.SetTV_1, _IoThrottle, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); //等待腔体压力Pump到设定值 WaitChamberPressDownTo((int)RoutineStep.WaitTV_1, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); } //关闭蝶阀,再关闭EPV2 SetThrottleToCloseMode((int)RoutineStep.SetTVCloseMode_1, _IoThrottle, 8); SetThrottleDisable((int)RoutineStep.CloseTV_1, _IoThrottle, 8); TimeDelay((int)RoutineStep.TimeDelay1, 1); SetIoValueByGroup((int)RoutineStep.SetEPV2_2, IoGroupName.EPV2, false, _IoValueTimeout); TimeDelay((int)RoutineStep.TimeDelay2, 3); //设定MFC流量 SetMfcFlow((int)RoutineStep.SetMfcFlow_1, _mfcData.Name, _mfcData.SetFlow, 3); TimeDelay((int)RoutineStep.TimeDelay3, 3); //记录第一次压力值 TimeDelay((int)RoutineStep.TimeDelay4, _mfcData.Interval); SetMfcRorPressure((int)RoutineStep.SetPressure1, 1, _IoThrottle.PressureFeedback); //记录第二次压力值 TimeDelay((int)RoutineStep.TimeDelay5, _mfcData.Interval); SetMfcRorPressure((int)RoutineStep.SetPressure2, 2, _IoThrottle.PressureFeedback); //记录第三次压力值 TimeDelay((int)RoutineStep.TimeDelay6, _mfcData.Interval); SetMfcRorPressure((int)RoutineStep.SetPressure3, 3, _IoThrottle.PressureFeedback); //记录第四次压力值 TimeDelay((int)RoutineStep.TimeDelay7, _mfcData.Interval); SetMfcRorPressure((int)RoutineStep.SetPressure4, 4, _IoThrottle.PressureFeedback); //设定MFC流量 SetMfcFlow((int)RoutineStep.SetMfcFlow_2, _mfcData.Name, 0, 3); if (_IoThrottle.PressureFeedback > _mfcData.BasePressure) { //打开EPV2 SetIoValueByGroup((int)RoutineStep.SetEPV2_2, IoGroupName.EPV2, true, _IoValueTimeout); //设置蝶阀Enable SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable_2, _IoThrottle, 5); //设置蝶阀为压力模式 SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode_2, _IoThrottle, 5); //伺服压力设定值到0mbar SetThrottlePressureAndWaitSetPoint((int)RoutineStep.SetTV_2, _IoThrottle, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); //等待腔体压力Pump到设定值 WaitChamberPressDownTo((int)RoutineStep.WaitTV_2, _pumpBasePressure, _pressureMaxDiff, _throttleTimeout); } //计算 if(_mfcData.IsStandardMfc) { CalStandardMfc((int)RoutineStep.CalStandardMfc); } else { CalTestMfc((int)RoutineStep.CalTestMfc); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s"); _swTimer.Stop(); return Result.DONE; } //计算标准MFC,求得反应腔压力 private void CalStandardMfc(int id) { _mfcData.MeanDifferentialPressure = (_mfcData.Pressure4 - _mfcData.Pressure1) / 3.0; _mfcData.Volume = 100000 * (_mfcData.SetFlow * 0.001 / Vm * R * _mfcData.Temperature) / ((_mfcData.MeanDifferentialPressure - 0) / (_mfcData.Interval/60.0)/0.01); } //计算测试MFC,求得实际流量 private void CalTestMfc(int id) { _mfcData.ActualFlow = ((_mfcData.MeanDifferentialPressure - 0)/(0.01 * (_mfcData.Interval / 60.0))) * (_mfcData.Volume / 100000.0 / (R * _mfcData.Temperature)) * Vm; _mfcData.Deviation = (_mfcData.ActualFlow / _mfcData.SetFlow - 1) * 100; } private void SetMfcRorPressure(int id,int index,double value) { switch(index) { case 1: { _mfcData.Pressure1 = value; } break; case 2: { _mfcData.Pressure2 = value; } break; case 3: { _mfcData.Pressure3 = value; } break; case 4: { _mfcData.Pressure4 = value; } break; } } public override void Abort() { 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()); // } // } //} } }