Browse Source

revise platingcell run recipe bug

chenzk 1 week ago
parent
commit
14a6f1f2cb

+ 55 - 11
PunkHPX8_RT/Modules/PlatingCell/PlatingCellDepositionRoutine.cs

@@ -2,6 +2,7 @@
 using Aitex.Core.RT.Log;
 using Aitex.Core.RT.Routine;
 using Aitex.Core.Util;
+using MECF.Framework.Common.Alarm;
 using MECF.Framework.Common.Beckhoff.Station;
 using MECF.Framework.Common.CommonData.PowerSupplier;
 using MECF.Framework.Common.RecipeCenter;
@@ -70,10 +71,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         private bool _isZeroCurrent = false;
         /// <summary>
-        /// 是否双有双向旋转
-        /// </summary>
-        private bool _isBiRotation = false;
-        /// <summary>
         /// 是否启动smart spin
         /// </summary>
         private bool _isSmartSpin = false;
@@ -115,10 +112,12 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         public RState Monitor()
         {               //没有上电保护,此刻给电
             Runner.RunIf(RunRecipeStep.RunPowerStep, _recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms)
+                //检验步阶电流是否完成
+                .WaitWithStopCondition(RunRecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus, false, _delay_1ms)
                 .LoopStart(RunRecipeStep.LoopRotationStart, "Start rotation cycle",_recipe.DepStepCount,NullFun)
                 //vertical 调整位置(第一步不用调,entry过程已经走到位置了)
                 .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSet, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0 && _depositionStepIndex!=0, () => StartVertical("Plate", _recipe.DepSteps[_depositionStepIndex].PlatingZoffset),_delay_1ms)
-                .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSetCheck, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0 && _depositionStepIndex != 0, CheckVerticalEnd, CheckVerticalError)
+                .LoopRunIfWithStopStatus(RunRecipeStep.LoopVerticalGotoOffSetCheck, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0 && _depositionStepIndex != 0, CheckVerticalEnd, CheckVerticalError)
                 
                 //不带双向旋转,时间到了直接变速(如果当前电机是停止状态,启动起来)
                 .LoopRunIf(RunRecipeStep.LoopRotationStartIfCurrentIsStoped, CheckRotationIsIdle() && !_recipe.DepSteps[_depositionStepIndex].BiDireaction,
@@ -137,9 +136,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
                         () => CommonFunction.CheckRoutineEndState(_rotationBiDirectionRoutine), 
                         () => CommonFunction.CheckRoutineStopState(_rotationBiDirectionRoutine))
                 .LoopEnd(RunRecipeStep.LoopEnd, UpdateDepositionIndex, _delay_1ms)
-                //检验步阶电流是否完成
-                .WaitWithStopCondition(RunRecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus,false,_delay_1ms)
-                
                 //如果电镀最后一步带双向旋转,后续电机会停止,需要再把电机启动起来
                 .RunIf(RunRecipeStep.RotationStartIfCurrentIsStoped, CheckRotationIsIdle(), () => { return StartRotation(ROTATION_FAR_POSITION); }, _delay_1ms)
                 .End(RunRecipeStep.End, NullFun);
@@ -275,6 +271,56 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             return _verticalEntity.IsError;
         }
         /// <summary>
+        /// 检验电流和电压合理性
+        /// </summary>
+        /// <param name="current"></param>
+        /// <param name="voltage"></param>
+        /// <param name="side"></param>
+        /// <returns></returns>
+        private bool CheckSidePowerInvalid(double current, double voltage)
+        {
+            double maxVoltage = _recipe.DepMaxVoltageFault;
+            double warnVoltage = _recipe.DepMaxVoltageWarning;
+            if (voltage > maxVoltage)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, $" voltage {voltage} is large than recipe max voltage {maxVoltage}", 0);
+                return true;
+            }
+            if (voltage > warnVoltage)
+            {
+                string str = $" voltage is {voltage} in warning";
+                if (AlarmListManager.Instance.AddWarn(Module, $"voltage", str))
+                {
+                    LOG.WriteLog(eEvent.WARN_METAL, Module, str);
+                }
+            }
+            double maxErrorCurrent = _powerSupplierStepPeriodDatas[_depositionStepIndex].Current * (double)(1 + _recipe.DepCurrentFault * 0.01);
+            double minErrorCurrent = _powerSupplierStepPeriodDatas[_depositionStepIndex].Current * (double)(1 - _recipe.DepCurrentFault * 0.01);
+            double maxWarnCurrent = _powerSupplierStepPeriodDatas[_depositionStepIndex].Current * (double)(1 + _recipe.DepCurrentWarning * 0.01);
+            double minWarnCurrent = _powerSupplierStepPeriodDatas[_depositionStepIndex].Current * (double)(1 - _recipe.DepCurrentWarning * 0.01);
+            if (current > maxErrorCurrent)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, $" current {current} is large than recipe max current {maxErrorCurrent}", 0);
+                return true;
+            }
+            if (current < minErrorCurrent)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, $" current {current} is less than recipe min current {minErrorCurrent}", 0);
+                return true;
+            }
+
+            if ((current <= maxErrorCurrent && current >= maxWarnCurrent) || (current >= minErrorCurrent && current <= minWarnCurrent))
+            {
+                string str = $" current {current} is in warning";
+                if (AlarmListManager.Instance.AddWarn(Module, $" current", str))
+                {
+                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, str);
+                }
+            }
+            return false;
+        }
+
+        /// <summary>
         /// 启动
         /// </summary>
         /// <param name="objs"></param>
@@ -283,9 +329,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         {
             _recipe = (DepRecipe)objs[0];
             _isZeroCurrent = (bool)objs[1];
-            _isBiRotation = (bool)objs[2];
-            _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[3];
-            _platingStartTime = (DateTime)objs[4];
+            _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[2];
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
             _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
             _depositionStepIndex = 0;

+ 0 - 1
PunkHPX8_RT/Modules/PlatingCell/PlatingCellEntryRoutine.cs

@@ -214,7 +214,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             _recipe = (DepRecipe)objs[0];
             _rotationgTargetPosition = (int)objs[1];
             _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[2];
-            _platingStartTime = (DateTime)objs[3];
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
             _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
             //获取vertical entity

+ 20 - 22
PunkHPX8_RT/Modules/PlatingCell/PlatingCellReclaimRoutine.cs

@@ -9,11 +9,13 @@ using MECF.Framework.Common.Utilities;
 using PunkHPX8_Core;
 using PunkHPX8_RT.Devices.AXIS;
 using PunkHPX8_RT.Devices.PlatingCell;
+using PunkHPX8_RT.Devices.PowerSupplier;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using System.Windows.Navigation;
 
 namespace PunkHPX8_RT.Modules.PlatingCell
 {
@@ -23,7 +25,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         {
             SetCurrentProtect,
             SetCurrentProtectWait,
-            PowerEnable,
             VerticalGotoReclaim,
             CheckVerticalGotoReclaim,
             PowerDisable,
@@ -71,6 +72,14 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         private double _reclaimCurrentSetPoint = 0;
         /// <summary>
+        /// 设置电流并启动routine
+        /// </summary>
+        private PowerSupplierSetCurrentRoutine _enablePowerRoutine;
+        /// <summary>
+        /// PowerSupplier
+        /// </summary>
+        protected CellPowerSupplier _powerSupplier;
+        /// <summary>
         /// 构造函数
         /// </summary>
         /// <param name="module"></param>
@@ -91,34 +100,19 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// <returns></returns>
         public RState Monitor()
         {
-            Runner.RunIf(RunRecipeStep.SetCurrentProtect, !_isZeroCurrent && _isCurrentProtectEnable , SetCurrent, _delay_1ms)
-                  .DelayIf(RunRecipeStep.SetCurrentProtectWait, !_isZeroCurrent && _isCurrentProtectEnable,500)
-                  .RunIf(RunRecipeStep.PowerEnable, !_isZeroCurrent && _isCurrentProtectEnable,EnablePower, _delay_1ms)
+            Runner.RunIf(RunRecipeStep.SetCurrentProtect, !_isZeroCurrent && _isCurrentProtectEnable, () => {return _enablePowerRoutine.Start(_reclaimCurrentSetPoint) == RState.Running; }, _delay_1ms)
+                  .WaitWithStopConditionIf(RunRecipeStep.SetCurrentProtectWait, !_isZeroCurrent && _isCurrentProtectEnable,
+                      () => CommonFunction.CheckRoutineEndState(_enablePowerRoutine), 
+                      () => CommonFunction.CheckRoutineStopState(_enablePowerRoutine))
                   .Run(RunRecipeStep.VerticalGotoReclaim, () => StartVertical("Reclaim",_recipe.ReclaimZoffset, _verticalReclaimSpeed, _verticalReclaimAcceleration), _delay_1ms)
                   .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoReclaim, CheckVerticalEnd, CheckVerticalError)
                   .RunIf(RunRecipeStep.PowerDisable, !_isZeroCurrent && _isCurrentProtectEnable, DisablePower, _delay_1ms)
-                  .Run(RunRecipeStep.PowerDisable, () => ChangeRotationSpeed(_recipe.ReclaimSpeed), _delay_1ms)
+                  .Run(RunRecipeStep.ChangeRotation, () => ChangeRotationSpeed(_recipe.ReclaimSpeed), _delay_1ms)
                   .Delay(RunRecipeStep.RotationDelay, _recipe.ReclaimTime*1000)
                   .End(RunRecipeStep.End, NullFun);
             return Runner.Status;
         }
         /// <summary>
-        /// 设置电流
-        /// </summary>
-        /// <returns></returns>
-        private bool SetCurrent()
-        {
-            return _device.PowerSupplier.SetCurrent(_reclaimCurrentSetPoint);
-        }
-        /// <summary>
-        /// 启动电源输出
-        /// </summary>
-        /// <returns></returns>
-        private bool EnablePower()
-        {
-            return _device.PowerSupplier.EnableOperation("", null);
-        }
-        /// <summary>
         /// 停止电源输出
         /// </summary>
         /// <returns></returns>
@@ -173,7 +167,11 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         {
             _recipe = (DepRecipe)objs[0];
             _isZeroCurrent = (bool)objs[1];
-            
+            _powerSupplier = (CellPowerSupplier)objs[2];
+            if (_powerSupplier != null)
+            {
+                _enablePowerRoutine = new PowerSupplierSetCurrentRoutine(_powerSupplier.DeviceID);
+            }
             _isCurrentProtectEnable = SC.GetValue<bool>("PlatingCell.PostProcessCurrentEnable");
             _verticalReclaimSpeed = SC.GetValue<int>("PlatingCell.ReclaimSpeed");
             _verticalReclaimAcceleration = SC.GetValue<int>("PlatingCell.ReclaimAcceleration");

+ 13 - 8
PunkHPX8_RT/Modules/PlatingCell/PlatingCellRunRecipeRoutine.cs

@@ -53,6 +53,10 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// ROTATION电机转速比例
         /// </summary>
         private const int SPEED_RATIO = 1;
+        /// <summary>
+        /// 电机以500rmp 运行12个小时的位置
+        /// </summary>
+        private const int LARGETARGETPOSITION = 12 * 60 * 60 * 500 * 6; 
         #endregion
 
         #region 内部变量
@@ -105,9 +109,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// <summary>
         /// run recipe 过程中电机会停的位置(需要根据recipe计算出来)
         /// </summary>
-        private List<int> _targetPositionList = new List<int>();
-
-
         #region 电镀通电相关
         /// <summary>
         /// 不通电
@@ -191,21 +192,21 @@ namespace PunkHPX8_RT.Modules.PlatingCell
                 
             Runner.LoopStart(RunRecipeStep.LoopStart, "Loop Start Cycle Run Platingcell Recipe Routine", _cycle, NullFun, _delay_1ms)
                 //interval rinse
-                .LoopRunIf(RunRecipeStep.InterRinse, _recipe.RinseBeforeEntryEnable, () => { return _interRinseRoutine.Start(_recipe, _targetPositionList[0]) == RState.Running; })
+                .LoopRunIf(RunRecipeStep.InterRinse, _recipe.RinseBeforeEntryEnable, () => { return _interRinseRoutine.Start(_recipe, LARGETARGETPOSITION) == RState.Running; })
                 .LoopRunIfWithStopStatus(RunRecipeStep.CheckInterRinse, _recipe.RinseBeforeEntryEnable, CheckInterRinseEndStatus,
                         () => CommonFunction.CheckRoutineStopState(_interRinseRoutine))
                 //entry
-                .LoopRun(RunRecipeStep.Entry,  () => { return _entryRoutine.Start(_recipe, _targetPositionList[0], _powerSupplierStepPeriodDatas,_platingStartTime) == RState.Running; })
+                .LoopRun(RunRecipeStep.Entry,  () => { return _entryRoutine.Start(_recipe, LARGETARGETPOSITION, _powerSupplierStepPeriodDatas) == RState.Running; })
                 .LoopRunWithStopStatus(RunRecipeStep.CheckEntry, CheckEntryEndStatus,
                         () => CommonFunction.CheckRoutineStopState(_entryRoutine))
 
                 //Deposition
-                .LoopRun(RunRecipeStep.Deposition, () => { return _depositionRoutine.Start(_recipe, _isZeroCurrent, _isRecipeContainsRevserseRotation,_powerSupplierStepPeriodDatas, _platingStartTime) == RState.Running; })
+                .LoopRun(RunRecipeStep.Deposition, () => { return _depositionRoutine.Start(_recipe, _isZeroCurrent,_powerSupplierStepPeriodDatas) == RState.Running; })
                 .LoopRunWithStopStatus(RunRecipeStep.CheckDeposition, CheckDepositionEndStatus,
                         () => CommonFunction.CheckRoutineStopState(_depositionRoutine))
 
                  //Reclaim
-                .LoopRun(RunRecipeStep.Reclaim, () => { return _reclaimRoutine.Start(_recipe, _isZeroCurrent) == RState.Running; })
+                .LoopRun(RunRecipeStep.Reclaim, () => { return _reclaimRoutine.Start(_recipe, _isZeroCurrent,_device.PowerSupplier) == RState.Running; })
                 .LoopRunWithStopStatus(RunRecipeStep.CheckReclaim, CheckReclaimEndStatus,
                         () => CommonFunction.CheckRoutineStopState(_reclaimRoutine))
 
@@ -368,6 +369,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
                 step.Second = (ushort)(_recipe.PlatingDelay % 60);  
                 step.Microsecond = 110; //到达entry位置提前100ms上电,提前一丢丢
                 step.Voltage = _recipe.DepMaxVoltageWarning;
+                step.Current = _recipe.EntryCurrent * 0.001; //recipe的entry current单位是毫安
                 _powerSupplierStepPeriodDatas.Add(step);
 
             }
@@ -392,6 +394,10 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             {
                 _isZeroCurrent = true;
             }
+            if(_maxCurrent < _recipe.EntryCurrent)//最大电流要考虑entry current
+            {
+                _maxCurrent = _recipe.EntryCurrent;
+            }
             if(_maxCurrent > 0.6) //设置电源挡位,有超过0.6A的电流则用高档,否则用中挡
             {
                 return _device.PowerSupplier.SetPowerGrade("set power grade high", new object[] { (byte)2 });
@@ -417,7 +423,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
                     continue;
                 }
             }
-            _targetPositionList.Add(12 * 60 * 60 * 500 * 6); //以500rmp 运行12个小时的位置
         }
         /// <summary>
         /// 检验前置条件