(* @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 mProdSimLtgProdTankBottomVol 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)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)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