ParamManagerScripts/backend/script_groups/TwinCat/.example/_BLENDER_PID_MAIN.EXP

1170 lines
39 KiB
Plaintext

(* @PATH := '\/TASK1_PID\/PID_Controllers' *)
(* @SYMFILEFLAGS := '59392' *)
PROGRAM _Blender_PID_Main
VAR CONSTANT
mBP_H2O : REAL := 200 ;
mBP_SYR : REAL := 200 ;
mBP_CO2 : REAL := 200 ;
END_VAR
VAR
mSlewOk : BOOL ;
mWaterFlowSlewValveSav : REAL ;
mWaterFlowSlewMFMSav : REAL ;
mWaterFlowSlewCycleCount : REAL ;
mSyrupFlowSlewMFM : REAL ;
mStopErrorsTimeOut : TON ;
mCriticalBlendingTOF : TOF ;
mCriticalBlending : BOOL ;
mFirstProdBlendErrEnTON : TON ;
mPrevRecipeName : STRING ;
mWaterFF_SlewLimit : SlewLimit ;
mCarboCO2Error : REAL ;
mSyrFact : REAL ;
mProdTotalizerLt : Integral ;
mProdSimLt : REAL ;
mTargetProdSlwd : SlewLimit ;
mTargetFillerProdSlwd : SlewLimit ;
mTargetProdSlewOut : REAL ;
mTargetRatioSlwd : SlewLimit ;
mTargetRatioSlewOut : REAL ;
mAuxONS : R_TRIG ;
mAux1ONS : R_TRIG ;
mProdBrixFlowFlt : LowPassFilter ;
mProdBrixFlowF : REAL ;
mPressCO2Flow : REAL ;
mPressCO2Total : REAL ;
mTemp : REAL ;
mPtr : POINTER TO REAL ;
mH2OKpLimit : SlewLimit ;
mH2OKp : REAL ;
mSyrKpLimit : SlewLimit ;
mSyrKp : REAL ;
mCO2DevStdFlt : LowPassFilter ;
mCO2DevStdFOut : REAL ;
mCO2DevStdInt : INT ;
mCO2KpLimit : SlewLimit ;
mCO2Kp : REAL ;
mWaterMaxFlow : REAL ;
mWaterMinFlow : REAL ;
mSyrupMaxFlow : REAL ;
mSyrupMinFlow : REAL ;
mMinRatio : REAL ;
mMaxRatio : REAL ;
mBevBrixMax : REAL ;
mBevBrixMin : REAL ;
mBevBrixDelta : REAL ;
mCalc : REAL ;
mBlendErrorRecTmr : TON ;
mCarboErrorRecTmr : TON ;
mBlendErrorSav : REAL ;
mCarboErrorSav : REAL ;
mSP_SYR_Flow : REAL;
mTargetSyrupLvlSlwd : SlewLimit;
END_VAR
(* @END_DECLARATION := '0' *)
Init_PID_Parameters;
_PID_Check;
_PID_SP_Calc;
_PID_FF_Calc ;
BlendingFault ;
NotARecipeCheck ;
gManual_PID_TempWater := gH_WaterTempValve_Man_Out_ON ;
IF gManual_PID_TempWater THEN
gManual_Value_TempWater := gH_WaterTempValve_Out_Man_Value ;
ELSE
gH_WaterTempValve_Out_Man_Value := gR_Out_TempWater_PID ;
END_IF
gManual_PID_TempProd := gH_ProdTempValve_Man_Out_ON ;
IF gManual_PID_TempProd THEN
gManual_Value_TempProd := gH_ProdTempValve_Out_Man_Value ;
ELSE
gH_ProdTempValve_Out_Man_Value := gR_Out_TempProd_PID ;
END_IF
gManual_PID_CIPTemp := gH_CIPTempValve_Man_Out_ON ;
IF gManual_PID_CIPTemp THEN
gManual_Value_CIPTemp := gH_CIPTempValve_Out_Man_Value ;
ELSE
gH_CIPTempValve_Out_Man_Value := gR_Out_CIPTemp_PID ;
END_IF
gManual_PID_SYR_Level := NOT gH_SyrupLevelValve_Auto ;
IF gManual_PID_SYR_Level THEN
gManual_Value_SYR_Level := gH_SyrupLevelValve_Manual ;
ELSE
gH_SyrupLevelValve_Manual := gR_Out_SYR_Level_PID ;
END_IF
(*IF gSyrupTankLoading THEN
gManual_PID_SYR_Level := TRUE ;
gManual_Value_SYR_Level := gSyrupTank_ValveOV_Loading ;
END_IF*)
IF NOT gH_VEP_DeaireationValve_Auto THEN
gOutDeaireationValve := gH_VEP_DeaireationValve_Manual ;
ELSE
IF gBlenderProdMode AND NOT gH_Blender_OPT_Flowtronic THEN
IF gDeairFlow_SP > 0 THEN
IF gH_EV28_Status THEN
gOutDeaireationValve := DeaireationValve(in_DeaireationFlow:= gDeairFlow_SP, in_InletPressure:= gCO2InjPressure, in_FlowCoefficient:= gH_ProcessSetup_DeaireationKVValve);
ELSE
gOutDeaireationValve := DeaireationValve(in_DeaireationFlow:= gDeairFlow_SP, in_InletPressure:= gActualRecipe_SP_Tank_Press, in_FlowCoefficient:= gH_ProcessSetup_DeaireationKVValve);
END_IF
ELSE
gOutDeaireationValve := 0.0 ;
END_IF
ELSIF gBlenderProdMode AND gH_Blender_OPT_Flowtronic THEN
gOutDeaireationValve := gIn_DeairFlow_PV * 100.0 / 500.0;
END_IF
gH_VEP_DeaireationValve_Manual := gOutDeaireationValve ;
END_IF
IF NOT gH_Blender_OPT_Simulation THEN
gPressCO2_PV := gProductTankPress ;
END_IF
IF gBlenderProdMode THEN
IF gH_Blender_OPT_Simulation THEN
IF gPID_PressCO2_Enabled THEN
IF NOT gPID_PressCO2_Release THEN
mPressCO2Flow := ValveFlow(i_DeltaP:= (gR_PressCO2_SP - gPressCO2_PV),i_ValveOp:=gR_Out_PressCO2_PID ,i_KFF:=1100.5, i_Dens:=gCO2_Density / 1000 ) ;
mPressCO2Total := mPressCO2Total + (mPressCO2Flow * gPIDPressCO2_CycleTime * 60) ;
ELSE
mPressCO2Total := mPressCO2Total - ValveFlow(i_DeltaP:= gPressCO2_PV,i_ValveOp:=9 ,i_KFF:=20, i_Dens:=gCO2_Density / 1000 );
END_IF
END_IF
IF gH_EV12_Status THEN
mPressCO2Total := mPressCO2Total - ValveFlow(i_DeltaP:= gPressCO2_PV,i_ValveOp:=2 ,i_KFF:=20, i_Dens:=gCO2_Density / 1000 );
END_IF
IF gProdTankVolume>0 AND mProdSimLt<gProdTankVolume THEN
gPressCO2_PV := mPressCO2Total / (gProdTankVolume - mProdSimLt) ;
END_IF
(* Product Totalizer in Liters *)
IF (gDeairStartUp_Done AND NOT gCarboStillProduct) OR ((gCarboStillProduct OR gH_Blender_OPT_DoubleDeair) AND gCarboWaterLine_Done) THEN
mProdTotalizerLt.i_NewValue :=(gActual_Prod_Flow - gFillerProductFlow) / 60 ;
END_IF
mProdTotalizerLt.i_IntCycle := gPID_Cycle_Time ;
mProdTotalizerLt(Out_Integral:=mProdSimLt) ;
(* Product Tank Level Variation during simulation *)
IF mProdSimLt>gProdTankBottomVol THEN
gProductTankLevel := ((mProdSimLt - gProdTankBottomVol) / (gProdTankVolume - gProdTankBottomVol)) * 100 ;
END_IF
(* Filler Product Compsumtion simulation *)
ELSE
;
END_IF (* End of IF gH_Blender_OPT_Simulation then... *)
(* Transfer the Flowrate Measure to the PID's PV Input *)
gH2O_Flow_PV := gH2O_Flow_Meas ;
gSYR_Flow_PV := gSYR_Flow_Meas ;
gCO2_Flow_PV := gCO2_Flow_Meas ;
IF gBlenderStableFlow AND (gH2O_Flow_Meas<50) THEN
gWaterFlowTooLow := TRUE ;
ELSE
gWaterFlowTooLow := FALSE ;
END_IF
(* Calculates the actual product brix from Flows *)
IF gH2O_Flow_Meas<>0 AND gSYR_Flow_Meas<>0 THEN
mProdBrixFlowF := (gSYR_Flow_Meas * gActualSyrupBrix) / (gH2O_Flow_Meas + gSYR_Flow_Meas) ;
mProdBrixFlowFlt(i_Value:=mProdBrixFlowF,i_Num:=49, i_Enable:=gBlenderBlending) ;
gFlowProdBrix := mProdBrixFlowFlt.FilterOut ;
END_IF
IF (gR_H2O_SP + gR_SYR_SP)<>0 AND gActualSyrupDens<>0 THEN
gProductDensity := (gR_H2O_SP + gR_SYR_SP) / (gR_H2O_SP + gR_SYR_SP / gActualSyrupDens) ;
END_IF
(* PID's Manual Bit *)
gManual_PID_H2O := NOT gH_WaterValve_Auto ;
gManual_PID_SYR := NOT gH_SyrupValve_Auto ;
gManual_PID_CO2 := NOT gH_CO2CarboValve_Auto ;
IF gManual_PID_H2O THEN
gManual_Value_H2O := gH_WaterValve_Manual ;
ELSE
gH_WaterValve_Manual := gR_Out_H2O_PID ;
END_IF
IF (gProdPipeRunOut_Running OR gProdTankRunOut_Running) AND gProdPipeRunOutWaterCountEn (*AND gH_Blender_OPT_FastChangeOverEnabled *)THEN
gManual_PID_H2O := TRUE ;
gManual_Value_H2O := gH2OOpenInProdPipeRunOut ;
END_IF
IF gManual_PID_SYR THEN
gManual_Value_SYR := gH_SyrupValve_Manual ;
ELSE
gH_SyrupValve_Manual := gR_Out_SYR_PID ;
END_IF
IF (gProdPipeRunOut_Running OR gProdTankRunOut_Running) AND gProdPipeRunOutWaterCountEn (*AND gH_Blender_OPT_FastChangeOverEnabled *)THEN
gManual_PID_SYR := TRUE ;
gManual_Value_SYR := gSyrupValveProdPipeRunOut ;
END_IF
IF gManual_PID_CO2 THEN
gManual_Value_CO2 := gH_CO2CarboValve_Manual ;
ELSE
gH_CO2CarboValve_Manual := gR_Out_CO2_PID ;
END_IF
gManual_PID_PressCO2 := NOT gH_CO2PressValve_Auto ;
IF gManual_PID_PressCO2 THEN
gManual_Value_PressCO2 := gH_CO2PressValve_Manual ;
ELSE
gH_CO2PressValve_Manual := gR_Out_PressCO2_PID ;
END_IF
IF gBlenderBlending THEN
IF mWaterFlowSlewCycleCount>0 AND NOT mSlewOk THEN
gWaterFlowSlewValve := gR_Out_H2O_PID / mWaterFlowSlewCycleCount ;
gWaterFlowSlewMFM := gMFM_WaterFlow / mWaterFlowSlewCycleCount ;
mSyrupFlowSlewMFM := gMFM_Syrup1Flow / mWaterFlowSlewCycleCount ;
mWaterFlowSlewCycleCount := gPID_Cycle_Time + mWaterFlowSlewCycleCount ;
IF gWaterFlowSlewMFM>mWaterFlowSlewMFMSav THEN
mSlewOk := TRUE ;
END_IF
mWaterFlowSlewMFMSav := gWaterFlowSlewMFM ;
ELSE
mWaterFlowSlewCycleCount := gPID_Cycle_Time + mWaterFlowSlewCycleCount ;
END_IF
ELSE
mWaterFlowSlewMFMSav := 0.0 ;
mWaterFlowSlewCycleCount := 0.0 ;
gWaterFlowSlewValve := 0.0 ;
gWaterFlowSlewMFM := 0.0 ;
mSyrupFlowSlewMFM := 0.0 ;
mSlewOk := FALSE ;
END_IF
IF gSYR_Flow_Meas>0 AND gActualSyrupDens<>0 THEN
gActual_Ratio := gH2O_Flow_Meas / gSYR_Flow_Meas * gActualSyrupDens ;
END_IF
IF gH2O_Flow_Meas>0 AND gCO2_Density<>0 AND gActualSyrupDens<>0 THEN
gActual_CO2_Vol := (gCO2_Flow_Meas / gCO2_Density) / (gH2O_Flow_Meas + (gSYR_Flow_Meas / gActualSyrupDens)) ;
END_IF
IF gWaterVFM_Area<>0 THEN
gWaterSpeedToStopError := gH2O_Flow_Meas / gWaterVFM_Area / 10.0 / 60.0 ; (* m/s *)
gWaterVFM_Vel := gSP_H2O / gWaterVFM_Area / 10.0 / 60.0 ; (* m/s *)
END_IF
mStopErrorsTimeOut(PT := t#10s, IN := NOT gBlenderBlending) ;
IF gWaterSpeedToStopError>gWaterVFM_MinVel AND NOT mStopErrorsTimeOut.Q THEN
gStopBlendCarboError := FALSE ;
ELSE
gStopBlendCarboError := TRUE ;
END_IF
IF gWaterVFM_Vel>gWaterVFM_MinVel THEN
gWaterSpeedToStop := FALSE ;
ELSE
gWaterSpeedToStop := TRUE ;
END_IF
IF gWaterPipe_Area<>0 THEN
gWaterPipe_Vel := gH2O_Flow_Meas / gWaterPipe_Area / 10.0 / 60.0 ; (* m/s *)
END_IF
IF gBlenderStableFlow AND (gWaterPipe_Vel<0.6) AND gH_Blender_OPT_CarboPresent THEN
gWaterSpeedTooLow := TRUE ;
ELSE
gWaterSpeedTooLow := FALSE ;
END_IF
(************************************************************************************************************************)
(* Calculates blend error *)
IF gActualSyrupDens<>0 THEN
gSyrupVolFlow_PV := gSYR_Flow_PV / gActualSyrupDens ;
END_IF
IF gWaterRecipe THEN
gBlendError := 0.0 ;
END_IF
IF gBlendErrorEn AND gActualSyrupDens<>0 THEN
IF gFirstProd_Latch AND gSugarBeverage THEN
IF gActualRecipe_Syrup_Brix<>0 THEN
mSyrFact := gMeterSyrBrix / gActualRecipe_Syrup_Brix ;
END_IF
gBlendErrorInt.i_NewValue := (gH2O_Flow_PV + ((1 - mSyrFact) * gSyrupVolFlow_PV) - gSyrupVolFlow_PV * mSyrFact * gActualSP_RatioVol) / 60 ;
gBlendErrorInt.i_IntCycle := gPID_Cycle_Time ;
gBlendErrorInt(Out_Integral:=gBlendError);
ELSE
gBlendErrorInt.i_NewValue:=(gH2O_Flow_PV - (gSYR_Flow_PV / gActualSyrupDens) * gActualSP_RatioVol) / 60 ;
gBlendErrorInt.i_IntCycle := gPID_Cycle_Time ;
gBlendErrorInt(Out_Integral:=gBlendError) ;
END_IF
ELSE
(* gBlendErrorInt(Out_Integral:=gBlendError);*) ;
END_IF
IF gCarboCO2ErrorEn THEN
gCarboCO2ErrorInt.i_NewValue:=((gActual_Prod_Flow * gActual_SP_CO2) - gCO2_Flow_Meas) / 60 ;
gCarboCO2ErrorInt.i_IntCycle := gPID_Cycle_Time ;
gCarboCO2ErrorInt(Out_Integral:=gCarboCO2Error) ;
ELSE
(* gCarboCO2ErrorInt(Out_Integral:=gCarboCO2Error);*) ;
END_IF
IF gBlenderRinseMode THEN
gManual_PID_H2O := TRUE;
gManual_Value_H2O := gH_ProcessSetup_RinseWaterValveOV;
gManual_PID_SYR := TRUE;
gManual_Value_SYR := gH_ProcessSetup_RinseSyrupValveOV;
IF gRinseDrainRunning AND NOT gH_Blender_OPT_FastChangeOverEnabled THEN
gManual_PID_PressCO2 := TRUE ;
gManual_Value_PressCO2 := gRinseDrainOpeningPressValve ;
END_IF
END_IF
gR_CIPTemp_SP := 0.0 ;
ELSE (* CIP *)
gR_CIPTemp_SP := gCIP_SPTemperature + gCIP_SP_DeltaT ;(* Increasing Real Temperature Set Point *)
gR_PressCO2_SP := 0.0 ;
gPID_PressCO2_Release := TRUE ;
gManual_PID_PressCO2 := TRUE ;
gManual_Value_PressCO2 := 0.0 ;
gManual_PID_H2O := TRUE;
IF gH_CIP_SyrTankFloodRun OR NOT gOut_WaterPumpRun THEN
gManual_Value_H2O := 0.0 ;
ELSE
gManual_Value_H2O := gH_ProcessSetup_CIPWaterValveOV;
END_IF
gManual_PID_SYR := TRUE;
IF gH_CIP_SyrTankFloodRun THEN
gManual_Value_SYR := 0.0 ;
ELSE
gManual_Value_SYR := gH_ProcessSetup_CIPSyrupValveOV;
END_IF
gManual_PID_CO2 := TRUE;
IF gP_CIP_CO2_Inj THEN
gManual_Value_CO2 := gCIP_CO2_InjectionValue;
ELSE
gManual_Value_CO2 := 0.0;
END_IF
IF gH_Blender_OPT_Simulation THEN
mPressCO2Total := 0.0 ;
mProdSimLt := 0.0 ;
gProductTankLevel := 0.0 ;
END_IF
END_IF
IF gFastChangeOverActivated THEN
mAux1ONS(CLK:=gLoadNextRecipe) ;
ELSE
gLoadNextRecipe := FALSE ;
END_IF
IF mAux1ONS.Q THEN
_Blender_PID_Main.NextRecipe ;
_Blender_PID_Main.Actual_Recipe_Load ;
gLoadNextRecipe := FALSE ;
END_IF
mAuxONS(CLK:=gH_A_Recipe_Transfer) ;
IF mAuxONS.Q THEN
Actual_Recipe_Load ;
END_IF
gH_A_Recipe_Transfer := FALSE;
gCIPTemp_PV := gCIPHeaterTemp_PV ;
gTempWater_PV := gWaterTemperature ;
gTempProd_PV := gProductTemperature ;
gSYR_Level_PV := gSyrupTankLevel ;
(* Call PID Blocks *)
Blender_PID_Ctrl_Loop();
FlowMeter_Error() ;
TestFlowmeters();
END_PROGRAM
ACTION _PID_Check:
gSystem_Task_Info := SystemTaskInfoArr;
gSystem_Info := systeminfo;
gPID_Cycle_Time := UDINT_TO_REAL (gSystem_Task_Info [2].cycleTime) / 10000;
gPID_Cycle_Time := gPID_Cycle_Time / 1000;
IF gPID_Cycle_Time = 0 THEN
gTask_Cycle_Alarm := TRUE;
ELSE
gTask_Cycle_Alarm := FALSE;
END_IF
END_ACTION
ACTION _PID_FF_Calc:
gWaterFrictionLoss := FrictionLoss(i_Flow:=gSP_H2O, i_K:= gH_ProcessSetup_KWaterLoss, i_Dens:=gH2O_Density) ;
IF gWaterFrictionLoss>gH_ProcessSetup_WaterPumpPressure THEN
gWaterFrictionLoss := gH_ProcessSetup_WaterPumpPressure ;
ELSIF gWaterFrictionLoss<0 THEN
gWaterFrictionLoss := 0.0 ;
END_IF
gSyrupFrictionLoss := FrictionLoss(i_Flow:=gSP_SYR, i_K:= gH_ProcessSetup_KSyrupLoss, i_Dens:=gActualSyrupDens) ;
IF gSyrupFrictionLoss>gH_ProcessSetup_SyrupPumpPressure THEN
gSyrupFrictionLoss := gH_ProcessSetup_SyrupPumpPressure ;
ELSIF gSyrupFrictionLoss<0 THEN
gSyrupFrictionLoss := 0.0 ;
END_IF
IF gBlenderBlending THEN
IF gPID_H2O_Enabled THEN
IF gEqPressSelected THEN
gWaterValveDeltaP := gH_ProcessSetup_WaterPumpPressure - gWaterFrictionLoss - gPressCO2_PV ;
ELSE
gWaterValveDeltaP := gH_ProcessSetup_WaterPumpPressure - gWaterFrictionLoss - gActualRecipe_SP_Tank_Press ;
END_IF
IF gBlenderStableFlow THEN
(* 100% / 12.5 sec = 8 %/sec slew limit to Water PID Feed Forward *)
mWaterFF_SlewLimit(i_InValue:=FeedForward(i_Flow:=gSP_H2O ,i_KFF:=gH_ProcessSetup_FFWaterPID, i_Delta_P:=gWaterValveDeltaP), i_SlewMax:= 8, i_Cycle := gPID_Cycle_Time,out := gR_FF_to_H2O_PID) ;
ELSE
gR_FF_to_H2O_PID := FeedForward(i_Flow:=gSP_H2O ,i_KFF:=gH_ProcessSetup_FFWaterPID, i_Delta_P:=gWaterValveDeltaP) ;
END_IF
gH_WaterValveFFOut := gR_FF_to_H2O_PID ;
IF NOT gModValveRiseTimeCalcEn THEN
gModValveRiseTimeCalcEn:= TRUE ;
gH2OValveRiseUpTime := REAL_TO_INT(gR_FF_to_H2O_PID / 18) ;
END_IF
END_IF
ELSE
gR_FF_to_H2O_PID := 0.0 ;
gModValveRiseTimeCalcEn := FALSE ;
END_IF
IF gBlenderBlending THEN
IF gPID_SYR_Enabled THEN
IF gFirstProd_Latch THEN
gSyrupValveDeltaP := gH_ProcessSetup_SyrupPumpPressure - gSyrupFrictionLoss - gPressCO2_PV ;
ELSE
gSyrupValveDeltaP := gH_ProcessSetup_SyrupPumpPressure - gSyrupFrictionLoss - gActualRecipe_SP_Tank_Press ;
END_IF
gR_FF_to_SYR_PID := FeedForward(i_Flow:=gSP_SYR ,i_KFF:=gH_ProcessSetup_FFSyrupPID ,i_Delta_P:= gSyrupValveDeltaP) ;
gH_SyrupValveFFOut := gR_FF_to_SYR_PID ;
END_IF
ELSE
gR_FF_to_SYR_PID := 0.0 ;
END_IF
IF gBlenderBlending OR gP_CarboPipe_En THEN
IF gPID_CarboCO2_Enabled THEN
gCarboCO2ValveDeltaP := gH_ProcessSetup_CarboCO2Pressure - gH_ProcessSetup_WaterPumpPressure ;
(* gCarboCO2ValveDeltaP := gCO2InjPressure - gH_ProcessSetup_WaterPumpPressure ; *)
(* IF gBlenderStableFlow THEN*)
gR_FF_to_CO2_PID := FeedForward(i_Flow:=gSP_CO2 ,i_KFF:=gH_ProcessSetup_FFCarboCO2PID ,i_Delta_P:=gCarboCO2ValveDeltaP ) ;
(* ELSE
gR_FF_to_CO2_PID := FeedForward(i_Flow:=(gActual_SP_CO2 * gActual_Prod_SP) ,i_KFF:=gH_ProcessSetup_FFCarboCO2PID ,i_Delta_P:=gCarboCO2ValveDeltaP ) ;
END_IF*)
IF gR_FF_to_CO2_PID<0 THEN
gR_FF_to_CO2_PID := 0;
END_IF
gH_carboCO2ValveFFOut := gR_FF_to_CO2_PID ;
END_IF
ELSE
gR_FF_to_CO2_PID := 0.0 ;
END_IF
IF gBlenderBlending THEN
mSP_SYR_Flow := gSP_SYR ;
ELSIF gSyrLineMFMPrep_Latch OR gSyrMFMStartUp_Latch THEN
mSP_SYR_Flow := gSyrupTank_FirstProductionRate ;
ELSE
mSP_SYR_Flow := 0.0 ;
END_IF
IF gBlenderBlending OR gSyrLineMFMPrep_Latch OR gSyrMFMStartUp_Latch THEN
IF gPID_SYRLevel_Enabled THEN
gR_FF_to_SYR_Level_PID := FeedForward(i_Flow:=mSP_SYR_Flow ,i_KFF:=gH_ProcessSetup_FFSyrupLevelPID ,i_Delta_P:= gH_ProcessSetup_SyrupLinePressure) ;
gH_SyrupLevelValveFFOut := gR_FF_to_SYR_Level_PID ;
END_IF
ELSE
gR_FF_to_SYR_Level_PID := 0.0 ;
END_IF
IF gGencoldChillerEn AND gCoolerEnabled THEN
gR_FF_TempWater_PID := 100 - CVQ_1p7_8_Perc(gR_TempWater_SP) ;
gR_FF_TempProd_PID := 100 - CVQ_1p7_8_Perc(gR_TempProd_SP) ;
ELSE
gR_FF_TempWater_PID := 0 ;
gR_FF_TempProd_PID := 0 ;
END_IF
END_ACTION
ACTION _PID_Reset_Integral:
gI_ITLVAL_H2O := 0.0 ;
gH2OPIDIntValue := 0.0 ;
gI_ITL_PID_H2O := TRUE ;
gI_ITLVAL_SYR := 0.0 ;
gSyrupPIDIntValue := 0.0 ;
gI_ITL_PID_SYR := TRUE ;
gI_ITLVAL_CO2 := 0.0 ;
gCarboCO2PIDIntValue := 0.0;
gI_ITL_PID_CO2 := TRUE ;
gI_ITLVAL_PressCO2 := 0.0 ;
gI_ITL_PID_PressCO2 := TRUE ;
gI_ITLVAL_SYR_Level := 0.0 ;
gI_ITL_PID_SYR_Level := TRUE ;
gI_ITL_PID_TempProd := TRUE ;
gI_ITLVAL_TempProd := 0.0 ;
gI_ITL_PID_TempWater := TRUE ;
gI_ITLVAL_TempWater := 0.0 ;
END_ACTION
ACTION _PID_SP_Calc:
gActualRecipe_SP_MaxDeltaBrix := gH_Blender_OPT_MaxSyrDeltaBrix ;
IF gH_Blender_OPT_BrixMeter AND gH_A_Recipe_ProdMeterHighBrix>gActualRecipe_Beverage_Brix AND gAlwaysOff THEN
mBevBrixDelta := (gH_A_Recipe_ProdMeterHighBrix - gActualRecipe_Beverage_Brix) / 2.0 ;
ELSE
(* mBevBrixDelta := 0.1 ; Pepsico Vitoria Plant - New Eurostar 2000 140 Valves *)
mBevBrixDelta := 0.06 ; (* Coca Cola Begano Plant - New Starcans 2000 91 Valves *)
END_IF
IF gSugarBeverage AND gActualSyrupBrix<>0 THEN
IF gFirstProd_Latch THEN
gActualSyrupPerc := (gActualRecipe_Beverage_Brix + gActualRecipe_Bev_Brix_Offset + gFirstProdExtraBrix) / gActualSyrupBrix ;
ELSE
gActualSyrupPerc := (gActualRecipe_Beverage_Brix + gActualRecipe_Bev_Brix_Offset + gBrixTrackingCorr) / gActualSyrupBrix ;
END_IF
ELSE
IF gFirstProd_Latch THEN
gActualSyrupPerc := 1 / (gH_A_Recipe_Ratio + 1 ) + gFirstProdDietExtraSyr ; (* During First Production: syrup injection 1.2% more *)
ELSE
gActualSyrupPerc := 1 / (gH_A_Recipe_Ratio + 1 ) ;
END_IF
END_IF
IF gWaterRecipe THEN
gActualWaterPerc := 1.0 ;
gActualSyrupPerc := 0.0 ;
ELSE
gActualWaterPerc := 1 - gActualSyrupPerc ;
END_IF
IF gActualSyrupPerc<> 0 THEN
IF gActualSyrupDens>0.99 AND NOT gSugarBeverage THEN
gActual_RatioM := gActualWaterPerc / (gActualSyrupPerc * gActualSyrupDens) ;
ELSE
gActual_RatioM := gActualWaterPerc / gActualSyrupPerc ;
END_IF
END_IF
IF gH2O_Density<>0 THEN
gActualSP_RatioVol := gActual_RatioM * gActualSyrupDens / gH2O_Density ;
END_IF
IF gActualSP_RatioVol=0 THEN
gActualSP_RatioVol := 0.01 ;
END_IF
IF gModValveFullStrokeTime<>0 THEN
gBlenderProdSlewMax := gBlenderNomSpeed / gModValveFullStrokeTime ;
mPtr := ADR(gProductionSlewRate) ;
IF gProductionSlewRate>gBlenderProdSlewMax THEN
mPtr^ := gBlenderProdSlewMax ;
END_IF
END_IF
(* Limit the minimum and maximum recipe Production Rate *)
IF gActual_Prod_SP > gBlenderNomSpeed THEN
gActual_Prod_SP := gBlenderNomSpeed ;
END_IF
IF gActual_Prod_SP < gH_ProcessSetup_MinProduction AND NOT gBlenderRun_Wait THEN
gActual_Prod_SP := gH_ProcessSetup_MinProduction ;
END_IF
IF gBlenderProdMode THEN
(* Calculates the CO2 Equilibrium Pressure plus 0.5 Atm, to Pressurize Product Tank *)
IF gCarboStillRecipe OR gH_Blender_OPT_DoubleDeair THEN
gCO2EqPressure := LIMIT (0, CO2EqPress(i_CO2Vol := gActualRecipe_SP_Vol_CO2 * gFirstProdExtraCO2Fact * gActualRecipe_Vol_CO2_Fact , i_Temp:=gActualRecipe_SP_Prod_Temp ), gActualRecipe_SP_Tank_Press) + 0.3 ;
ELSE
gCO2EqPressure := gActualRecipe_SP_Tank_Press ;
END_IF
(* Transfer the Set Point to the PID's SP Input *)
IF gBlenderRinseMode OR (gProdTankDrain_Latch AND (gSyrRunOut_Done OR NOT gFirstProdLatched)) THEN
gR_PressCO2_SP := gH_ProcessSetup_RinseProdTankPress ;
ELSIF NOT gWaitLevelToHold_TankPress AND (NOT gFirstProd_Done OR (gFirstProd_Done AND NOT (gProdTankRunOut_Latch OR gProdTankRunOut_Done OR gProdPipeRunOut_Done))) THEN
gR_PressCO2_SP := gCO2EqPressure ;
ELSE
gR_PressCO2_SP := gActualRecipe_SP_Tank_Press ;
END_IF
IF gFirstProd_Latch AND NOT gBlenderRun_Wait THEN (* During First Production set minimum speed *)
gActual_Prod_SP := gH_ProcessSetup_MinProduction * gFirstProdSpeedGain ;
END_IF
IF gBlenderStartPumps AND NOT gBlenderBlending AND gEnRampDownToStop THEN (* Start blending with minimum speed *)
gActual_Prod_SP := gH_ProcessSetup_MinProduction ;
ELSIF NOT gEnRampDownToStop THEN
gActual_Prod_SP := gSP_ProdTrackFiller ;
ELSE
IF NOT gFirstProd_Latch AND gBlenderEnToRamp THEN
mTargetFillerProdSlwd(i_InValue:=gSP_ProdTrackFiller, i_SlewMax:=gFillerSpeedTrackSlew, i_Cycle:=gPID_Cycle_Time, out:=gActual_Prod_SP) ;
END_IF
IF gBlenderRun_Wait THEN
(* Stop Blender with the Maximum Slope *)
mTargetProdSlwd(i_InValue:=0.0, i_SlewMax:=gBlenderProdSlewMax ,i_Cycle:=gPID_Cycle_Time, out:=gActual_Prod_SP ) ; (* Slewed at "gBlenderProdSlewMax" L/sec *)
END_IF
END_IF
ELSE
gActual_Prod_SP := 0.0 ;
END_IF
mTargetRatioSlwd(i_InValue:=gActualSP_RatioVol,i_SlewMax:=0.02,i_Cycle:=gPID_Cycle_Time, out:=mTargetRatioSlewOut ) ; (* Slewed at 0.02 *)
IF gBlenderRun_Running AND NOT gBlenderRinseMode THEN
IF NOT gWaterRecipe AND (gActualSP_RatioVol + 1.0)<>0 THEN
gSP_H2O := gActual_Prod_SP / (gActualSP_RatioVol + 1.0) * gActualSP_RatioVol ;
ELSE
gSP_H2O := gActual_Prod_SP ;
END_IF
ELSE
gSP_H2O := 0.0 ;
END_IF
IF gR_H2O_SP>0 THEN
IF ABS(gBlendError)>0.5 AND ABS((gR_H2O_SP-gH2O_Flow_PV) / gR_H2O_SP)>0.2 AND (gActual_Prod_SP>(0.6*gBlenderNomSpeed)) AND gFlowToFiller THEN
mCriticalBlending := TRUE ;
ELSE
mCriticalBlending := FALSE ;
END_IF
ELSE
mCriticalBlending := FALSE ;
END_IF
mCriticalBlendingTOF(IN:=mCriticalBlending,PT:=REAL_TO_TIME(gModValveFullStrokeTime*1000)) ;
gCriticalBlending := mCriticalBlendingTOF.Q ;
IF (gBlenderEnToRamp AND (gR_Out_H2O_PID>95)) OR gCriticalBlending OR (gBlenderStopping AND gBlenderBlending) THEN
gTrackH2OEnable := TRUE ;
ELSE
gTrackH2OEnable := FALSE ;
END_IF
IF gBlenderRun_Running AND NOT gWaterRecipe AND NOT gBlenderRinseMode THEN
IF gBlenderStableFlow THEN
IF gTrackH2OEnable AND gBlenderEnToRamp THEN
gSP_SYR := ((gH2O_Flow_Meas / gActualSP_RatioVol) + ( gBlendError * gK_RecBlendError )) * gActualSyrupDens ;
ELSE
gSP_SYR := ((gActual_Prod_SP / (gActualSP_RatioVol + 1.0)) + ( gBlendError * gK_RecBlendError )) * gActualSyrupDens ;
END_IF
ELSE
IF gTrackH2OEnable THEN
(* gSP_SYR := (gH2O_Flow_Meas / gActualSP_RatioVol) * gActualSyrupDens ;*)
gSP_SYR := ((gH2O_Flow_Meas / gActualSP_RatioVol) + ( gBlendError * gK_RecBlendError )) * gActualSyrupDens ;
ELSE
gSP_SYR := ((gActual_Prod_SP / (gActualSP_RatioVol + 1.0)) + ( gBlendError * gK_RecBlendError )) * gActualSyrupDens ;
(* gSP_SYR := (gActual_Prod_SP / (gActualSP_RatioVol + 1.0)) * gActualSyrupDens ;*)
END_IF
END_IF
ELSE
gSP_SYR := 0.0 ;
END_IF
gDeairCO2Comp := DeairCO2TempComp(i_Temp:=gDeairWaterTemp, i_CO2Off:=gH_Blender_OPT_CO2_Offset) ;
gWaterO2 := PPM_O2(i_Temp:=gDeairWaterTemp);
gSyrupO2 := PPM_O2(i_Temp:=gMFM_TemperatureSyrup1) * (1 - gActualRecipe_Syrup_Brix / 100) ;
IF (gActual_RatioM + 1)<>0 THEN
gProductO2 := (gActual_RatioM * gDeairWaterO2 + gSyrupO2) / (gActual_RatioM + 1) ;
END_IF ;
gCO2Solubility := CO2_Solubility(gDeairWaterTemp) * gDeairEfficiency ;
IF gBlenderEnToRamp OR gBlenderRinseMode OR gBlenderCIPMode OR gCarboWaterLine_Latch THEN
gDeairCO2Vol := MaxCarboCO2_Vol(gDeairWaterTemp, gDeairPressure) * gDeairEfficiency ;
END_IF
gDeairCO2Comp := gDeairCO2Vol - gH_Blender_OPT_CO2_Offset ;
gFillerCO2Loss := gH_Blender_OPT_CO2_Offset ;
IF gFirstProd_Latch THEN
gActual_SP_CO2 := (gActualRecipe_SP_Vol_CO2 - gDeairCO2Comp) * gFirstProdExtraCO2Fact * gActualRecipe_Vol_CO2_Fact * (1 - gActualRecipe_Beverage_Brix / 100.0) ; (* nL/min *)
ELSE
gActual_SP_CO2 := (gActualRecipe_SP_Vol_CO2 - gDeairCO2Comp) * gActualRecipe_Vol_CO2_Fact * (1 - gActualRecipe_Beverage_Brix / 100.0) ; (* nL/min *)
END_IF
IF gBlenderBlending AND gCarboStillProduct AND gBlenderStableFlow AND NOT gBlenderRinseMode THEN
gSP_CO2 := (gActual_SP_CO2 * gActual_Prod_Flow) + (gCarboCO2Error * gK_RecCarboCO2Error) ;
ELSIF gBlenderBlending AND NOT gBlenderStableFlow AND (gCarboStillProduct OR gH_Blender_OPT_DoubleDeair) AND NOT gBlenderRinseMode THEN
gSP_CO2 := (gActual_SP_CO2 * gActual_Prod_SP) + (gCarboCO2Error * gK_RecCarboCO2Error) ;
(* gSP_CO2 := (gActual_SP_CO2 * gActual_Prod_Flow) ;*)
ELSIF gP_CarboPipe_En AND gCarboStillProduct AND NOT gBlenderRinseMode THEN
IF gActualSP_RatioVol <>0 AND NOT gWaterRecipe THEN
gSP_CO2 := gActual_SP_CO2 *(gH2O_Flow_Meas + gH2O_Flow_Meas / gActualSP_RatioVol) ;
ELSE
gSP_CO2 := (gActual_SP_CO2 * gActual_Prod_Flow) ;
END_IF
ELSE
gSP_CO2 := 0.0 ;
END_IF
gR_H2O_SP := gSP_H2O ;
gR_SYR_SP := gSP_SYR ;
gMaxCarboCO2_V := MaxCarboCO2_Vol(i_Temp:=gDeairWaterTemp , i_Press :=gH_ProcessSetup_WaterPumpPressure - 1.5 ) ;
IF gP_CarboPipe_En THEN
gR_CO2_SP := gSP_CO2 ;
ELSE
gR_CO2_SP := LIMIT(0, gSP_CO2, (gMaxCarboCO2_V * gSP_H2O)) ;
END_IF
IF gBlenderProdMode THEN
IF gBlenderRinseMode THEN
gR_SYR_Level_SP := gH_ProcessSetup_CIPSyrTankMinLevel;
ELSIF gSyrLineMFMPrep_Latch OR gSyrRunOut_Latch THEN
gR_SYR_Level_SP := gSyrupTankFirst_EndProdLvl;
ELSIF gFirstProd_Running AND gBlenderBlending THEN
mTargetSyrupLvlSlwd(i_InValue:=gSyrupTankProdLvl, i_SlewMax:=gSyrupTank_LvlSlewRate, i_Cycle:=gPID_Cycle_Time, out:=gR_SYR_Level_SP) ;
ELSIF gFirstProd_Done THEN
gR_SYR_Level_SP := gSyrupTankProdLvl;
END_IF
ELSE
IF gH_CIP_SyrTankFloodRun THEN
gR_SYR_Level_SP := 100.0 ;
ELSE
gR_SYR_Level_SP := gH_ProcessSetup_CIPSyrTankMinLevel;
END_IF
END_IF
IF gBlenderProdMode THEN
IF gProductChillerEn THEN
gR_TempWater_SP := gH_A_Recipe_SP_ProdTemp ;
gR_TempProd_SP := gH_A_Recipe_SP_ProdTemp ;
ELSIF gWaterChillerEn THEN
gR_TempWater_SP := gH_A_Recipe_SP_ProdTemp - (gCpSyrup * (gMeterSyrTemp - gH_A_Recipe_SP_ProdTemp) * gActualSyrupDens / gCpH2O) ;
END_IF
IF gH_ColdRinseRun OR gFirstProd_Latch OR gCarboWaterLine_Latch THEN
gR_TempWater_SP := gFirstProdColdRinseTempSP ;
gR_TempProd_SP := gFirstProdColdRinseTempSP ;
END_IF
ELSIF gBlenderCIPMode AND gGencoldChillerEn THEN
gR_TempWater_SP := 0.0 ;
gR_TempProd_SP := 0.0 ;
ELSE
gR_TempWater_SP := 100.0 ;
gR_TempProd_SP := 100.0 ;
END_IF
IF gBlenderProdMode AND gH_EV01_Status OR gDeairStartUp_Latch THEN
IF gBlenderRinseMode OR gCarboWaterLine_Running THEN
gDeairFlow_SP := gH2O_Flow_Meas * gH_ProcessSetup_DeaireationFactor ;
ELSE
(* gDeairFlow_SP := gR_H2O_SP * gH_ProcessSetup_DeaireationFactor ;*)
gDeairFlow_SP := gActual_Prod_SP * gH_ProcessSetup_DeaireationFactor ;
END_IF
IF gDeairTankLoading OR (NOT gDeairTankMinLvlAux AND NOT gDeairStartUp_Done) THEN
gDeairFlow_SP := gBlenderNomSpeed * gH_ProcessSetup_DeaireationFactor ;
ELSIF gDeairTankMinLvlAux AND NOT gDeairStartUp_Done THEN
gDeairFlow_SP := gH_ProcessSetup_MinProduction * gH_ProcessSetup_DeaireationFactor ;
END_IF
IF NOT gCarboStillRecipe OR NOT gH_Blender_OPT_Deaireation THEN
gDeairFlow_SP := gDeairFlow_SP / 10 ;
END_IF
ELSE
gDeairFlow_SP := 0.0;
END_IF
IF NOT gH_EV28_Status AND gH_Blender_OPT_Flowtronic THEN
gDeairFlow_SP := gIn_DeairFlow_PV ;
END_IF
END_ACTION
ACTION Actual_Recipe_Load:
IF gH_Blender_OPT_BrixMeter AND (gH_Blender_OPT_MeterType=1 OR gH_Blender_OPT_MeterType=2) AND gProductRecipeNum<>gH_A_Recipe_ProdMeterRecipeNum THEN
gProdMeterTransferRecipe := TRUE ;
END_IF
IF gH_Blender_OPT_BrixMeter AND (gH_Blender_OPT_MeterType = 4 OR gH_Blender_OPT_MeterType = 5) THEN
gProdMeterTransferRecipe := TRUE ;
END_IF
gActualRecipe_Syrup_Brix_Fact := gH_A_Recipe_SyrupFactor ;
gActualRecipe_SyrDens := gH_A_Recipe_SyrupDensity ;
gActualRecipe_SP_Prod := gH_A_Recipe_ProductionRate ;
gActualRecipe_SP_Tank_Press := gH_A_Recipe_ProdTankPress ;
gActualRecipe_SP_MinTankLevel := gH_A_Recipe_PrdTankMinLevel ;
gActualRecipe_SP_FillingValveHead := gH_A_Recipe_FillingValveHead_SP ;
gActualRecipe_SP_Prod_Temp := gH_A_Recipe_SP_ProdTemp ;
CASE gH_A_Recipe_Type OF
1: ; (* Recipe Diet Type *)
gSugarBeverage := FALSE ;
gActualSP_RatioVol := gH_A_Recipe_Ratio ;
gActualRecipe_Bev_Brix_Offset := 0.0 ;
gActualRecipe_Syrup_Brix := 0.0 ;
gActualRecipe_Syrup_Brix_Fact := 1.0 ;
gActualRecipe_Beverage_Brix := 0.0 ;
gNotARecipe_Fault := FALSE ;
2: ; (* Recipe Regular Type *)
gSugarBeverage := TRUE ;
gActualSP_RatioVol := gH_A_Recipe_Ratio ;
gActualRecipe_Bev_Brix_Offset := gH_A_Recipe_ProdBrixOffset ;
gActualRecipe_Syrup_Brix := gH_A_Recipe_SyrupBrix ;
gActualRecipe_Beverage_Brix := gH_A_Recipe_ProductBrix ;
gActualRecipe_Syrup_Brix_Fact := gH_A_Recipe_SyrupFactor ;
gNotARecipe_Fault := FALSE ;
3: ; (* Recipe Ratio Type *)
gSugarBeverage := TRUE ;
gActualSP_RatioVol := gH_A_Recipe_Ratio ;
gActualRecipe_Bev_Brix_Offset := 0.0 ;
gActualRecipe_Syrup_Brix := gH_A_Recipe_SyrupBrix ;
gActualRecipe_Beverage_Brix := gH_A_Recipe_ProductBrix ;
gActualRecipe_Syrup_Brix_Fact := gH_A_Recipe_SyrupFactor ;
gNotARecipe_Fault := FALSE ;
ELSE
gNotARecipe_Fault := TRUE ;
gSugarBeverage := FALSE ;
END_CASE
(*IF mPrevRecipeName<> gH_A_Recipe_Name AND NOT gFirstProd_Latch THEN
_Blender_Ctrl_Main.InitErrors() ;
mPrevRecipeName := gH_A_Recipe_Name ;
END_IF
*)
IF gH_Blender_OPT_CoolerPresent AND gH_Blender_OPT_CoolerControl>=1 AND gH_A_Recipe_EnProdTemp THEN
gCoolerEnabled := TRUE ;
ELSE
gCoolerEnabled := FALSE ;
END_IF
IF gH_Blender_OPT_CarboPresent THEN
gActualRecipe_SP_Vol_CO2 := gH_A_Recipe_CO2Vols ;
ELSE
gActualRecipe_SP_Vol_CO2 := 0.0 ;
END_IF
gActualRecipe_Vol_CO2_Fact := gH_A_Recipe_CO2Fact ;
IF gH_Blender_OPT_CO2_N2_Injection AND gH_Blender_OPT_VacuumPump THEN
IF gH_A_Recipe_CO2 AND gActualRecipe_SP_Vol_CO2>0.1THEN
gCarboStillRecipe := TRUE;
END_IF
IF NOT gH_A_Recipe_CO2 AND gActualRecipe_SP_Vol_CO2>0.1THEN
gCarboStillRecipe := FALSE;
END_IF
IF NOT gH_A_Recipe_CO2 AND gActualRecipe_SP_Vol_CO2<0.1THEN
gCarboStillRecipe := FALSE;
END_IF
ELSE
IF mPrevRecipeName<> gH_A_Recipe_Name THEN
IF gActualRecipe_SP_Vol_CO2>0.1 AND gActualRecipe_Vol_CO2_Fact > 0.1 AND NOT gH_Blender_OPT_DoubleDeair THEN
gCarboStillRecipe := TRUE; (*gH_A_Recipe_GasStill ;*)
ELSE
gCarboStillRecipe := FALSE;
END_IF
END_IF
END_IF
IF gActualRecipe_SP_Vol_CO2<0.1THEN
gH_A_Recipe_CO2 := FALSE;
END_IF
IF gH_Blender_OPT_CO2_N2_Injection AND NOT gH_A_Recipe_CO2 THEN
IF gH_A_Recipe_CO2Vols>0.1 AND NOT gH_Blender_OPT_DoubleDeair THEN
gCarboStillProduct := TRUE ;
ELSE
gCarboStillProduct := FALSE ;
END_IF
ELSE
IF gActualRecipe_SP_Vol_CO2>0.1 AND gActualRecipe_Vol_CO2_Fact > 0.1 AND NOT gH_Blender_OPT_DoubleDeair THEN
gCarboStillProduct := TRUE; (*gH_A_Recipe_GasStill ;*)
ELSE
gCarboStillProduct := FALSE;
END_IF
END_IF
IF NOT gH_Blender_OPT_CO2_N2_Injection THEN
IF gActualRecipe_SP_Vol_CO2>0.1THEN
gH_A_Recipe_CO2 := TRUE;
END_IF
END_IF
IF gActualSP_RatioVol>19 THEN
gWaterRecipe := TRUE ;
gSugarBeverage := FALSE ;
ELSE
gWaterRecipe := FALSE ;
END_IF
IF (gH_Blender_OPT_ByPassDeair AND NOT gH_A_Recipe_EnDeaireation) OR (gH_Blender_OPT_StillWaterByPass AND gWaterRecipe AND NOT gCarboStillRecipe) THEN
gSkipDeaireation := TRUE ;
ELSE
gSkipDeaireation := FALSE ;
END_IF
mPrevRecipeName := gH_A_Recipe_Name;
END_ACTION
ACTION BlendingFault:
IF gFirstProd_Latch AND gBlenderEnToRamp THEN
mFirstProdBlendErrEnTON(PT := t#20s, IN := TRUE) ;
ELSE
mFirstProdBlendErrEnTON(IN := FALSE) ;
END_IF
IF (ABS(gBlendError)>gH_MaxBlendError AND gBlenderBlending) AND (mFirstProdBlendErrEnTON.Q OR gFirstProd_Done) THEN
IF gBlendError>0 THEN
gBlendErrorLowSyr_Fault := TRUE ;
ELSE
gBlendErrorHighSyr_Fault := TRUE ;
END_IF
END_IF
IF (gBlendErrorLowSyr_Fault OR gBlendErrorHighSyr_Fault) AND DI_Reset_Btn THEN
(* IF gMaxBlendErrorAfterFault THEN*)
gBlendError := 0 ;
(* gMaxBlendErrorAfterFault := FALSE ;*)
(* ELSE
mBlendErrorSav := gBlendError ;
gMaxBlendErrorAfterFault := TRUE ;
END_IF*)
gMaxBlendErrorAfterFault := TRUE ;
gBlendErrorLowSyr_Fault := FALSE ;
gBlendErrorHighSyr_Fault := FALSE ;
END_IF
mBlendErrorRecTmr(IN:=gMaxBlendErrorAfterFault AND gBlenderStableFlow ,PT:=t#10s ) ;
IF mBlendErrorRecTmr.Q THEN
(* IF ABS(gBlendError)<abs(mBlendErrorSav) THEN*)
IF ABS(gBlendError)<gH_MaxBlendError THEN
mBlendErrorRecTmr.IN := FALSE ;
gMaxBlendErrorAfterFault := FALSE ;
mBlendErrorSav := 0 ;
(* ELSIF gBlendError>0 THEN
gBlendErrorLowSyr_Fault := TRUE ;
ELSIF gBlendError<0 THEN
gBlendErrorHighSyr_Fault := TRUE ;*)
END_IF
END_IF
IF (ABS(gCarboCO2Error)>gH_MaxCarboCO2Error AND gBlenderBlending) AND (mFirstProdBlendErrEnTON.Q OR gFirstProd_Done) THEN
IF gCarboCO2Error>0 THEN
gCarboCO2Error_LowCO2_Fault := TRUE ;
ELSE
gCarboCO2Error_HighCO2_Fault := TRUE ;
END_IF
END_IF
IF (gCarboCO2Error_LowCO2_Fault OR gCarboCO2Error_HighCO2_Fault) AND DI_Reset_Btn THEN
(* IF gMaxCarboErrorAfterFault THEN
gMaxCarboErrorAfterFault := FALSE ;*)
gCarboCO2Error := 0 ;
(* ELSE
mCarboErrorSav := gCarboCO2Error ;
gMaxCarboErrorAfterFault := TRUE ;
END_IF*)
gMaxCarboErrorAfterFault := TRUE ;
gCarboCO2Error_LowCO2_Fault := FALSE ;
gCarboCO2Error_HighCO2_Fault := FALSE ;
END_IF
mCarboErrorRecTmr(IN:=gMaxCarboErrorAfterFault AND gBlenderStableFlow ,PT:=t#20s ) ;
IF mCarboErrorRecTmr.Q THEN
(* IF ABS(gCarboCO2Error)<ABS(mCarboErrorSav) THEN*)
IF ABS(gCarboCO2Error)<gH_MaxCarboCO2Error THEN
mCarboErrorRecTmr.IN := FALSE ;
gMaxCarboErrorAfterFault := FALSE ;
mCarboErrorSav := 0 ;
(* ELSIF gCarboCO2Error>0 THEN
gCarboCO2Error_LowCO2_Fault := TRUE ;
ELSIF gCarboCO2Error<0 THEN
gCarboCO2Error_HighCO2_Fault := TRUE ;*)
END_IF
END_IF
END_ACTION
ACTION FlowMeter_Error:
IF gSP_H2O<>0 THEN
gWaterVFMCalcError := gWaterVFMMeasError / 100 * gSP_H2O ;
END_IF
IF gSP_SYR<>0 THEN
gSyrupMFMCalcError := (gSyrupMFMMeasError / 100 + (gSyrupMFMZeroStab / (gSP_SYR * 60)) / 100) * gSP_SYR ;
END_IF
IF gSP_CO2<>0 THEN
gCO2MFMCalcError := (gCO2MFMMeasError / 100 + (gCO2MFMZeroStab / (gSP_CO2 * 60 / 1000)) / 100) * gSP_CO2 ;
END_IF
mWaterMaxFlow := gSP_H2O + gWaterVFMCalcError ;
mWaterMinFlow := gSP_H2O - gWaterVFMCalcError ;
IF gActualRecipe_SyrDens<>0 THEN
mSyrupMaxFlow := (gSP_SYR + gSyrupMFMCalcError) / gActualRecipe_SyrDens ;
mSyrupMinFlow := (gSP_SYR - gSyrupMFMCalcError) / gActualRecipe_SyrDens ;
END_IF
IF mSyrupMaxFlow<>0 THEN
mMinRatio := mWaterMinFlow / mSyrupMaxFlow ;
END_IF
IF mSyrupMinFlow<>0 THEN
mMaxRatio := mWaterMaxFlow / mSyrupMinFlow ;
END_IF
IF gActualRecipe_SyrDens<>0 THEN
mBevBrixMax := gActualRecipe_Syrup_Brix / ((mMinRatio / gActualRecipe_SyrDens) + 1) ;
mBevBrixMin := gActualRecipe_Syrup_Brix / ((mMaxRatio / gActualRecipe_SyrDens) + 1) ;
END_IF
gBlenderBlendMaxError := mBevBrixMax - mBevBrixMin ;
END_ACTION
ACTION Init_PID_Parameters:
gK_RecBlendError := gH_ProcessSetup_KRecBlendError ;
gK_RecCarboCO2Error := gH_ProcessSetup_KRecCarboCO2Error ;
gR_H2O_TI := gH_ProcessSetup_TIWaterPID ;
gR_SYR_TI := gH_ProcessSetup_TISyrupPID ;
gR_CO2_TI := gH_ProcessSetup_TICarboCO2PID ;
gR_SYR_Level_TI := gH_ProcessSetup_TISyrupLevelPID ;
gR_H2O_TD := gH_ProcessSetup_TDWaterPID ;
gR_SYR_TD := gH_ProcessSetup_TDSyrupPID ;
gR_CO2_TD := gH_ProcessSetup_TDCarboCO2PID ;
gR_SYR_Level_TD := gH_ProcessSetup_TDSyrupLevelPID ;
gR_PressCO2_KP := gH_ProcessSetup_KpCO2PressPID ;
gR_PressCO2_Deadb_W := gH_ProcessSetup_DeadBandCO2PressPID ;
gR_CIPTemp_TI := gH_ProcessSetup_TICIPTempPID ;
gR_CIPTemp_TD := gH_ProcessSetup_TDCIPTempPID ;
gR_TempWater_TI := gH_ProcessSetup_TIWaterTempPID ;
gR_TempWater_TD := gH_ProcessSetup_TDWaterTempPID ;
gR_TempProd_TI := gH_ProcessSetup_TIProdTempPID ;
gR_TempProd_TD := gH_ProcessSetup_TDProdTempPID ;
gPIDPressCO2_CycleTime := gPID_Cycle_Time ;
gPIDCarboCO2_CycleTime := gPID_Cycle_Time ;
gPIDH2O_CycleTime := gPID_Cycle_Time ;
gPIDSYR_CycleTime := gPID_Cycle_Time ;
gPIDSYR_Level_CycleTime := gPID_Cycle_Time ;
gPIDTempProd_CycleTime := gPID_Cycle_Time ;
gPIDTempWater_CycleTime := gPID_Cycle_Time ;
gPIDCIPTemp_CycleTime := gPID_Cycle_Time ;
IF gH_ProcessSetup_BPWaterPID<>0 THEN
gR_H2O_KP := 100 / gH_ProcessSetup_BPWaterPID ;
mH2OKp := gR_H2O_KP ;
mH2OKpLimit(i_InValue:=mH2OKp, i_SlewMax:=0.02 ,i_Cycle:=gPID_Cycle_Time, out:=gR_H2O_KP ) ;
ELSE
gR_H2O_KP := 0.0 ;
END_IF
IF gH_ProcessSetup_BPSyrupPID<>0 THEN
gR_SYR_KP:= 100 / gH_ProcessSetup_BPSyrupPID ;
IF gBlenderStopping THEN
mSyrKp := gR_SYR_KP * 1.4 ;
ELSE
mSyrKp := gR_SYR_KP ;
END_IF
mSyrKpLimit(i_InValue:=mSyrKp, i_SlewMax:=0.08 ,i_Cycle:=gPID_Cycle_Time, out:=gR_SYR_KP ) ;
ELSE
gR_SYR_KP:= 0.0 ;
END_IF
IF gH_ProcessSetup_BPCarboCO2PID<>0 THEN
gR_CO2_KP:= 100 / gH_ProcessSetup_BPCarboCO2PID ;
mCO2DevStdFlt(i_Value:=gCarboCO2Stat_DevStd,i_Num:=10, i_Enable:=gBlenderFlowFltEn) ;
mCO2DevStdFOut := ABS(mCO2DevStdFlt.FilterOut) ;
IF gBlenderStableFlow THEN
mCO2DevStdInt := REAL_TO_INT(mCO2DevStdFOut * 1) ;
END_IF
IF mCO2DevStdInt<1 THEN
mCO2Kp := 1 ;
ELSIF mCO2DevStdInt>10 THEN
mCO2DevStdInt := 10 ;
END_IF
IF gBlenderStopping THEN
mCO2Kp := gR_CO2_KP * 1.3 ;
ELSIF gP_CarboPipe_En THEN
(* mCO2Kp := gR_CO2_KP / 2.5 ;*)
mCO2Kp := 0.006 ;
gR_CO2_KP := mCO2Kp ;
gR_CO2_TD := 0.0 ;
(* gR_CO2_TI := 30 ;*)
ELSIF mCO2DevStdInt>5 AND NOT gBlenderStopping THEN
mCO2Kp := gR_CO2_KP / 2;
ELSE
mCO2Kp := gR_CO2_KP ;
END_IF
mCO2KpLimit(i_InValue:=mCO2Kp, i_SlewMax:=0.8 ,i_Cycle:=gPID_Cycle_Time, out:=gR_CO2_KP ) ;
ELSE
gR_CO2_KP:= 0.0 ;
END_IF
IF gH_ProcessSetup_BPSyrupLevelPID<>0 THEN
gR_SYR_Level_KP := 100 / gH_ProcessSetup_BPSyrupLevelPID ;
ELSE
gR_SYR_Level_KP := 0.0 ;
END_IF
IF gH_ProcessSetup_BPProdTempPID<>0 THEN
gR_TempProd_KP := 100 / gH_ProcessSetup_BPProdTempPID ;
ELSE
gR_TempProd_KP := 0.0 ;
END_IF
IF gH_ProcessSetup_BPWaterTempPID<>0 THEN
gR_TempWater_KP := 100 / gH_ProcessSetup_BPWaterTempPID ;
ELSE
gR_TempWater_KP := 0.0 ;
END_IF
IF gH_ProcessSetup_BPCIPTempPID<>0 THEN
gR_CIPTemp_KP := 100 / gH_ProcessSetup_BPCIPTempPID ;
ELSE
gR_CIPTemp_KP := 0.0 ;
END_IF
END_ACTION
ACTION NextRecipe:
gH_A_Recipe_Name := gH_N_Recipe_Name ;
gH_A_Recipe_SyrupBrix := gH_N_Recipe_SyrupBrix ;
gH_A_Recipe_SyrupDensity := gH_N_Recipe_SyrupDensity ;
gH_A_Recipe_SyrupFactor := gH_N_Recipe_SyrupFactor ;
gH_A_Recipe_ProductBrix := gH_N_Recipe_ProductBrix ;
gH_A_Recipe_ProdBrixOffset := gH_N_Recipe_ProdBrixOffset ;
gH_A_Recipe_ProductionRate := gH_N_Recipe_ProductionRate ;
gH_A_Recipe_Ratio := gH_N_Recipe_Ratio ;
gH_A_Recipe_CO2Vols := gH_N_Recipe_CO2Vols ;
gH_A_Recipe_CO2Fact := gH_N_Recipe_CO2Fact ;
gH_A_Recipe_CO2 := gH_N_Recipe_CO2;
gH_A_Recipe_ProdTankPress := gH_N_Recipe_ProdTankPress ;
gH_A_Recipe_SP_ProdTemp := gH_N_Recipe_SP_ProdTemp ;
gH_A_Recipe_EnProdTemp := gH_N_Recipe_EnProdTemp ;
gH_A_Recipe_PrdTankMinLevel := gH_N_Recipe_PrdTankMinLevel ;
gH_A_Recipe_Type := gH_N_Recipe_Type ;
gH_A_Recipe_WaterValveSave := gH_N_Recipe_WaterValveSave ;
gH_A_Recipe_SyrupValveSave := gH_N_Recipe_SyrupValveSave ;
gH_A_Recipe_CarboCO2ValveSave := gH_N_Recipe_CarboCO2ValveSave ;
gH_A_Recipe_ProdMeterRecipeNum := gH_N_Recipe_ProdMeterRecipeNum ;
gH_A_Recipe_ProdMeterHighBrix := gH_N_Recipe_ProdMeterHighBrix ;
gH_A_Recipe_ProdMeterLowBrix := gH_N_Recipe_ProdMeterLowBrix ;
gH_A_Recipe_ProdMeterHighCO2 := gH_N_Recipe_ProdMeterHighCO2 ;
gH_A_Recipe_ProdMeterLowCO2 := gH_N_Recipe_ProdMeterLowCO2 ;
gH_A_Recipe_ProdMeter_ZeroCO2 := gH_N_Recipe_ProdMeter_ZeroCO2 ;
gH_A_Recipe_ProdMeter_ZeroBrix := gH_N_Recipe_ProdMeter_ZeroBrix ;
gH_A_Recipe_ProdHighCond := gH_N_Recipe_ProdHighCond ;
gH_A_Recipe_ProdLowCond := gH_N_Recipe_ProdLowCond ;
gH_A_Recipe_FillerNextRecipeNum := gH_N_Recipe_FillerNextRecipeNum ;
gH_A_Recipe_FillingValveHead_SP := gH_N_Recipe_FillingValveHead_SP ;
gH_A_Recipe_EnDeaireation := gH_N_Recipe_EnDeaireation ;
gH_A_Recipe_WaterSelection := gH_N_Recipe_WaterSelection ;
gH_A_Recipe_BottleSize := gH_N_Recipe_BottleSize ;
gH_A_Recipe_BottleShape := gH_N_Recipe_BottleShape ;
gH_N_Recipe_Transfer := FALSE ;
END_ACTION
ACTION NotARecipeCheck:
IF (gH_A_Recipe_Type>=1) AND (gH_A_Recipe_Type<=3) OR NOT gBlenderProdMode THEN
gNotARecipe_Fault := FALSE ;
ELSE
gNotARecipe_Fault := TRUE ;
END_IF
END_ACTION
ACTION PressureLoss:
IF gMeterSyrDens<>0 AND ni<>0 AND d<>0 THEN
Re := 2 * (gSYR_Flow_Meas / 60) / (gP_Greek * d * ni * gMeterSyrDens) ;
END_IF
END_ACTION