123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629 |
- using Aitex.Common.Util;
- using Aitex.Core.Common.DeviceData;
- using Aitex.Core.RT.DataCenter;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.IOCore;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.OperationCenter;
- using Aitex.Core.RT.ParameterCenter;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.RT.Tolerance;
- using Aitex.Core.Util;
- using MECF.Framework.Common.CommonData;
- using MECF.Framework.Common.Device.Bases;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.Event;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Xml;
- namespace FurnaceRT.Devices
- {
- public class IoHeater : HeaterBase
- {
- public IoHeater(string module, XmlElement node, string ioModule = "")
- {
- base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module");
- base.Name = node.GetAttribute("id");
- base.Display = node.GetAttribute("display");
- base.DeviceID = node.GetAttribute("schematicId");
- formatString = node.GetAttribute("formatString");
- InstallZone = node.GetAttribute("installzone");
- _uniqueName = $"{Module}{Name}";
- _isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
- _aiCascadePV = ParseAiNode("aiCascadePV", node, ioModule);
- _aiHeaterPV = ParseAiNode("aiHeaterPV", node, ioModule);
- _aiWorkingOutput = ParseAiNode("aiWorkingOutput", node, ioModule);
- _aiOverTemp = ParseAiNode("aiOverTemp", node, ioModule);
- _aoCascadeControlModeSetPoint = ParseAoNode("aoCascadeControlModeSetPoint", node, ioModule);
- _aoHeaterControlModeSetPoint = ParseAoNode("aoHeaterControlModeSetPoint", node, ioModule);
- _aoCascadePID_P = ParseAoNode("aoCascadePID_P", node, ioModule);
- _aoCascadePID_I = ParseAoNode("aoCascadePID_I", node, ioModule);
- _aoCascadePID_D = ParseAoNode("aoCascadePID_D", node, ioModule);
- _aoHeaterPID_P = ParseAoNode("aoHeaterPID_P", node, ioModule);
- _aoHeaterPID_I = ParseAoNode("aoHeaterPID_I", node, ioModule);
- _aoHeaterPID_D = ParseAoNode("aoHeaterPID_D", node, ioModule);
- _aoUpRate = ParseAoNode("aoUpRate", node, ioModule);
- _aoDownRate = ParseAoNode("aoDownRate", node, ioModule);
- _aoTCOpenOffsetOffset = ParseAoNode("aoTCOpenOffsetOffset", node, ioModule);
- _diCascadePVSBrk = ParseDiNode("diCascadePVSBrk", node, ioModule);
- _diHeaterPVSBrk = ParseDiNode("diHeaterPVSBrk", node, ioModule);
- _diEnableOutput = ParseDiNode("diEnableOutput", node, ioModule);
- _doEnableIn = ParseDoNode("doEnableIn", node, ioModule);
- _doAutoManual = ParseDoNode("doAutoManual", node, ioModule);
- _doSelect = ParseDoNode("doMainPVSelect", node, ioModule);
- _doCascadeMode = ParseDoNode("doCascadeMode", node, ioModule);
- _scRoot = node.GetAttribute("scRoot");
- }
- #region fields
- private AIAccessor _aiCascadePV;
- private AIAccessor _aiHeaterPV;
- private AIAccessor _aiWorkingOutput;
- private AIAccessor _aiOverTemp;
- private AOAccessor _aoCascadeControlModeSetPoint;
- private AOAccessor _aoHeaterControlModeSetPoint;
- private AOAccessor _aoCascadePID_P;
- private AOAccessor _aoCascadePID_I;
- private AOAccessor _aoCascadePID_D;
- private AOAccessor _aoHeaterPID_P;
- private AOAccessor _aoHeaterPID_I;
- private AOAccessor _aoHeaterPID_D;
- private AOAccessor _aoUpRate;
- private AOAccessor _aoDownRate;
- private AOAccessor _aoTCOpenOffsetOffset;
- private DIAccessor _diCascadePVSBrk;
- private DIAccessor _diHeaterPVSBrk;
- private DIAccessor _diEnableOutput;
- private DOAccessor _doEnableIn;
- private DOAccessor _doAutoManual;
- private DOAccessor _doSelect;
- private DOAccessor _doCascadeMode;
- private string formatString;
- private const int physicalMax = 16000;
- private ToleranceChecker _toleranceCheckerWarning = new ToleranceChecker();
- private ToleranceChecker _toleranceCheckerAlarm = new ToleranceChecker();
- //tolerance check
- private float _alarmJudgmentRange;
- private float _warningJudgmentRange;
- private float _alarmJudgmentTime;
- private float _warningJudgmentTime;
- private float _toleranceJudgmentDelayTime;
- private DeviceTimer _toleranceJudgmentDelayTimer = new DeviceTimer();
- //stable check
- private Stopwatch _stableJudgmentTimer = new Stopwatch();
- private float _stableJudgmentTime = 1;
- private float _stableMinValue;
- private float _stableMaxValue;
- private SCConfigItem _scEnableCalibration;
- private SCConfigItem _scCalibrationTable;
- private SCConfigItem _scRange;
- private SCConfigItem _scRampRate;//°C/min
- private List<CalibrationItem> _calibrationTable = new List<CalibrationItem>();
- private string _previousSetting;
- private DeviceTimer _rampTimer = new DeviceTimer();
- private double _rampTarget;
- private double _rampInitValue;
- private int _rampTime;
- private DeviceTimer _stableTimer = new DeviceTimer();
- private bool _isWarned;
- private string _uniqueName;
- private float _tempSetpoint = 0.0f;
- private string _scRoot;
- private bool _isStartRamp = false;
- private bool _isFloatAioType = false;
- private Dictionary<string, int> _pidTableAssociate;
- #region temp correct
- private float _profileTemp = 0;
- private float _profileCorrect = 0;
- private float _profileTCCalib = 0;
- private float _cascadeTCCorrect = 0;
- public string CurrentCorrectFileName { get; private set; }
- public int CurrentCorrectIndex { get; private set; }
- private string _writeLog = "";
- #endregion
- #region temp profile
- private float _preheatTime = 0;
- private float _checkTime = 0;
- private float _checkLimit = 0;
- private float _alarmLimit = 0;
- private float _totalTime = 0;
- private Stopwatch _profileTimer = new Stopwatch();
- private Stopwatch _profileStableTimer = new Stopwatch();
- public bool IsProfileMode => _profileTimer != null && _profileTimer.IsRunning;
- public bool IsProfileSuccess { get; set; }
- private R_TRIG _profileTotalTimeoutTrig = new R_TRIG();
- private R_TRIG _profileAlarmLimitTrig = new R_TRIG();
- private R_TRIG _profileSuccessTrig = new R_TRIG();
- private bool _isWait;
- private float _waitHigh;
- private float _waitLow;
- private bool _isInit = false;
- private Stopwatch _initTimer = new Stopwatch();
- #endregion
- #endregion
- #region properties
- public string InstallZone { get; set; }
- public double Range => _scRange.DoubleValue;
- public AlarmEventItem AlarmToleranceWarning { get; set; }
- public AlarmEventItem AlarmToleranceAlarm { get; set; }
- public AlarmEventItem InterlockAlarm { get; set; }
- public AlarmEventItem HeaterErrorAlarm { get; set; }
- public AlarmEventItem HeaterErrorRecoveryWarning { get; set; }
- public AlarmEventItem HeaterStripBreakAlarm { get; set; }
- public AlarmEventItem HeaterStripBreakWarning { get; set; }
- public bool IsHeaterStripBreak { get; set; }
- private RD_TRIG _trigHeaterErrorSignalOn = new RD_TRIG();
- public R_TRIG TrigHeaterStripBreakSignalOn = new R_TRIG();
- public DeviceTimer HeaterStripBreakTimer = new DeviceTimer();
- public string InstallPosition => SC.GetStringValue($"{_scRoot}.Heater.{InstallZone}.{Name}.InstallPosition");
- public bool IsError => _diCascadePVSBrk == null || _diHeaterPVSBrk == null ? false : _diCascadePVSBrk.Value || _diHeaterPVSBrk.Value;
- private R_TRIG _tcBreakTrig = new R_TRIG();
- public bool IsStable
- {
- get
- {
- if (_stableJudgmentTimer.IsRunning)
- {
- if (DeviceData.FeedBack < (DeviceData.SetPoint - _stableMinValue) ||
- DeviceData.FeedBack > (DeviceData.SetPoint + _stableMaxValue))
- {
- _stableJudgmentTimer.Restart();
- }
- if (_stableJudgmentTimer.ElapsedMilliseconds >= _stableJudgmentTime * 1000)
- {
- return true;
- }
- }
- else
- {
- _stableJudgmentTimer.Restart();
- }
- return false;
- }
- }
- public override float TempSetPoint
- {
- get
- {
- return _tempSetpoint;
- }
- set
- {
- if (_aoCascadeControlModeSetPoint != null && _aoHeaterControlModeSetPoint != null)
- {
- if (_isFloatAioType)
- {
- if(ControlMode == 0)
- {
- if (Math.Abs(_aoCascadeControlModeSetPoint.FloatValue - value) > 0.0001)
- _aoCascadeControlModeSetPoint.FloatValue = value;
- }
- else
- {
- if (Math.Abs(_aoHeaterControlModeSetPoint.FloatValue - value) > 0.0001)
- _aoHeaterControlModeSetPoint.FloatValue = value;
- }
- }
- }
- }
- }
- public float HeaterPID_P
- {
- get
- {
- return _aoHeaterPID_P.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoHeaterPID_P.FloatValue - value) > 0.0001)
- _aoHeaterPID_P.FloatValue = value;
- }
- }
- public float HeaterPID_I
- {
- get
- {
- return _aoHeaterPID_I.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoHeaterPID_I.FloatValue - value) > 0.0001)
- _aoHeaterPID_I.FloatValue = value;
- }
- }
- public float HeaterPID_D
- {
- get
- {
- return _aoHeaterPID_D.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoHeaterPID_D.FloatValue - value) > 0.0001)
- _aoHeaterPID_D.FloatValue = value;
- }
- }
- public float CascadePID_P
- {
- get
- {
- return _aoCascadePID_P.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoCascadePID_P.FloatValue - value) > 0.0001)
- _aoCascadePID_P.FloatValue = value;
- }
- }
- public float CascadePID_I
- {
- get
- {
- return _aoCascadePID_I.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoCascadePID_I.FloatValue - value) > 0.0001)
- _aoCascadePID_I.FloatValue = value;
- }
- }
- public float CascadePID_D
- {
- get
- {
- return _aoCascadePID_D.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoCascadePID_D.FloatValue - value) > 0.0001)
- _aoCascadePID_D.FloatValue = value;
- }
- }
- public float UpRate
- {
- get
- {
- return _aoUpRate.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoUpRate.FloatValue - value) > 0.0001)
- _aoUpRate.FloatValue = value;
- }
- }
- public float DownRate
- {
- get
- {
- return _aoDownRate.FloatValue;
- }
- set
- {
- if (Math.Abs(_aoDownRate.FloatValue - value) > 0.0001)
- _aoDownRate.FloatValue = value;
- }
- }
- public int ControlMode
- {
- get
- {
- if (_doSelect != null && _doCascadeMode != null)
- {
- if (!_doSelect.Value && !_doCascadeMode.Value)
- {
- // Furnace control
- return 0;
- }
- else if (!_doSelect.Value && _doCascadeMode.Value)
- {
- // Heater control
- return 1;
- }
- else if (_doSelect.Value && _doCascadeMode.Value)
- {
- //Furnace Diect control
- return 2;
- }
- }
- return 0;
- }
- }
- public float TCOpenOffsetOffset
- {
- get
- {
- return _aoTCOpenOffsetOffset != null ? _aoTCOpenOffsetOffset.FloatValue : 0;
- }
- set
- {
- if (_aoTCOpenOffsetOffset != null && Math.Abs(_aoTCOpenOffsetOffset.FloatValue - value) > 0.0001)
- _aoTCOpenOffsetOffset.FloatValue = value;
- }
- }
- public override float TempFeedback => (float)(ControlMode == 1 ? (_aiHeaterPV == null ? 0 : _aiHeaterPV.FloatValue - _profileTCCalib) : (_aiCascadePV == null ? 0 : _aiCascadePV.FloatValue - _profileTCCalib));
- #endregion
- public override bool Initialize()
- {
- DeviceData = new AITHeaterData()
- {
- DeviceName = Name,
- DeviceSchematicId = DeviceID,
- DisplayName = Display,
- Module = Module,
-
- Scale = SC.GetValue<double>($"{_scRoot}.{Name}.Range"),
- OverTempScale= SC.GetValue<double>($"{_scRoot}.{Name}.OverTempRange"),
- //Scale = 1200,
- Unit = "°C",
- //SetPoint = TempSetPoint,
- FeedBack = TempFeedback,
- };
- _pidTableAssociate = new Dictionary<string, int>()
- {
- { "HeaterU",0 },
- { "HeaterCU",1 },
- { "HeaterC",2 },
- { "HeaterCL",3 },
- { "HeaterL",4 },
- };
- _scEnableCalibration = SC.GetConfigItem($"{_scRoot}.{Name}.EnableCalibration");
- _scCalibrationTable = SC.GetConfigItem($"{_scRoot}.{Name}.CalibrationTable");
- //_scRange = SC.GetConfigItem($"{_scRoot}.{Name}.Range");
- _scRampRate = SC.GetConfigItem($"{_scRoot}.{Name}.RampRate");
- //AlarmToleranceWarning = SubscribeAlarm($"{_scRoot}.{Name}.ToleranceWarning", "", ResetWarningChecker, EventLevel.Warning);
- //AlarmToleranceAlarm = SubscribeAlarm($"{_scRoot}.{Name}.ToleranceAlarm", "", ResetAlarmChecker);
- //AlarmToleranceWarning.Id = SC.ContainsItem($"{_scRoot}.{Name}.ToleranceWarningID") ? SC.GetValue<int>($"{_scRoot}.{Name}.ToleranceWarningID") : 0;
- //AlarmToleranceAlarm.Id = SC.ContainsItem($"{_scRoot}.{Name}.ToleranceAlarmID") ? SC.GetValue<int>($"{_scRoot}.{Name}.ToleranceAlarmID") : 0;
- //_stableJudgmentTime = (float)SC.GetValue<double>($"{_scRoot}.{Name}.Stabilize.JudgmentTime");
- //_stableMinValue = (float)SC.GetValue<double>($"{_scRoot}.{Name}.Stabilize.MinusValue");
- //_stableMaxValue = (float)SC.GetValue<double>($"{_scRoot}.{Name}.Stabilize.PlusValue");
- DATA.Subscribe($"{Module}.{Name}.CascadePV", () => (float)DeviceData.CascadePV);
- DATA.Subscribe($"{Module}.{Name}.HeaterPV", () => (float)DeviceData.HeaterPV);
- DATA.Subscribe($"{Module}.{Name}.CascadePID_P", () => (float)DeviceData.CascadePID_P);
- DATA.Subscribe($"{Module}.{Name}.CascadePID_I", () => (float)DeviceData.CascadePID_I);
- DATA.Subscribe($"{Module}.{Name}.CascadePID_D", () => (float)DeviceData.CascadePID_D);
- DATA.Subscribe($"{Module}.{Name}.HeaterPID_P", () => (float)DeviceData.HeaterPID_P);
- DATA.Subscribe($"{Module}.{Name}.HeaterPID_I", () => (float)DeviceData.HeaterPID_I);
- DATA.Subscribe($"{Module}.{Name}.HeaterPID_D", () => (float)DeviceData.HeaterPID_D);
- DATA.Subscribe($"{Module}.{Name}.CascadeControlModeSV", () => _aoCascadeControlModeSetPoint != null ? _aoCascadeControlModeSetPoint.FloatValue : 0.0f);
- DATA.Subscribe($"{Module}.{Name}.HeaterControlModeSV", () => _aoHeaterControlModeSetPoint != null ? _aoHeaterControlModeSetPoint.FloatValue : 0.0f);
- DATA.Subscribe($"{Module}.{Name}.UpRate", () => UpRate);
- DATA.Subscribe($"{Module}.{Name}.DownRate", () => DownRate);
- DATA.Subscribe($"{Module}.{Name}.WorkingOutput", () => _aiWorkingOutput.FloatValue);
- DATA.Subscribe($"{Module}.{Name}.OverTemp", () => _aiOverTemp.FloatValue);
- DATA.Subscribe($"{Module}.{Name}.IsCascadePVBreak", () => _diCascadePVSBrk.Value);
- DATA.Subscribe($"{Module}.{Name}.IsHeaterPVBreak", () => _diHeaterPVSBrk.Value);
- DATA.Subscribe($"{Module}.{Name}.IsEnableOutput", () => _diEnableOutput.Value);
- DATA.Subscribe($"{Module}.{Name}.IsEnableIn", () => _doEnableIn.Value);
- DATA.Subscribe($"{Module}.{Name}.IsAutoManual", () => _doAutoManual.Value);
- DATA.Subscribe($"{Module}.{Name}.IsSelect", () => _doSelect.Value);
- DATA.Subscribe($"{Module}.{Name}.IsCascadeMode", () => _doCascadeMode.Value);
- DATA.Subscribe($"{Module}.{Name}.ControlMode", () => ControlMode);
- DATA.Subscribe($"{Module}.{Name}.TCOpenOffsetOffset", () => TCOpenOffsetOffset);
- OP.Subscribe($"{Module}.{Name}.SetRemoteMode", SetRemoteMode);
- OP.Subscribe($"{Module}.{Name}.SetAutoTuning", SetAutoTuning);
- OP.Subscribe($"{Module}.{Name}.SetOnOff", SetOnOff);
- OP.Subscribe($"{Module}.{Name}.SetUpDownRate", (out string reason, int time, object[] param) =>
- {
- reason = string.Empty;
- SetUpDownRate(param);
- return true;
- });
- OP.Subscribe($"{Module}.{Name}.SetManualParameters", (out string reason, int time, object[] param) =>
- {
- reason = string.Empty;
- SetManualParameters(param);
- return true;
- });
- //recipe
- OP.Subscribe($"PM1.{Name}.SetParameters", (out string reason, int time, object[] param) =>
- {
- reason = string.Empty;
- SetParameters(param);
- return true;
- });
- _doEnableIn.SetValue(true, out _);
- var setLastPoint = SC.GetConfigItem($"PM1.Heater.{this.Name}.SetLastPoint");
- if (setLastPoint != null)
- {
- _tempSetpoint = (float)setLastPoint.DoubleValue;
- DeviceData.SetPoint = _tempSetpoint;
- }
- SetCorrectParameters(SC.GetStringValue("PM1.TempCorrection"));
- return base.Initialize();
- }
- public override void Monitor()
- {
- if(!string.IsNullOrEmpty(_writeLog))
- {
- LOG.Write(_writeLog);
- _writeLog = "";
- }
- if (!_isInit)
- {
- if (!_initTimer.IsRunning)
- _initTimer.Start();
- if (_initTimer.ElapsedMilliseconds > 5 * 1000)
- {
- _initTimer.Stop();
- _isInit = true;
- if (_tempSetpoint == 0)
- {
- if(ControlMode == 0)
- {
- if(_aoCascadeControlModeSetPoint != null && _aoCascadeControlModeSetPoint.FloatValue > 0)
- {
- _tempSetpoint = _aoCascadeControlModeSetPoint.FloatValue;
- }
- }
- else
- {
- if (_aoCascadeControlModeSetPoint != null && _aoHeaterControlModeSetPoint.FloatValue > 0)
- {
- _tempSetpoint = _aoHeaterControlModeSetPoint.FloatValue;
- }
- }
- }
- SetPIDParameters(SC.GetStringValue("PM1.Heater.PID"));
- }
- }
-
- if(DeviceData != null)
- {
- DeviceData.CascadePID_P = _aoCascadePID_P == null ? 0 : _aoCascadePID_P.FloatValue;
- DeviceData.CascadePID_I = _aoCascadePID_I == null ? 0 : _aoCascadePID_I.FloatValue;
- DeviceData.CascadePID_D = _aoCascadePID_D == null ? 0 : _aoCascadePID_D.FloatValue;
- DeviceData.HeaterPID_P = _aoHeaterPID_P == null ? 0 : _aoHeaterPID_P.FloatValue;
- DeviceData.HeaterPID_I = _aoHeaterPID_I == null ? 0 : _aoHeaterPID_I.FloatValue;
- DeviceData.HeaterPID_D = _aoHeaterPID_D == null ? 0 : _aoHeaterPID_D.FloatValue;
- DeviceData.OverTemp = _aiOverTemp == null ? 0 : _aiOverTemp.FloatValue;
- DeviceData.CascadePV = _aiCascadePV == null ? 0 : _aiCascadePV.FloatValue;
- DeviceData.HeaterPV = _aiHeaterPV == null ? 0 : _aiHeaterPV.FloatValue;
- DeviceData.FeedBack = TempFeedback;
- DeviceData.SetPoint = _tempSetpoint;
- DeviceData.ManipulatedVariable = _aiWorkingOutput == null ? 0 : _aiWorkingOutput.FloatValue;
- DeviceData.RampSetPoint = TempSetPoint;//Ramp的过程值
- DeviceData.Ramping = _aoUpRate == null ? 0 : _aoUpRate.FloatValue;
- DeviceData.ControlMode = ControlMode;// 控制模式
- DeviceData.IsAlarm = IsError;
- DeviceData.UpRateSetPoint = UpRate;
- DeviceData.DownRateSetPoint = DownRate;
- DeviceData.EnableOutput = _diEnableOutput.Value;
- DeviceData.IsCascadePVBreak = _diCascadePVSBrk.Value;
- DeviceData.IsHeaterPVBreak = _diHeaterPVSBrk.Value;
- DeviceData.IsProfiling = IsProfileMode;
- DeviceData.IsOverTempError = DeviceData.OverTemp > DeviceData.OverTempScale;
- DeviceData.IsTempLmtError = DeviceData.FeedBack > DeviceData.Scale;
- if (_profileTimer != null && _profileTimer.IsRunning)
- {
- DeviceData.ProfileTotalTime = _totalTime - _profileTimer.ElapsedMilliseconds / 1000 > 0 ? _totalTime - _profileTimer.ElapsedMilliseconds / 1000 : 0;
- DeviceData.ProfilePreheatTime = _preheatTime - _profileTimer.ElapsedMilliseconds / 1000 > 0 ? _preheatTime - _profileTimer.ElapsedMilliseconds / 1000 : 0;
- }
- if(_profileStableTimer != null && _profileStableTimer.IsRunning)
- {
- DeviceData.ProfileCheckTime = _checkTime - _profileStableTimer.ElapsedMilliseconds / 1000 > 0 ? _checkTime - _profileStableTimer.ElapsedMilliseconds / 1000 : 0;
- }
- }
-
- MonitorTolerance();
- Ramping();
- _tcBreakTrig.CLK = IsError;
- if (_tcBreakTrig.Q)
- TCOpenOffsetOffset = _profileCorrect;
- base.Monitor();
- }
- public override void SetTemperature(float temperature)
- {
- //if (temperature != SetpointFeedback)
- {
- var _rampTime = _scRampRate.DoubleValue != 0 ? (Math.Abs(temperature - TempFeedback) / _scRampRate.DoubleValue) * 60 * 1000 : 0;
- Ramp(temperature, (int)_rampTime);
- }
- }
- public void SetRamping(float ramping)
- {
- SaveRampRate(ramping.ToString("F1"));
- }
- private void SetManualParameters(object[] param)
- {
- //value:ramp
- if (param == null || param.Length < 1)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature set parameter");
- return;
- }
- var array = param[0].ToString().Split(';');
- if (array == null || array.Length < 2)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature set parameter");
- return;
- }
- float.TryParse(array[0], out float temperature);
- float.TryParse(array[1], out float rampTime);//°C/min
- DeviceData.SetPoint = temperature;
- DeviceData.RampSetPoint = rampTime;
- var profileCorrect = 0.0f;
- var profileTCCalib = 0.0f;
- //var actualSet = temperature - profileCorrect < 0 ? 0 : temperature - profileCorrect;
- var actualSet = temperature + _profileTCCalib;//加上flat zone的值
- UpRate = rampTime;
- DownRate = rampTime;
- var controlMode = "";
- if (array.Length > 2)
- {
- controlMode = array.Length > 2 ? array[2].ToString() : "";
- SetControlMode(controlMode);
- }
- _tempSetpoint = temperature;
- TempSetPoint = actualSet;
- LOG.Write($"{Name} setpoint={temperature} control mode={controlMode}");
- //Ramp(actualSet, (int)rampTime);
- }
- public void SetControlMode(string mode, string recipeProfileFileName = "")
- {
- var reason = "";
- DeviceData.ControlModeSetpoint = mode;
- switch(mode.ToLower())
- {
- case "heater":
- case "heater control":
- if(_doSelect.Value)
- _doSelect.SetValue(false, out reason);
- if (!_doCascadeMode.Value)
- _doCascadeMode.SetValue(true, out reason);
- break;
- case "furnace":
- case "furnace control":
- if (_doSelect.Value)
- _doSelect.SetValue(false, out reason);
- if (_doCascadeMode.Value)
- _doCascadeMode.SetValue(false, out reason);
- break;
- case "furnace direct":
- case "furnace direct control":
- if (!_doSelect.Value)
- _doSelect.SetValue(true, out reason);
- if (!_doCascadeMode.Value)
- _doCascadeMode.SetValue(true, out reason);
- break;
- default:
- if(mode.ToLower().StartsWith("profile"))
- {
- var arry = mode.Replace(")","").Split('(');
- if(arry != null && arry.Length > 1)
- {
- var profileArray = arry[1].Split(',');
- if(profileArray != null && profileArray.Length > 2)
- {
- var profileFileName = profileArray[0];
- int.TryParse(profileArray[1], out int profileTableIndex);
- GetProfileParameters(profileFileName, profileTableIndex, recipeProfileFileName);
- _profileTimer.Restart();
- _profileStableTimer.Stop();
- _profileTotalTimeoutTrig.RST = true;
- _profileAlarmLimitTrig.RST = true;
- _profileSuccessTrig.RST = true;
- IsProfileSuccess = false;
- DeviceData.ProfileResult = 0;
- LOG.Write($"{Name} profile start preheatTime={_preheatTime} checkTime={_checkTime} totalTime={_totalTime} checkLimit={_checkLimit} alarmLimit={_alarmLimit}");
- }
- }
- }
- break;
- }
- }
- private void SetUpDownRate(object[] param)
- {
- }
- public void SetParameters(object[] param)
- {
- if (param != null && param.Length > 0)
- {
- string zoneName = "";
- float temperature = 0.0f;
- string tempUnit = "";
- float ramp = 0.0f;
- string rampUnit = "";
- string controlMode = "";
- string correct = "";
- string PID = "";
- var array = param[0].ToString().Split(';');//zoneName;temp;tempUnit;ramp;rampUnit;checkWait;tempHigh;tempLow;unitStepCompletionCondition;controlMode;correct;PID
- if (System.Text.RegularExpressions.Regex.Match(array[1].ToString(), @"[a-zA-Z]").Success)
- {
- var table = array[1].ToString().Split(':');//AssociateParameterTable
- if (SC.ContainsItem($"PM1.RecipeEditParameter.TempSetting.{table[0]}.{Name}"))
- {
- temperature = (float)SC.GetValue<double>($"PM1.RecipeEditParameter.TempSetting.{table[0]}.{Name}");
- }
- }
- else
- {
- float.TryParse(array[1].ToString(), out temperature);
- }
- tempUnit = array.Length > 2 ? array[2].ToString() : "";
- if (array.Length > 3)
- {
- float.TryParse(array[3], out ramp);
- }
- rampUnit = array.Length > 4 ? array[4].ToString() : "";
- if (array.Length > 5)
- {
- bool.TryParse(array[5], out _isWait);
- }
- if (array.Length > 6)
- {
- float.TryParse(array[6], out _waitHigh);
- }
- if (array.Length > 7)
- {
- float.TryParse(array[7], out _waitLow);
- }
- var unitStepCompletionCondition = array.Length > 8 ? array[8].ToString() : "";
- _stableJudgmentTimer.Stop();
- controlMode = array.Length > 9 ? array[9].ToString() : "";
- correct = array.Length > 10 ? array[10].ToString() : "";
- PID = array.Length > 11 ? array[11].ToString() : "";
- var correctileName = array.Length > 12 ? array[12].ToString() : "";
- var PIDFileName = array.Length > 13 ? array[13].ToString() : "";
- var profileFileName = array.Length > 14 ? array[14].ToString() : "";
- var DPR = array.Length > 16 ? (array[15].ToString().ToLower() == "open" ? true : false) : false;
- var BWR = array.Length > 16 ? (array[15].ToString().ToLower() == "open" ? true : false) : false;
- SetControlMode(controlMode, profileFileName);
- SetPIDParameters(PID, PIDFileName);
- SetCorrectParameters(correct, correctileName, profileFileName);
- var profileCorrect = 0.0f;
- var profileTCCalib = 0.0f;
- //var actualSet = temperature - profileCorrect < 0 ? 0 : temperature - profileCorrect;
- var actualSet = temperature + _profileTCCalib;//加上flat zone的值
- float _rampTime = 0;
- if(DPR && BWR)
- {
- DownRate = 0;
- UpRate = 0;
- }
- else
- {
- if (ramp == 0)
- {
- DownRate = Math.Abs(TempFeedback - actualSet);//单位是°C/min
- UpRate = Math.Abs(TempFeedback - actualSet);//单位是°C/min
- }
- else if (rampUnit.ToLower() == "time")
- {
- DownRate = Math.Abs(TempFeedback - actualSet) / ramp;//单位是°C/min
- UpRate = Math.Abs(TempFeedback - actualSet) / ramp;//单位是°C/min
- }
- else
- {
- DownRate = ramp;//单位是°C/min
- UpRate = ramp;//单位是°C/min
- }
- }
- DeviceData.SetPoint = temperature;
- DeviceData.RampSetPoint = _rampTime;
- if (_tempSetpoint != temperature)
- {
- SC.SetItemValueFromString($"PM1.Heater.{this.Name}.SetLastPoint", temperature.ToString("F1"));
- }
- _tempSetpoint = temperature;
- TempSetPoint = actualSet;
- //LOG.Write($"{Name} setpoint={temperature} control mode={controlMode}, PID={PID}, correct={correct}");
- _writeLog = $"{Name} setpoint={temperature} control mode={controlMode}, PID={PID}, correct={correct}";
- //Ramp(actualSet, (int)_rampTime);
- }
- return;
- }
- private bool SetRemoteMode(out string reason, int time, params object[] param)
- {
- reason = string.Empty;
- if (param == null || param.Length == 0)
- {
- reason = $"invalid parameter";
- return false;
- }
- bool.TryParse(param[0].ToString(), out bool isRemoteMode);
- //_doRemoteControl.SetValue(isRemoteMode, out _);
- return true;
- }
- private bool SetOnOff(out string reason, int time, params object[] param)
- {
- reason = string.Empty;
- if (param == null || param.Length == 0)
- {
- reason = $"invalid parameter";
- return false;
- }
- bool.TryParse(param[0].ToString(), out bool isOn);
- //if (!_doStartHeating.Check(isOn, out reason))
- //{
- // return false;
- //}
- //return _doStartHeating.SetValue(isOn, out reason);
- return true;
- }
- public void SetRun(bool isOn)
- {
- //_doStartHeating.SetValue(isOn, out _);
- EV.PostInfoLog(Name, $"{Name}.SetRun({isOn})");
- }
- public void SetRemote(bool isRemote)
- {
- //_doRemoteControl.SetValue(isRemote, out _);
- }
- private bool SetAutoTuning(out string reason, int time, params object[] param)
- {
- reason = string.Empty;
- if (param == null || param.Length == 0)
- {
- reason = $"invalid parameter";
- return false;
- }
- bool.TryParse(param[0].ToString(), out bool isAutoSetAutoTuning);
- if (isAutoSetAutoTuning)
- {
- //_doCanWritePara.SetPulseValue(true, 2000);
- //_doStopAutoTunningMode.SetValue(false, out _);
- //_doStartAutoTunningMode.SetPulseValue(true, 2000);
- }
- else
- {
- //_doCanWritePara.SetPulseValue(true, 2000);
- //_doStartAutoTunningMode.SetValue(false, out _);
- //_doStopAutoTunningMode.SetPulseValue(true, 2000);
- }
- return true;
- }
- public override void Terminate()
- {
- ProfileFinish();
- base.Terminate();
- }
- public void ProfileFinish()
- {
- _profileTimer.Stop();
- _profileStableTimer.Stop();
- _profileTotalTimeoutTrig.RST = true;
- _profileAlarmLimitTrig.RST = true;
- _profileSuccessTrig.RST = true;
- IsProfileSuccess = false;
- DeviceData.ProfileTable = "";
- DeviceData.ProfileTotalTime = 0;
- DeviceData.ProfilePreheatTime = 0;
- DeviceData.ProfileCheckTime = 0;
- DeviceData.ProfileAlarmLimit = 0;
- DeviceData.ProfileCheckLimit = 0;
- }
- public bool SetEnable(bool isEnable)
- {
- return _doEnableIn.SetValue(isEnable, out _);
- }
-
- public bool ResetWarningChecker()
- {
- _toleranceCheckerWarning.Reset(_warningJudgmentTime);
- return true;
- }
- public bool ResetAlarmChecker()
- {
- _toleranceCheckerAlarm.Reset(_alarmJudgmentTime);
- return true;
- }
- public override void Reset()
- {
- AlarmToleranceWarning?.Reset();
- AlarmToleranceAlarm?.Reset();
- _toleranceJudgmentDelayTimer?.Stop();
- }
- public void ResetHeaterError()
- {
- _trigHeaterErrorSignalOn.RST = true;
- if (HeaterErrorAlarm != null)
- HeaterErrorAlarm.IsAcknowledged = true;
- }
- public void ResetHeaterStripBreak()
- {
- TrigHeaterStripBreakSignalOn.RST = true;
- if (HeaterStripBreakAlarm != null)
- HeaterStripBreakAlarm.IsAcknowledged = true;
- }
- private void MonitorTolerance()
- {
- if (IsHeaterStripBreak || TempSetPoint < 0.001 || _toleranceJudgmentDelayTimer.IsIdle() || _toleranceJudgmentDelayTimer.GetElapseTime() < _toleranceJudgmentDelayTime * 1000)
- {
- _toleranceCheckerWarning.RST = true;
- _toleranceCheckerAlarm.RST = true;
- return;
- }
- if (_alarmJudgmentRange != 0 && _alarmJudgmentTime > 0)
- {
- _toleranceCheckerAlarm.Monitor(DeviceData.FeedBack, DeviceData.RampSetPoint - Math.Abs(_alarmJudgmentRange), DeviceData.RampSetPoint + Math.Abs(_alarmJudgmentRange), _alarmJudgmentTime);
- }
- if (_warningJudgmentRange != 0 && _warningJudgmentTime > 0)
- {
- _toleranceCheckerWarning.Monitor(DeviceData.FeedBack, DeviceData.RampSetPoint - Math.Abs(_warningJudgmentRange), DeviceData.RampSetPoint + Math.Abs(_warningJudgmentRange), _warningJudgmentTime);
- }
- }
- public override bool CheckToleranceAlarm()
- {
- return _toleranceCheckerAlarm.Result;
- }
- public override bool CheckToleranceWarning()
- {
- return _toleranceCheckerWarning.Result;
- }
- public void SetToleranceAlarm()
- {
- AlarmToleranceAlarm.Description = $"{Display} temperature out of range {_alarmJudgmentRange} °C in {_alarmJudgmentTime:F0} seconds";
- AlarmToleranceAlarm.Set();
- }
- public void SetToleranceWarning()
- {
- AlarmToleranceWarning.Description = $"{Display} temperature out of range {_warningJudgmentRange} °C in {_warningJudgmentTime:F0} seconds";
- AlarmToleranceWarning.Set();
- }
- public void Ramp(double target, int time)
- {
- target = Math.Max(0, target);
- //target = Math.Min(Range, target);
- _rampInitValue = TempFeedback; //ramp 初始值取当前设定值,而非实际读取值.零漂问题
- _rampTime = time;
- _rampTarget = target;
- _rampTimer.Start(_rampTime);
- _isStartRamp = true;
- }
- private void Ramping()
- {
- //只有修改了温度,才开始ramp,避免一开机温度设定值大于0的问题。
- if (!_isStartRamp)
- return;
- if (_rampTimer.IsTimeout() || _rampTime == 0)
- {
- TempSetPoint = (float)_rampTarget;
- }
- else
- {
- TempSetPoint = (float)(_rampInitValue + (_rampTarget - _rampInitValue) * _rampTimer.GetElapseTime() / _rampTime);
- }
- }
- private void SaveRampRate(string ramping)
- {
- SC.SetItemValueFromString($"{_scRoot}.{Name}.RampRate", ramping);
- }
- public void SetCorrectParameters(string name, string recipeCorrectFileName = null, string recipeProfileFileName = null)
- {
- //"Heater;Parameter\\TempCorrection\\tempCorrect,2,Name2;Parameter\\TempPID\\tempPID,3,Name3"
- //var defaultPID = SC.GetStringValue("PM1.APCPID");
- if (string.IsNullOrEmpty(name))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file is empty");
- name = SC.GetStringValue("PM1.TempCorrection");
- }
- var array = name.Split(',');
- if (array == null || array.Length < 2)
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature correct parameter");
- name = SC.GetStringValue("PM1.TempCorrection");
- array = name.Split(',');
- }
- if (!File.Exists($"{PathManager.GetParameterDir()}\\{array[0]}.rcp"))
- {
- name = SC.GetStringValue("PM1.TempCorrection");
- var temp = name.Split(',');
- if (temp != null && array.Length > 0)
- {
- array[0] = temp[0];
- name = string.Join(",", array);
- }
- }
- if (array == null || array.Length < 2)
- {
- return;
- }
- var fileNameAndPath = array[0];
- int.TryParse(array[1], out int index);
- var para = fileNameAndPath.Split('\\').ToList().Skip(2);//"Parameter\\TempCorrection"
- if (para == null)
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file is empty");
- return;
- }
- var fileName = string.Join("\\", para.ToArray());
- if (!string.IsNullOrEmpty(recipeCorrectFileName))
- fileName = recipeCorrectFileName;
-
- CurrentCorrectFileName = fileName;
- CurrentCorrectIndex = index;
- var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempCorrection", fileName, false);
- if (string.IsNullOrEmpty(content))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"{fileNameAndPath} heater temperature correct file is empty");
- return;
- }
- var doc = new XmlDocument();
- doc.LoadXml(content);
- XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
- if (nodeSteps == null)
- nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
- if (nodeSteps == null)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature correct file {fileNameAndPath}");
- return;
- }
- Dictionary<int, CorrectTableParameter> dic = new Dictionary<int, CorrectTableParameter>();
- for(int i= 0;i < nodeSteps.Count;i++)
- {
- var step = nodeSteps[i];
- XmlElement stepNode = step as XmlElement;
- var correctTableParameter = new CorrectTableParameter();
- correctTableParameter.CorrectParameterLst = new List<CorrectParameter>();
- int tableIndex = i + 1;
- foreach (XmlAttribute att in stepNode.Attributes)
- {
- switch (att.Name.ToLower())
- {
- case "index":
- int.TryParse(att.Value, out int no);
- correctTableParameter.No = no;
- break;
- case "name":
- correctTableParameter.Name = att.Value;
- break;
- case "tableuserangemax":
- float.TryParse(att.Value, out float tableuserangemax);
- correctTableParameter.TableUseRangeMax = tableuserangemax;
- break;
- case "tableuserangemin":
- float.TryParse(att.Value, out float tableuserangemin);
- correctTableParameter.TableUseRangeMin = tableuserangemin;
- break;
- case "profileconditiontableno":
- int.TryParse(att.Value, out int profileconditiontableno);
- correctTableParameter.ProfileConditionTableNo = profileconditiontableno;
- break;
- case "pemppidtableno":
- int.TryParse(att.Value, out int pemppidtableno);
- correctTableParameter.TempPIDTableNo = pemppidtableno;
- break;
- case "profiletccalibtemp":
- float.TryParse(att.Value, out float profiletccalibtemp);
- correctTableParameter.ProfileTCCalibTemp = profiletccalibtemp;
- break;
- }
- if (att.Name.ToLower() == "correctiondata" && !dic.ContainsKey(tableIndex))
- {
- //"Index:1;Name:U;ProfileTemp:0;ProfileCorrect:0;CascadeTCCorrect:0;ProfileTCCalib:0|Index:2;Name:CU;ProfileTemp:0;ProfileCorrect:0;CascadeTCCorrect:0;ProfileTCCalib:0|Index:3;Name:C;ProfileTemp:0;ProfileCorrect:0;CascadeTCCorrect:0;ProfileTCCalib:0|Index:4;Name:CL;ProfileTemp:0;ProfileCorrect:0;CascadeTCCorrect:0;ProfileTCCalib:0|Index:5;Name:L;ProfileTemp:0;ProfileCorrect:0;CascadeTCCorrect:0;ProfileTCCalib:0"
- var correctionDataString = att.Value;
- if (string.IsNullOrEmpty(correctionDataString))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file is empty");
- return;
- }
- var correctionDatas = correctionDataString.Split('|');
- if (correctionDatas.Length < 5)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file data length is invalid");
- return;
- }
- foreach (var datas in correctionDatas)
- {
- var dataArry = datas.Split(';');
- if (dataArry.Length < 6)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file data length is invalid");
- return;
- }
- var correctParameter = new CorrectParameter();
- foreach (var item in dataArry)
- {
- var itemArry = item.Split(':');
- if (itemArry.Length < 2)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature correct file data length is invalid");
- return;
- }
- switch (itemArry[0].ToLower())
- {
- case "index":
- int.TryParse(itemArry[1], out int no);
- correctParameter.No = no;
- break;
- case "name":
- correctParameter.Name = itemArry[1];
- break;
- case "profiletemp":
- float.TryParse(itemArry[1], out float profiletemp);
- correctParameter.ProfileTemp = profiletemp;
- break;
- case "profilecorrect":
- float.TryParse(itemArry[1], out float profilecorrect);
- correctParameter.ProfileCorrect = profilecorrect;
- break;
- case "cascadetccorrect":
- float.TryParse(itemArry[1], out float cascadetccorrect);
- correctParameter.CascadeTCCorrect = cascadetccorrect;
- break;
- case "profiletccalib":
- float.TryParse(itemArry[1], out float profiletccalib);
- correctParameter.ProfileTCCalib = profiletccalib;
- break;
- }
- }
- correctTableParameter.CorrectParameterLst.Add(correctParameter);
- }
- break;
- }
- }
- dic.Add(tableIndex, correctTableParameter);
- }
- if(dic.ContainsKey(index))
- {
- var item = dic[index];
- var heaterIndex = GetHeaterIndex() - 1;//U的index是0
- if(item.CorrectParameterLst.Count > heaterIndex)
- {
- _profileTemp = item.CorrectParameterLst[heaterIndex].ProfileTemp;
- _profileCorrect = item.CorrectParameterLst[heaterIndex].ProfileCorrect;
- _profileTCCalib = item.CorrectParameterLst[heaterIndex].ProfileTCCalib;
- _cascadeTCCorrect = item.CorrectParameterLst[heaterIndex].CascadeTCCorrect;
-
- }
- else
- {
- _profileTemp = 0;
- _profileCorrect = 0;
- _profileTCCalib = 0;
- _cascadeTCCorrect = 0;
- }
- GetProfileParameters(SC.GetStringValue("PM1.TempProfile"), item.ProfileConditionTableNo, recipeProfileFileName);
- }
- else
- {
- _profileTemp = 0;
- _profileCorrect = 0;
- _profileTCCalib = 0;
- _cascadeTCCorrect = 0;
- //auto select
- }
- var temperature = DeviceData.SetPoint;
- var actualSet = temperature + _profileTCCalib;
- if(temperature > 0)
- TempSetPoint = (float)actualSet;
- DeviceData.CorrectTable = name;
- if (SC.GetStringValue("PM1.TempCorrection") != name)
- SC.SetItemValueFromString("PM1.TempCorrection", name);
- }
- public void SetPIDParameters(string name, string recipePIDFileName = null)
- {
- //"Heater;Parameter\\TempCorrection\\tempCorrect,2,Name2;Parameter\\TempPID\\tempPID,3,Name3"
- //var defaultPID = SC.GetStringValue("PM1.APCPID");
- if (string.IsNullOrEmpty(name))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file is empty");
- return;
- }
- var array = name.Split(',');
- if (array == null || array.Length < 2)
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature PID parameter");
- return;
- }
- if (!File.Exists($"{PathManager.GetParameterDir()}\\{array[0]}.rcp"))
- return;
- var fileNameAndPath = array[0];
- int.TryParse(array[1], out int index);
- var para = fileNameAndPath.Split('\\').ToList().Skip(2);//"Parameter\\TempPID"
- if (para == null)
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file is empty");
- return;
- }
- var fileName = string.Join("\\", para.ToArray());
- if (!string.IsNullOrEmpty(recipePIDFileName))
- fileName = recipePIDFileName;
- var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempPID", fileName, false);
- if (string.IsNullOrEmpty(content))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"{fileNameAndPath} heater temperature PID file is empty");
- return;
- }
- var doc = new XmlDocument();
- doc.LoadXml(content);
- XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
- if (nodeSteps == null)
- nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
- if (nodeSteps == null)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature PID file {fileNameAndPath}");
- return;
- }
- Dictionary<int, List<PIDParameter>> dic = new Dictionary<int, List<PIDParameter>>();
- for (int i = 0; i < nodeSteps.Count; i++)
- {
- var step = nodeSteps[i];
- XmlElement stepNode = step as XmlElement;
- var pidParameters = new List<PIDParameter>();
- int tableIndex = i + 1;
- foreach (XmlAttribute att in stepNode.Attributes)
- {
- if (att.Name == "PIDData" && !dic.ContainsKey(tableIndex))
- {
- //"Index:1;Name:HT.U;P:11.5;I:12;D:13|Index:2;Name:HTCU;P:21.5;I:22;D:23|Index:3;Name:HT.C;P:31.5;I:32;D:33|Index:4;Name:HTCL;P:41.5;I:42;D:43|Index:5;Name:HT.L;P:51.5;I:52;D:53|Index:6;Name:PR.U;P:0.5;I:10;D:0|Index:7;Name:PRCU;P:0.5;I:10;D:0|Index:8;Name:PR.C;P:0.5;I:10;D:0|Index:9;Name:PRCL;P:0.5;I:10;D:0|Index:10;Name:PR.L;P:0.5;I:10;D:0"
- var PIDDataString = att.Value;
- if (string.IsNullOrEmpty(PIDDataString))
- {
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file is empty");
- return;
- }
- var pidDatas = PIDDataString.Split('|');
- if (pidDatas.Length < 5)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file data length is invalid");
- return;
- }
- foreach (var datas in pidDatas)
- {
- var dataArry = datas.Split(';');
- if (dataArry.Length < 5)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file data length is invalid");
- return;
- }
- var pidParameter = new PIDParameter();
- foreach (var item in dataArry)
- {
- var itemArry = item.Split(':');
- if (itemArry.Length < 2)
- {
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature PID file data length is invalid");
- return;
- }
- switch (itemArry[0].ToLower())
- {
- case "index":
- int.TryParse(itemArry[1], out int no);
- pidParameter.No = no;
- break;
- case "name":
- pidParameter.Name = itemArry[1];
- break;
- case "p":
- float.TryParse(itemArry[1], out float p);
- pidParameter.P = p;
- break;
- case "i":
- float.TryParse(itemArry[1], out float ii);
- pidParameter.I = ii;
- break;
- case "d":
- float.TryParse(itemArry[1], out float d);
- pidParameter.D = d;
- break;
- }
- }
- pidParameters.Add(pidParameter);
- }
- break;
- }
- }
- dic.Add(tableIndex, pidParameters);
- }
- if (dic.ContainsKey(index))
- {
- var item = dic[index];
- if (_pidTableAssociate.ContainsKey(Name) && item.Count > _pidTableAssociate[Name] + 5)
- {
- HeaterPID_P = item[_pidTableAssociate[Name]].P;
- HeaterPID_I = item[_pidTableAssociate[Name]].I;
- HeaterPID_D = item[_pidTableAssociate[Name]].D;
- CascadePID_P = item[_pidTableAssociate[Name] + 5].P;
- CascadePID_I = item[_pidTableAssociate[Name] + 5].I;
- CascadePID_D = item[_pidTableAssociate[Name] + 5].D;
- }
- }
- else
- {
- //auto select
- }
- if (SC.GetStringValue("PM1.Heater.PID") != name)
- SC.SetItemValueFromString("PM1.Heater.PID", name);
- DeviceData.PIDTable = name;
- }
- public void GetProfileParameters(string fileNameAndPath, int index, string recipeProfileFileName = null)
- {
- //"Heater;Parameter\\TempCorrection\\tempCorrect,2,Name2;Parameter\\TempPID\\tempPID,3,Name3"
- if (string.IsNullOrEmpty(fileNameAndPath))
- {
- DeviceData.ProfileTable = "";
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature Profile file is empty");
- return;
- }
- if (!File.Exists($"{PathManager.GetParameterDir()}\\{fileNameAndPath}.rcp"))
- return;
- var para = fileNameAndPath.Split('\\').ToList().Skip(2);//"Parameter\\TempPID"
- if (para == null)
- {
- DeviceData.ProfileTable = "";
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"Heater temperature Profile file is empty");
- return;
- }
- var fileName = string.Join("\\", para.ToArray());
- if (!string.IsNullOrEmpty(recipeProfileFileName))
- fileName = recipeProfileFileName;
- var content = ParameterFileManager.Instance.LoadParameter("Parameter\\TempProfile", fileName, false);
- if (string.IsNullOrEmpty(content))
- {
- DeviceData.ProfileTable = "";
- //EV.PostWarningLog(ModuleName.PM1.ToString(), $"{fileNameAndPath} heater temperature Profile file is empty");
- return;
- }
- var doc = new XmlDocument();
- doc.LoadXml(content);
- XmlNodeList nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Module[@Name='']/Step");
- if (nodeSteps == null)
- nodeSteps = doc.SelectNodes($"Aitex/TableParameterData/Step");
- if (nodeSteps == null)
- {
- DeviceData.ProfileTable = "";
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"Invalid heater temperature Profile file {fileNameAndPath}");
- return;
- }
- Dictionary<int, ProfileParameter> dic = new Dictionary<int, ProfileParameter>();
- for (int i = 0; i < nodeSteps.Count; i++)
- {
- var step = nodeSteps[i];
- XmlElement stepNode = step as XmlElement;
- var profileParameter = new ProfileParameter();
- int tableIndex = i + 1;
- foreach (XmlAttribute att in stepNode.Attributes)
- {
- switch (att.Name.ToLower())
- {
- case "index":
- int.TryParse(att.Value, out int no);
- profileParameter.No = no;
- break;
- case "name":
- profileParameter.Name = att.Value;
- break;
- case "preheattime":
- float.TryParse(att.Value, out float preheattime);
- profileParameter.PreheatTime = preheattime;
- break;
- case "checktime":
- float.TryParse(att.Value, out float checktime);
- profileParameter.CheckTime = checktime;
- break;
- case "totaltime":
- int.TryParse(att.Value, out int totaltime);
- profileParameter.TotalTime = totaltime;
- break;
- case "alarmlimit":
- int.TryParse(att.Value, out int alarmlimit);
- profileParameter.AlarmLimit = alarmlimit;
- break;
- case "u":
- float.TryParse(att.Value, out float u);
- profileParameter.U = u;
- break;
- case "cu":
- float.TryParse(att.Value, out float cu);
- profileParameter.CU = cu;
- break;
- case "c":
- float.TryParse(att.Value, out float c);
- profileParameter.C = c;
- break;
- case "cl":
- float.TryParse(att.Value, out float cl);
- profileParameter.CL = cl;
- break;
- case "l":
- float.TryParse(att.Value, out float l);
- profileParameter.L = l;
- break;
- }
- }
- dic.Add(tableIndex, profileParameter);
- }
- if (dic.ContainsKey(index))
- {
- var item = dic[index];
- _preheatTime = item.PreheatTime;
- _checkTime = item.CheckTime;
- _alarmLimit = item.AlarmLimit;
- _totalTime = item.TotalTime;
- DeviceData.ProfileTable = $"{fileNameAndPath},{index},{item.Name}";
- switch (Name)
- {
- case "HeaterU":
- _checkLimit = item.U;
- break;
- case "HeaterCU":
- _checkLimit = item.CU;
- break;
- case "HeaterC":
- _checkLimit = item.C;
- break;
- case "HeaterCL":
- _checkLimit = item.CL;
- break;
- case "HeaterL":
- _checkLimit = item.L;
- break;
- }
- DeviceData.ProfileTotalTime = _totalTime;
- DeviceData.ProfilePreheatTime = _preheatTime;
- DeviceData.ProfileCheckTime = _checkTime;
- DeviceData.ProfileAlarmLimit = _alarmLimit;
- DeviceData.ProfileCheckLimit = _checkLimit;
- DeviceData.ProfileStatus = "PreHeat";
- }
- else
- {
- _checkLimit = 0;
- _preheatTime = 0;
- _checkTime = 0;
- _alarmLimit = 0;
- _totalTime = 0;
- DeviceData.ProfileTable = "";
- DeviceData.ProfileTotalTime = 0;
- DeviceData.ProfilePreheatTime = 0;
- DeviceData.ProfileCheckTime = 0;
- DeviceData.ProfileAlarmLimit = 0;
- DeviceData.ProfileCheckLimit = 0;
- }
- }
- public bool CheckProfileFinish(out string reason)
- {
- reason = "";
- if (_profileTimer != null && _profileTimer.IsRunning)
- {
- _profileTotalTimeoutTrig.CLK = _profileTimer.ElapsedMilliseconds >= _totalTime * 1000;
- if (_profileTotalTimeoutTrig.Q)
- {
- LOG.Write($"{Name} profile timeout={_totalTime}");
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"{Name} profile timeout={_totalTime}");//超过total time之后,只是报warning提示
- }
- if (_profileTimer.ElapsedMilliseconds >= _preheatTime * 1000)//preheat time之后,才开始判断
- {
- DeviceData.ProfileStatus = "Profile Check";
- if (_profileStableTimer != null)
- {
- if (!_profileStableTimer.IsRunning)
- _profileStableTimer.Restart();
- if(Math.Abs(TempFeedback - TempSetPoint) > _checkLimit)
- _profileStableTimer.Restart();
-
- _profileAlarmLimitTrig.CLK = Math.Abs(TempFeedback - TempSetPoint) > _alarmLimit && _alarmLimit > 0;
- if (_profileAlarmLimitTrig.Q)
- EV.PostWarningLog(ModuleName.PM1.ToString(), $"{Name} profile success setpoint={TempSetPoint} feedback={TempFeedback}, difference={Math.Abs(TempFeedback - TempSetPoint)} is more than alarm limit={_alarmLimit}");
- _profileSuccessTrig.CLK = _profileStableTimer.ElapsedMilliseconds > _checkTime * 1000;
- if (_profileStableTimer.ElapsedMilliseconds > _checkTime * 1000)
- {
- IsProfileSuccess = true;
- if(_profileSuccessTrig.Q)
- LOG.Write($"{Name} profile success setpoint={TempSetPoint} feedback={TempFeedback}");
- return true;
- }
- }
- }
- reason = $"{Name} profile not finish";
- return false;
- }
- else
- {
- return true;
- }
- }
- private int GetHeaterIndex()
- {
- int.TryParse(Name.Replace("Heater", ""), out int heaterIndex);//改了heater数量这边需要改
- switch (Name)
- {
- case "HeaterU":
- heaterIndex = 1;
- break;
- case "HeaterCU":
- heaterIndex = 2;
- break;
- case "HeaterC":
- heaterIndex = 3;
- break;
- case "HeaterCL":
- heaterIndex = 4;
- break;
- case "HeaterL":
- heaterIndex = 5;
- break;
- }
- return heaterIndex;
- }
- public bool CheckWaitCondition(out string reason)
- {
- reason = "";
- if (!_isWait || _waitHigh == 0 || _waitLow == 0)
- return true;
- if (_stableJudgmentTimer.IsRunning)
- {
- if (TempFeedback < _tempSetpoint - _waitLow ||
- TempFeedback > _tempSetpoint + _waitHigh)
- {
- _stableJudgmentTimer.Restart();
- }
- if (_stableJudgmentTimer.ElapsedMilliseconds >= _stableJudgmentTime * 1000)
- {
- return true;
- }
- }
- else
- {
- _stableJudgmentTimer.Restart();
- }
- reason = $"{Name} feedback={TempFeedback}, wait limit is ({_tempSetpoint - _waitLow}, {_tempSetpoint + _waitHigh})";
- return false;
- }
- struct PIDParameter
- {
- public int No { get; set; }
- public string Name { get; set; }
- public float P { get; set; }
- public float I { get; set; }
- public float D { get; set; }
- }
- struct CorrectTableParameter
- {
- public int No { get; set; }
- public string Name { get; set; }
- public float ProfileTCCalibTemp { get; set; }
- public float TableUseRangeMin { get; set; }
- public float TableUseRangeMax { get; set; }
- public int ProfileConditionTableNo { get; set; }
- public int TempPIDTableNo { get; set; }
- public List<CorrectParameter> CorrectParameterLst{ get; set; }
- }
- struct ProfileParameter
- {
- public int No { get; set; }
- public string Name { get; set; }
- public float PreheatTime { get; set; }
- public float CheckTime { get; set; }
- public float TotalTime { get; set; }
- public float AlarmLimit { get; set; }
- public float U { get; set; }
- public float CU { get; set; }
- public float C { get; set; }
- public float CL { get; set; }
- public float L { get; set; }
- }
- }
- public struct CorrectParameter
- {
- public int No { get; set; }
- public string Name { get; set; }
- public float ProfileTemp { get; set; }
- public float ProfileTCCalib { get; set; }
- public float ProfileCorrect { get; set; }
- public float CascadeTCCorrect { get; set; }
- }
- }
|