SicMultiplate/Modules/Mainframe/PMs/Routines/PMMfcRorRoutine.cs

452 lines
17 KiB
C#
Raw Normal View History

2023-06-05 14:39:23 +08:00
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;
2023-06-05 17:30:39 +08:00
using SicModules.PMs.Utilities;
2023-06-08 17:34:02 +08:00
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.DBCore;
2023-06-13 09:23:22 +08:00
using Aitex.Core.Common.DeviceData;
2023-06-05 14:39:23 +08:00
namespace SicModules.PMs.Routines
{
public class PMMfcRorRoutine : PMBaseRoutine
{
private enum RoutineStep
{
TimeDelay1,
TimeDelay2,
TimeDelay3,
TimeDelay4,
TimeDelay5,
TimeDelay6,
TimeDelay7,
TimeDelay8,
TimeDelay9,
2023-06-07 17:41:20 +08:00
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,
2023-06-08 17:34:02 +08:00
SetMaintainPressure1,
SetMaintainPressure2,
2023-06-07 17:41:20 +08:00
CalStandardMfc,
CalTestMfc,
2023-06-08 17:34:02 +08:00
CalBasePressure1,
CalBasePressure2,
2023-06-05 14:39:23 +08:00
}
private ModuleName moduleName;
2023-06-08 17:34:02 +08:00
2023-06-05 14:39:23 +08:00
private PMModule _pmModule;
2023-06-07 17:41:20 +08:00
private MfcRorData _mfcData;
2023-06-05 14:39:23 +08:00
private Stopwatch _swTimer = new Stopwatch();
2023-06-07 17:41:20 +08:00
//摩尔气体常数
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;
2023-06-08 17:34:02 +08:00
private bool _flag;
private string _startTime;
private string _endTime;
2023-06-05 14:39:23 +08:00
public PMMfcRorRoutine(ModuleName module, PMModule pm) : base(module, pm)
{
moduleName = module;
_pmModule = pm;
2023-06-05 17:30:39 +08:00
Name = "MfcRor";
2023-06-05 14:39:23 +08:00
2023-06-07 17:41:20 +08:00
_IoThrottle = DEVICE.GetDevice<IoThrottleValve2>($"{Module}.TV");
}
2023-06-05 14:39:23 +08:00
public override Result Start(params object[] objs)
{
Reset();
2023-06-07 17:41:20 +08:00
_mfcData = (MfcRorData)objs[0];
_pressureMaxDiff = SC.GetValue<double>($"PM.{Module}.ThrottlePressureMaxDiff");
_throttleTimeout = SC.GetValue<int>($"PM.{Module}.ThrottlePressureTimeout");
2023-06-05 14:39:23 +08:00
_startTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
2023-06-05 14:39:23 +08:00
_swTimer.Restart();
2023-06-08 17:34:02 +08:00
Notify($"Start {_mfcData.Name} ROR");
2023-06-05 14:39:23 +08:00
return Result.RUN;
}
public override Result Monitor()
{
try
{
//CheckRoutineTimeOut();
2023-06-08 17:34:02 +08:00
CalBasePressure((int)RoutineStep.CalBasePressure1);
if (_flag)
2023-06-07 17:41:20 +08:00
{
//打开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);
2023-06-08 17:34:02 +08:00
if (_mfcData.IsStandardMfc)
{
//记录第一次保压值
TimeDelay((int)RoutineStep.TimeDelay3, _mfcData.Interval);
SetRorMaintainPressure((int)RoutineStep.SetMaintainPressure1, 1);
//记录第二次保压值
TimeDelay((int)RoutineStep.TimeDelay4, _mfcData.Interval);
SetRorMaintainPressure((int)RoutineStep.SetMaintainPressure2, 2);
}
2023-06-07 17:41:20 +08:00
//设定MFC流量
SetMfcFlow((int)RoutineStep.SetMfcFlow_1, _mfcData.Name, _mfcData.SetFlow, 3);
2023-06-08 17:34:02 +08:00
TimeDelay((int)RoutineStep.TimeDelay5, 3);
2023-06-07 17:41:20 +08:00
//记录第一次压力值
2023-06-08 17:34:02 +08:00
TimeDelay((int)RoutineStep.TimeDelay6, _mfcData.Interval);
SetRorPressure((int)RoutineStep.SetPressure1, 1);
2023-06-07 17:41:20 +08:00
//记录第二次压力值
2023-06-08 17:34:02 +08:00
TimeDelay((int)RoutineStep.TimeDelay7, _mfcData.Interval);
SetRorPressure((int)RoutineStep.SetPressure2, 2);
2023-06-07 17:41:20 +08:00
//记录第三次压力值
2023-06-08 17:34:02 +08:00
TimeDelay((int)RoutineStep.TimeDelay8, _mfcData.Interval);
SetRorPressure((int)RoutineStep.SetPressure3, 3);
2023-06-05 14:39:23 +08:00
2023-06-07 17:41:20 +08:00
//记录第四次压力值
2023-06-08 17:34:02 +08:00
TimeDelay((int)RoutineStep.TimeDelay9, _mfcData.Interval);
SetRorPressure((int)RoutineStep.SetPressure4, 4);
2023-06-07 17:41:20 +08:00
//设定MFC流量
SetMfcFlow((int)RoutineStep.SetMfcFlow_2, _mfcData.Name, 0, 3);
2023-06-08 17:34:02 +08:00
CalBasePressure((int)RoutineStep.CalBasePressure2);
if (_flag)
2023-06-07 17:41:20 +08:00
{
//打开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);
}
2023-06-05 14:39:23 +08:00
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
_swTimer.Stop();
2023-06-05 17:30:39 +08:00
2023-06-05 14:39:23 +08:00
return Result.DONE;
}
2023-06-08 17:34:02 +08:00
private void CalBasePressure(int id)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
_flag = _pmModule.GetChamberPressure() > _mfcData.BasePressure;
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
2023-06-07 17:41:20 +08:00
//计算标准MFC,求得反应腔压力
private void CalStandardMfc(int id)
{
2023-06-08 17:34:02 +08:00
Tuple<bool, Result> ret = Execute(id, () =>
{
if (_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference > 0)
{
_mfcData.Volume = 100000 * (_mfcData.SetFlow * 0.001 / Vm * R * _mfcData.Temperature) /
((_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference) / (_mfcData.Interval / 60.0) / 0.01);
//保留2位小数
_mfcData.Volume = Math.Round(_mfcData.Volume, 2);
_endTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
//数据保存至数据库
2023-06-09 18:31:58 +08:00
string sql = string.Format($"insert into \"pm_mfcror\"(\"starttime\",\"endtime\",\"name\",\"module\",\"scale\",\"pressure1\",\"pressure2\",\"pressure3\",\"pressure4\",\"actualflow\",\"setflow\",\"temperature\",\"interval\",\"isstandardmfc\",\"maintainpressure1\",\"maintainpressure2\",\"maintainpressuredifference\",\"volume\",\"meandifferencepressure\",\"basepressure\") values('{_startTime}','{_endTime}','{_mfcData.Name}','{_mfcData.Module}','{_mfcData.Scale}','{_mfcData.Pressure1}','{_mfcData.Pressure2}','{_mfcData.Pressure3}','{_mfcData.Pressure4}','{_mfcData.ActualFlow}','{_mfcData.SetFlow}','{_mfcData.Temperature}','{_mfcData.Interval}','{_mfcData.IsStandardMfc}','{_mfcData.MaintainPressure1}','{_mfcData.MaintainPressure2}','{_mfcData.MaintainPressureDifference}','{_mfcData.Volume}','{_mfcData.MeanDifferencePressure}','{_mfcData.BasePressure}')");
List<string> cmdList = new List<string>() { sql };
if(DB.ExcuteTransAction(cmdList))
{
2023-06-13 09:23:22 +08:00
//设置基准MFC
_pmModule.StandardMfcRorData = _mfcData;
Notify($"{_mfcData.Name} ROR Finished! Chamber Volume is {_mfcData.Volume};Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
else
{
EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
2023-06-08 17:34:02 +08:00
}
else
{
EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
2023-06-07 17:41:20 +08:00
2023-06-08 17:34:02 +08:00
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
2023-06-07 17:41:20 +08:00
}
//计算测试MFC,求得实际流量
private void CalTestMfc(int id)
2023-06-05 14:39:23 +08:00
{
2023-06-08 17:34:02 +08:00
Tuple<bool, Result> ret = Execute(id, () =>
{
if (_mfcData.SetFlow != 0)
{
_mfcData.ActualFlow = ((_mfcData.MeanDifferencePressure - _mfcData.MaintainPressureDifference) / (0.01 * (_mfcData.Interval / 60.0))) * (_mfcData.Volume / 100000.0 / (R * _mfcData.Temperature)) * Vm;
2023-06-08 17:34:02 +08:00
_mfcData.Deviation = (_mfcData.ActualFlow / _mfcData.SetFlow - 1) * 100;
//保留2位小数
2023-06-12 14:35:24 +08:00
_mfcData.Deviation = Math.Round(_mfcData.Deviation, 2);
_mfcData.Volume = Math.Round(_mfcData.Volume, 2);
2023-06-12 14:35:24 +08:00
//大于3%的MFC为超标
_mfcData.IsOverStandard = _mfcData.Deviation > 3;
_endTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
2023-06-08 17:34:02 +08:00
//数据保存至数据库
2023-06-12 14:35:24 +08:00
string sql = string.Format($"insert into \"pm_mfcror\"(\"starttime\",\"endtime\",\"name\",\"module\",\"scale\",\"pressure1\",\"pressure2\",\"pressure3\",\"pressure4\",\"actualflow\",\"setflow\",\"temperature\",\"interval\",\"isstandardmfc\",\"maintainpressure1\",\"maintainpressure2\",\"maintainpressuredifference\",\"volume\",\"meandifferencepressure\",\"basepressure\",\"deviation\",\"IsOverStandard\") values('{_startTime}','{_endTime}','{_mfcData.Name}','{_mfcData.Module}','{_mfcData.Scale}','{_mfcData.Pressure1}','{_mfcData.Pressure2}','{_mfcData.Pressure3}','{_mfcData.Pressure4}','{_mfcData.ActualFlow}','{_mfcData.SetFlow}','{_mfcData.Temperature}','{_mfcData.Interval}','{_mfcData.IsStandardMfc}','{_mfcData.MaintainPressure1}','{_mfcData.MaintainPressure2}','{_mfcData.MaintainPressureDifference}','{_mfcData.Volume}','{_mfcData.MeanDifferencePressure}','{_mfcData.BasePressure}','{_mfcData.Deviation}','{_mfcData.IsOverStandard}')");
2023-06-05 14:39:23 +08:00
List<string> cmdList = new List<string>() { sql };
if (DB.ExcuteTransAction(cmdList))
{
Notify($"{_mfcData.Name} ROR Finished! {_mfcData.Name} Deviation is {_mfcData.Deviation}%;Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
else
{
EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
}
else
{
EV.PostWarningLog(Module, $"{_mfcData.Name} ROR Failed! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
}
2023-06-08 17:34:02 +08:00
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
2023-06-07 17:41:20 +08:00
}
2023-06-08 17:34:02 +08:00
//设定压力
private void SetRorPressure(int id,int index)
2023-06-07 17:41:20 +08:00
{
2023-06-08 17:34:02 +08:00
Tuple<bool, Result> ret = Execute(id, () =>
2023-06-07 17:41:20 +08:00
{
2023-06-08 17:34:02 +08:00
switch (index)
{
case 1:
{
_mfcData.Pressure1 = _pmModule.GetChamberPressure();
}
break;
case 2:
{
_mfcData.Pressure2 = _pmModule.GetChamberPressure();
}
break;
case 3:
{
_mfcData.Pressure3 = _pmModule.GetChamberPressure();
}
break;
case 4:
{
_mfcData.Pressure4 = _pmModule.GetChamberPressure();
_mfcData.MeanDifferencePressure = (_mfcData.Pressure4 - _mfcData.Pressure1) / 3.0;
}
break;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
}
}
//设定保压压力
private void SetRorMaintainPressure(int id, int index)
{
Tuple<bool, Result> ret = Execute(id, () =>
{
switch (index)
{
case 1:
{
_mfcData.MaintainPressure1 = _pmModule.GetChamberPressure();
}
break;
case 2:
{
_mfcData.MaintainPressure2 = _pmModule.GetChamberPressure();
_mfcData.MaintainPressureDifference = _mfcData.MaintainPressure2 - _mfcData.MaintainPressure1;
}
break;
}
return true;
});
if (ret.Item1)
{
if (ret.Item2 == Result.FAIL)
{
throw (new RoutineFaildException());
}
else
throw (new RoutineBreakException());
2023-06-07 17:41:20 +08:00
}
}
public override void Abort()
{
2023-06-05 14:39:23 +08:00
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());
// }
// }
//}
}
}