*** %% Obsidean Requirements obsidian://show-plugin?id=obsidian-plantuml obsidian://show-plugin?id=obsidian-mindmap-nextgen %% ## Overview `BlenderPID_PIDSPCalc` is a function block that calculates setpoints for PID controllers in a beverage blending system. It handles calculations related to syrup and water flows, CO2 injection, tank levels, and temperature control in beverage production. ## Temporary Variables - `ValBinTmr131`: WORD variable for timer - `ValBcdTmr131`: S5TIME variable for timer ## Main Variables - `mCriticalBlending`: Critical blending state (BOOL) - Timer conversion variables: `TimerConvDINT`, `TimerConvTIME`, `TimerConvS5TIME` - Slew rate variables: `mTargetRatioSlewOut`, `mTargetProdSlwd`, `mTargetFillerProdSlwd`, etc. - `mBevBrixDelta`: Brix delta for beverage ```plantuml @startuml BlenderClassDiagram skinparam class { BackgroundColor LightCyan BorderColor Black } class BlenderPID_PIDSPCalc { +Execute() } class RecipeParameters { +ProductBrix: REAL +ProdBrixOffset: REAL +SyrupBrix: REAL +Ratio: REAL +CO2Vols: REAL +CO2Fact: REAL +GAS2Vols: REAL +SP_ProdTemp: REAL +ProdTankPress: REAL } class SystemVariables { +gActualSyrupPerc: REAL +gActualWaterPerc: REAL +gActual_RatioM: REAL +gActual_Prod_SP: REAL +gActual_Prod_Flow: REAL +gSP_H2O: REAL +gSP_SYR: REAL +gSP_CO2: REAL +gSP_GAS2: REAL +gCriticalBlending: BOOL } class PIDControllers { +RMM301: PID +RMP302: PID +RVM301: PID +RVN304: PID } class OperationModes { +gBlenderProdMode: BOOL +gBlenderRinseMode: BOOL +gBlenderCIPMode: BOOL +gBlenderStableFlow: BOOL +First_Production: BOOL } class TankSetpoints { +gSP_SYR_Level: REAL +gSP_DEAIR_Level: REAL +gSP_STORAGE_Level: REAL +gSP_H2O_Temperature: REAL +gSP_Prod_Temperature: REAL } BlenderPID_PIDSPCalc -- RecipeParameters BlenderPID_PIDSPCalc -- SystemVariables BlenderPID_PIDSPCalc -- PIDControllers BlenderPID_PIDSPCalc -- OperationModes BlenderPID_PIDSPCalc -- TankSetpoints @enduml ``` ## Main Calculations *** ```plantuml @startuml BlenderPIDCalculationFlow skinparam activity { BackgroundColor<> PaleGreen BackgroundColor<> LightBlue BackgroundColor<> LightYellow BackgroundColor<> Pink BorderColor Black } start :Initialize variables; partition "Recipe Parameters" { :Determine beverage type; if (Sugar beverage?) then (yes) :Calculate syrup percentage based on Brix; note right: gActualSyrupPerc = (ProductBrix + ProdBrixOffset) / gActualSyrupBrix else (no) :Calculate syrup percentage based on ratio; note right: gActualSyrupPerc = 1 / (Ratio + 1) endif :Calculate water percentage; note right: gActualWaterPerc = 1 - gActualSyrupPerc :Calculate mixing ratio; note right: gActualRatioM = gActualWaterPerc / gActualSyrupPerc } partition "Flow Setpoint Calculations" { if (Production mode?) then (yes) :Calculate CO2 equilibrium pressure; :Set tank pressure setpoint based on mode; :Calculate target production rate; :Apply slew rate limiting; :Calculate water flow setpoint; note right: gSP_H2O = gActual_Prod_SP / (gActualSP_RatioVol + 1.0) * gActualSP_RatioVol :Check for critical blending conditions; :Calculate syrup flow setpoint; note right: gSP_SYR = (gSyrSPRef + gSyrSPTemp) * gActualSyrupDens :Calculate CO2 setpoint; if (Second gas injection enabled?) then (yes) :Calculate second gas setpoint; else (no) :Set second gas setpoint to zero; endif else (no) :Set all flow setpoints to zero; endif } partition "Tank Level Controls" { :Calculate syrup tank level setpoint; :Calculate deaeration tank level setpoint; :Calculate storage tank level setpoint; } partition "Temperature Controls" { :Calculate water and product temperature setpoints; } stop @enduml ``` ### 1. Brix Delta Calculation For systems with Brix meter: $$mBevBrixDelta = \frac{ProdMeterHighBrix - ProductBrix}{2.0}$$ For systems without Brix meter: $$mBevBrixDelta = 0.06$$ ### 2. Syrup Percentage Calculation For sugar beverages during first production: $$gActualSyrupPerc = \frac{ProductBrix + ProdBrixOffset + gFirstProdExtraBrix}{gActualSyrupBrix}$$ For sugar beverages in normal production: $$gActualSyrupPerc = \frac{ProductBrix + ProdBrixOffset + gBrixTrackingCorr}{gActualSyrupBrix}$$ For diet beverages during first production: $$gActualSyrupPerc = \frac{1}{Ratio + 1} + gFirstProdDietExtraSyr$$ For diet beverages in normal production: $$gActualSyrupPerc = \frac{1}{Ratio + 1}$$ ### 3. Water Percentage Calculation $$gActualWaterPerc = 1 - gActualSyrupPerc$$ ### 4. Mixing Ratio Calculation For syrup with density > 0.99 and non-sugar beverage: $$gActualRatioM = \frac{gActualWaterPerc}{(gActualSyrupPerc \times gActualSyrupDens)}$$ For other cases: $$gActualRatioM = \frac{gActualWaterPerc}{gActualSyrupPerc}$$ ### 5. Volumetric Ratio Calculation $$gActualSPRatioVol = \frac{gActualRatioM \times gActualSyrupDens}{gH2ODensity}$$ ### 6. CO2 Equilibrium Pressure Calculation $$gCO2EqPressure = CO2EqPress(iCO2Vol, iTemp) + 0.3$$ Where: - $iCO2Vol = CO2Vols \times gFirstProdExtraCO2Fact \times CO2Fact$ - $iTemp = SPProdTemp$ ### 7. Water Flow Setpoint Calculation $$gSPH2O = \frac{gActualProdSP}{(gActualSPRatioVol + 1.0)} \times gActualSPRatioVol$$ ### 8. Syrup Flow Setpoint Calculation $$gSPSYR = (gSyrSPRef + gSyrSPTemp) \times gActualSyrupDens$$ Where: - $gSyrSPRef = \frac{gActualProdSP}{(gActualSPRatioVol + 1.0)}$ or $\frac{gH2OFlowMeas}{gActualSPRatioVol}$ - $gSyrSPTemp = LIMIT(-1.0 \times gSyrSPRef \times gSyrupSPRecFact, gBlendError \times gKRecBlendError, gSyrSPRef \times gSyrupSPRecFact)$ ### 9. CO2 Setpoint Calculation $$gActualSPCO2 = (CO2Vols - gDeairCO2Comp + gCO2TrackingCorr) \times CO2Fact \times (1 - \frac{ProductBrix}{100.0})$$ $$gSPCO2 = gCO2SPRef + gCO2SPTemp$$ Where: - $gCO2SPRef = gActualSPCO2 \times gActualProdFlow$ - $gCO2SPTemp = LIMIT(-1.0 \times gCO2SPRef \times gCO2SPRecFact, gCO2SPTemp2, gCO2SPRef \times gCO2SPRecFact)$ - $gCO2SPTemp2 = gCarboCO2Error \times gKRecCarboCO2Error$ ## Tank Level Control ### Syrup Tank Level The syrup tank level setpoint (`gSP_SYR_Level`) is calculated based on operation mode: - In CIP mode: `CIPTP301MinLevel` - During first production: `gTP301FirstProdLvl` with ramp to `gTP301ProdLvl` - During normal production: `gTP301ProdLvl` ### Deaeration Tank Level The deaeration tank level setpoint (`gSP_DEAIR_Level`) is calculated: - In CIP mode: `CIPTN301MinLevel` - During first production: ramp to `gTN301ProdLvl` - During normal production: `gTN301ProdLvl` ## Temperature Control Temperature is controlled based on cooling mode: For product chiller: $$gSPH2OTemperature = SPProdTemp$$ For water chiller: $$gSPH2OTemperature = SPProdTemp - \left(\frac{gCpSyrup \times (gMeterSyrTemp - SPProdTemp) \times gActualSyrupDens}{gCpH2O}\right)$$ ## Critical Blending Detection Blending is considered critical when: $$|gBlendError| > 0.5 \text{ AND } \left|\frac{RMM301.SP - RMM301.PV}{RMM301.SP}\right| > 0.2$$ And when: $$gActualProdSP > (0.6 \times gBlenderNomSpeed)$$ ## Additional Features - The block implements slew rate control for various setpoints to prevent abrupt changes - Includes CO2 compensation based on temperature - Handles different recipes (sugar, diet, water) - Controls multiple valves and pumps to maintain precise ratios ## Process Modes The function block handles multiple operating modes: 1. Production mode 2. CIP (Clean-In-Place) mode 3. Rinse mode 4. First production mode 5. Water line mode Each mode has specific setpoints and control parameters for optimal process control. ```plantuml @startuml BlenderOperationalStates skinparam state { BackgroundColor<> LightGreen BackgroundColor<> LightBlue BackgroundColor<> LightYellow BackgroundColor<> LightPink } [*] --> Idle state Idle state "Production Mode" as Production <> { state "First Production" as FirstProd state "Normal Production" as NormalProd state "Production Runout" as RunOut FirstProd --> NormalProd : First production\ncompleted NormalProd --> RunOut : End production\nrequested RunOut --> FirstProd : New recipe } state "CIP Mode" as CIP <> { state "Tank Cleaning" as TankCIP state "Line Cleaning" as LineCIP TankCIP --> LineCIP } state "Rinse Mode" as Rinse <> { state "Cold Rinse" as ColdRinse state "Hot Rinse" as HotRinse ColdRinse --> HotRinse } state "Startup Sequence" as Startup <> { state "Deaerator Startup" as DeaerStartup state "Syrup Startup" as SyrupStartup state "Blend/Fill Startup" as BlendStartup DeaerStartup --> SyrupStartup SyrupStartup --> BlendStartup } Idle --> Startup : Start system Startup --> FirstProd : Startup complete Production --> Rinse : Production complete Rinse --> CIP : Rinse complete CIP --> Idle : CIP complete Production --> CIP : Emergency CIP Rinse --> Idle : Emergency stop @enduml ``` ## Oxygen and CO2 Calculations The block calculates oxygen content in water, syrup, and product: $$gProductO2 = \frac{gActualRatioM \times gDeairWaterO2 + gSyrupO2}{gActualRatioM + 1}$$ It also calculates CO2 solubility and volume based on temperature and pressure conditions. --- ### Flowchart: *** ```mermaid flowchart TD Start([Start]) --> A A[Initialize variables] --> B B{"Has Brix
meter?"} -->|Yes| C1["Calculate mBevBrixDelta
based on measurements"] B -->|No| C2["Use default value
mBevBrixDelta = 0.06"] C1 --> D C2 --> D D{"Is sugar
beverage?"} -->|Yes| E1 D -->|No| E2 E1{"First
production?"} -->|Yes| F1["Calculate gActualSyrupPerc
with extra Brix"] E1 -->|No| F2["Calculate gActualSyrupPerc
with Brix compensation"] E2{"First
production?"} -->|Yes| F3["Calculate gActualSyrupPerc
with extra syrup"] E2 -->|No| F4["Calculate gActualSyrupPerc
based on ratio"] F1 --> G F2 --> G F3 --> G F4 --> G G{"Water
recipe?"} -->|Yes| H1["Adjust percentages
for pure water"] G -->|No| H2["Calculate gActualWaterPerc"] H1 --> I H2 --> I I["Calculate mixing ratios"] --> J["Calculate gActualSP_RatioVol"] J --> K["Calculate maximum
slew rates"] K --> L{"Production
mode?"} -->|Yes| M1["Calculate CO2
equilibrium pressure"] L -->|No| M2["Set production
setpoint to zero"] M1 --> N["Set tank
pressure setpoints"] N --> O["Calculate current
production setpoint"] O --> P["Apply slew
rate limits"] M2 --> Q P --> Q Q["Calculate water
flow setpoint"] --> R["Evaluate critical
blending condition"] R --> S["Calculate syrup
flow setpoint"] S --> T["Calculate CO2
temperature compensation"] T --> U["Calculate O2
content in product"] U --> V["Calculate CO2
injection setpoint"] V --> W{"Second gas
injection?"} -->|Yes| X1["Calculate second
gas setpoint"] W -->|No| X2["Second gas
setpoint = 0"] X1 --> Y X2 --> Y Y["Calculate tank
level setpoints"] Y --> Z["Calculate temperature
setpoints"] Z --> End([End]) ``` ### Sequence *** ```plantuml @startuml BlenderSequence skinparam sequence { LifeLineBackgroundColor LightYellow ParticipantBackgroundColor LightCyan } participant "BlenderPID_PIDSPCalc" as Calc participant "Water Flow Controller" as Water participant "Syrup Flow Controller" as Syrup participant "CO2 Controller" as CO2 participant "Tank Level Controller" as Level participant "Temperature Controller" as Temp activate Calc == Startup Phase == Calc -> Level : Set deaerator tank level setpoint activate Level Level -> Calc : Level feedback deactivate Level Calc -> Temp : Set target water temperature activate Temp Temp -> Calc : Temperature feedback deactivate Temp == First Production Phase == Calc -> Water : Set initial water flow activate Water Water -> Calc : Flow measurement deactivate Water Calc -> Syrup : Set initial syrup flow (with extra syrup) activate Syrup Syrup -> Calc : Flow measurement deactivate Syrup Calc -> CO2 : Set CO2 injection (with extra CO2) activate CO2 CO2 -> Calc : CO2 measurement deactivate CO2 == Normal Production Phase == loop While in production mode Calc -> Water : Adjust water flow setpoint activate Water Water -> Calc : Flow measurement deactivate Water Calc -> Syrup : Adjust syrup flow setpoint activate Syrup Syrup -> Calc : Flow measurement alt Critical blending detected Calc -> Syrup : Apply correction factor end deactivate Syrup Calc -> CO2 : Adjust CO2 setpoint activate CO2 CO2 -> Calc : CO2 measurement deactivate CO2 Calc -> Level : Monitor and maintain target levels activate Level Level -> Calc : Level feedback deactivate Level end == Runout Phase == Calc -> Water : Ramp down water flow Calc -> Syrup : Ramp down syrup flow Calc -> CO2 : Reduce CO2 injection Calc -> Level : Adjust tank levels for end of production deactivate Calc @enduml ``` ```markmap --- markmap: height: 860 highlight: false --- # BlenderPID_PIDSPCalc ## Initialization - Initialize variables - Set up slew rate limits - Configure timer variables ## Beverage Type Detection ### Sugar Beverage - Calculate syrup percentage based on Brix #### First Production Mode - Formula: $gActualSyrupPerc = \frac{ProductBrix + ProdBrixOffset + gFirstProdExtraBrix}{gActualSyrupBrix}$ - Add extra Brix for first production #### Normal Production Mode - Formula: $gActualSyrupPerc = \frac{ProductBrix + ProdBrixOffset + gBrixTrackingCorr}{gActualSyrupBrix}$ - Apply Brix tracking correction ### Diet Beverage - Calculate syrup percentage based on ratio #### First Production Mode - Formula: $gActualSyrupPerc = \frac{1}{Ratio + 1} + gFirstProdDietExtraSyr$ - Add extra syrup (1.2% more) #### Normal Production Mode - Formula: $gActualSyrupPerc = \frac{1}{Ratio + 1}$ ### Water Recipe - Set water percentage to 100% - Set syrup percentage to 0% ## Ratio Calculations - Water percentage: $gActualWaterPerc = 1 - gActualSyrupPerc$ - Mixing ratio: $gActualRatioM = \frac{gActualWaterPerc}{gActualSyrupPerc}$ - Volumetric ratio: $gActualSPRatioVol = \frac{gActualRatioM \times gActualSyrupDens}{gH2ODensity}$ ## Production Mode Operations ### CO2 Equilibrium Pressure Calculation - Calculate pressure based on CO2 volumes - Add safety margin (0.3 bar) - Set tank pressure setpoints ### Production Setpoint Management - Apply production speed limits - Handle first production special conditions - Apply slew rate limiting for smooth changes ### Water Flow Control - Formula: $gSPH2O = \frac{gActualProdSP}{gActualSPRatioVol + 1.0} \times gActualSPRatioVol$ - Handle water-only recipes ### Critical Blending Detection - Monitor blending error magnitude - Monitor flow deviation percentage - Enable tracking mode if critical ### Syrup Flow Control - Track water flow in critical conditions - Calculate reference setpoint - Apply blend error correction - Formula: $gSPSYR = (gSyrSPRef + gSyrSPTemp) \times gActualSyrupDens$ ## CO2 and Gas Control ### CO2 Temperature Compensation - Calculate temperature-based compensation - Account for deaeration effect ### Oxygen Content Calculation - Calculate water O2 content - Calculate syrup O2 content - Calculate product O2 content: $gProductO2 = \frac{gActualRatioM \times gDeairWaterO2 + gSyrupO2}{gActualRatioM + 1}$ ### CO2 Injection Control - Calculate CO2 volumes setpoint - Apply corrections based on flow - Formula: $gSPCO2 = gCO2SPRef + gCO2SPTemp$ - First production: $gActualSPCO2 = (CO2Vols - gDeairCO2Comp) \times gFirstProdExtraCO2Fact \times CO2Fact \times (1 - \frac{ProductBrix}{100.0})$ ### Secondary Gas Injection - Calculate second gas volumes if enabled - Formula: $gActualSPGAS2 = GAS2Vols \times GAS2Fact \times (1 - \frac{ProductBrix}{100.0})$ - Set to zero if disabled ## Tank Level Control ### Syrup Tank - Set level based on operation mode - Use slew limiting for transitions - Handle CIP mode conditions ### Deaeration Tank - Set level based on operation mode - Handle startup conditions - Control deaeration effectiveness ### Storage Tank - Set level based on target level - Apply slew rate limiting ## Temperature Control ### Product Chiller Mode - Set water and product temperature equal - Match recipe temperature setpoint ### Water Chiller Mode - Compensate for syrup temperature - Formula: $gSPH2OTemperature = SPProdTemp - \frac{gCpSyrup \times (gMeterSyrTemp - SPProdTemp) \times gActualSyrupDens}{gCpH2O}$ ### CIP Mode - Set appropriate temperature for cleaning ```