--- # Sistema DAR – Diet as Regular SAE452 · Mixer Sidel con CPU S7-317 ## 1. Objetivo 1. Reducir pérdidas de jarabe (syrup) durante los cambios de producto. 2. Compensar la dilución y la variabilidad de °Brix del jarabe Diet, tratándolo como Regular: * Al inicio: detectar la llegada real de jarabe y comenzar la carga del tanque TP301 sin arrastrar agua. * Al final: detectar la desaparición del jarabe y drenar sólo el volumen mínimo necesario. ## 2. Alcance de este documento Step 0 / Step 1 del proyecto DAR: lectura de instrumentos, detección de interfaces agua/jarabe y alarmas de conductividad. La autocorrección de mezcla (Step 2) y el control refinado con UR29 no se detallan aquí. ## 3. Arquitectura de instrumentación añadida | Etiqueta | Instrumento | Función principal | Interface PLC | |----------|-------------|------------------|---------------| | **UR62 – QTM306** | Refractómetro Maselli (Ø 2″) | Detección rápida de paso agua → jarabe y jarabe → agua en la línea de llegada «Syrup Line» | 4-20 mA ó TCP (seleccionable)
`HMI_Instrument.QTM306` | | **UR29 – QTM307** | Refractómetro Maselli alta precisión (stream jarabe) | Medición precisa de °Brix para futura autocorrección (Step 2) | 4-20 mA/TCP
`HMI_Instrument.QTM307` | | **CTS306** | Conductivímetro Knick 2405 | Comprobar dureza (µS/cm) del agua de proceso; generar alarmas fuera de rango | 4-20 mA
`HMI_Instrument.CTS306` | Diagrama simplificado: ``` [ Water In ]--CTS306----┐ │ (purge) +--┴--Drain | Syrup Tanks --Pump--UR62(QTM306)-----> Mixer pipe ---> UR29(QTM307) ---> TP301 ``` ## 4. Fases operativas 1. **Priming / Syrup Line Preparation** - La sala de jarabe envía agua para purga inicial. - `UR62` lee °Brix. Mientras `Brix_UR62` sea menor que el umbral `_BrixCutUR62`, la válvula AVS347/348 permanece abierta a drenaje y se descartan los litros contados en la tabla histórica según el tanque origen. - Cuando `Brix_UR62 ≥ _BrixCutUR62` (filtro TON 0,5 s) ⇒ * Se cierra drenaje, se abre ruta a TP301 y se inicia el totalizador de jarabe. 2. **Carga de TP301 (Producción)** - El control de caudal se basa en los medidores FTP302 (masa jarabe) y FTN301 (agua). - `UR29` todavía puede monitorizar, pero no interviene en Step 1. 3. **Final de producción (Run-out)** - El set point de corte es el mismo principio pero inverso: cuando `Brix_UR62` cae por debajo de `_BrixCutUR62` se considera fin de jarabe y se conmuta a agua. 4. **Alarmas de conductividad** - `CTS306.PVFiltered` se compara con los límites (`_Water_Conduct_Min` y `_Water_Conduct_Max`) configurados en la receta: * Bajo límite ⇒ `Alarm084` * Sobre límite ⇒ `Alarm085` ## 5. Algoritmo de corte °Brix Variable receta: `Recipe__XX.Actual_Recipe_Parameters._BrixCutUR62` ``` SyrBrix_Threshold = SyrBrix_Recipe * _BrixCutUR62 ``` La recomendación inicial (Step 1) es 50 % del °Brix nominal del jarabe. El valor es configurable por receta para adaptar distintas formulaciones. Condición lógica (extracto de idea): ``` IF UR62_Brix ≥ SyrBrix_Threshold THEN SyrupLoaded := TRUE // comienza carga TP301 ELSE SyrupLoaded := FALSE // continúa drenaje ``` ## 6. Implementación en el PLC ### 6.1 Lectura analógica vs digital Bloque `Maselli_ADAM_Read` ```SCL o_Brix := … // conversión 4-20 mA → °Brix o_Alarm_Present := CurrentErrorCode <> 0 ``` En `DAR_Logic` se selecciona la fuente según parámetro `READ_MASELLI_DIGITAL`: - `FALSE` ⇒ Vía IM155 (PEW) y `Maselli_ADAM_Read` - `TRUE` ⇒ Comunicación TCP (`MaselliTCP_DB_UR62`, `MaselliTCP_DB_UR29`) ### 6.2 Variables clave | Variable | Descripción | |----------|-------------| | `HMI_Instrument.QTM306.PVFiltered` | °Brix filtrado de UR62 | | `HMI_Instrument.QTM307.PVFiltered` | °Brix filtrado de UR29 | | `HMI_Instrument.CTS306.PVFiltered` | Conductividad agua | | `Recipe..._Water_Conduct_Min/Max` | Límites de alarma | | `_BrixCutUR62` | % de corte sobre °Brix jarabe | ### 6.3 Lógica de alarmas (fragmento) ```SCL IF CTS306.PVFiltered < _Water_Conduct_Min THEN Alarm084 := TRUE; IF CTS306.PVFiltered > _Water_Conduct_Max THEN Alarm085 := TRUE; ``` ### 6.4 Tabla de litros por tanque (legacy) Mientras se afina el disparo por °Brix, el programa sigue disponiendo de la matriz de volúmenes históricos para cada tanque de origen. Esta tabla se encuentra en los datos persistentes de la sala Syrup y se usa como respaldo. ## 7. Calibración y puesta en marcha 1. Parametrizar en cada receta: * °Brix jarabe (`_SyrupBrix`) * `_BrixCutUR62` (empíricamente 0,5) * Límites de conductividad agua. 2. Verificar offset ADC-DAC (`i_Offset_ADC_DAC`) en `Maselli_ADAM_Read` (≈ 0,025 mA medido). 3. Comprobar IP de los gateways digitales (líneas 22-27 de `DAR_Logic`). 4. Ejecutar pruebas de paso agua→jarabe y jarabe→agua para cada línea/tanque y ajustar `_BrixCutUR62` si aparecen falsos disparos. ## 8. Mejoras previstas (Step 2) - Uso de `UR29` para autocorrección del ratio agua/jarabe (`SyrBrix_Autocorrection.scl`). - Cierre automático según `Brix_UR29` en Storage TM301. - Sustitución completa de tabla de litros por detección 100 % basada en °Brix. ## 9. Referencias de código - `source/DAR_Logic.scl` – Funciones principales de lectura y alarmas. - `source/Maselli_ADAM_Read.scl` – Conversión 4-20 mA → °Brix. - `source/HMI_Instrument.scl` – DB de proceso con variables de los instrumentos. - `source/Syrup_Line_MFM_Prep_DAR.scl` – Secuencia automática de purga/carga (FC 1813 propuesto). - `source/Recipe__XX.scl` – Parámetros de receta (_BrixCutUR62, conductividad, etc.). --- ## 10. Anexo – Tabla rápida de códigos de error `Maselli_ADAM_Read` | Código | Significado | Rango mA | |--------|-------------|----------| | 0 | OK | 3,9 – 20,1 | | 1 | Maselli sin datos | ≈ 1,5 ± 0,1 | | 2 | Alarma Maselli | ≈ 2,0 ± 0,1 | | 3 | Sobre-rango alto | 20,1 – 22,8 | | 4 | Overflow | > 22,8 | | 5 | Sub-rango general | — | | 6 | Crítico (< 1,185 mA) | < 1,185 | --- ## 11. Detalle operativo actual de cálculo de litros y criterios de corte ### 11.1 Inicio – Priming de la línea Syrup 1. Al iniciar la secuencia `FTP302Line_Preparation` se copia el totalizador instantáneo del caudalímetro de jarabe FTP302: ```pascal gSyrLinePrepCountInit := Profibus_Variables.gFTP302_Tot ``` 2. En cada ciclo se calcula el volumen realmente desplazado desde ese instante: ```pascal TP301SyrupPrimingCount = Profibus_Variables.gFTP302_Tot - gSyrLinePrepCountInit ``` 3. Umbral volumétrico: * `Aux_Somma_Lt = _SyrupRunOutLiters + DB784` (DB784 es un ajuste dinámico calculado por la lógica *fuzzy-net*). * `WaterCountAcheaved = TP301SyrupPrimingCount ≥ Aux_Somma_Lt` 4. Umbral de °Brix (ver §5): * `UR62_Brix ≥ SyrBrix_Threshold` 5. Condiciones de fin de priming (se deben cumplir ambas): ```pascal WaterCountAcheaved = TRUE AND UR62_Brix ≥ SyrBrix_Threshold ``` Cuando esto ocurre, la FB `Syrup_Line_MFM_Prep_Seq` libera el paso a TP301 y pone `Procedure_Variables.FTP302Line_Preparation.LinePrepared := TRUE`. ```plantuml @startuml title 11.1 Priming – Syrup Line to TP301 hide footbox skinparam ArrowHeadColor none skinparam NoteBackgroundColor #F0F0F0 skinparam NoteBorderColor #999999 skinparam ParticipantPadding 20 skinparam BoxPadding 6 skinparam WrapWidth 250 !pragma teoz true ' ==== Estilos reutilizables (tomados del ejemplo) ==== !define VAR(x) x !define SIG(x) x !define FROM(x) x !define TO(x) x !definelong Nota($donde, $text) note over $donde $text end note !enddefinelong participant "Sala Syrup" as SR participant "Pump P2" as P2 participant "UR62\nQTM306" as UR62 participant PLC as PLC participant "Drain Valve\nAVS347/348" as DV participant "MFM FTP302" as FTP302 participant "Tank TP301" as TP301 == Inicio purga == SR -> P2 : FROM(Start purge – water) PLC -> DV : FROM(Open drain) loop Purga (agua) UR62 -> PLC : SIG(Brix) ≈ 0 PLC -> FTP302 : SIG(Read Tot) Nota(PLC, "Brix < _BrixCutUR62\nContando litros purga") end UR62 -> PLC : SIG(Brix) ≥ VAR(Threshold) PLC -> PLC : TO(WaterCountAcheaved := TRUE) == Fin priming == PLC -> DV : TO(Close drain) PLC -> TP301 : TO(Route syrup to TP301) Nota(PLC, "LinePrepared := TRUE\nSyrup loading starts") @enduml ``` ```plantuml @startuml ' Activity Diagram – Priming Syrup Line (New Syntax) ' PlantUML activity-beta title 11.1 Priming – Syrup Line to TP301 (Activity) skinparam wrapWidth 240 skinparam maxMessageSize 120 start :Iniciar purga de agua\n(Pump P2 ON, AVS347/348 OPEN); repeat :Medir Brix con UR62\n`Brix_UR62`; if (¿Brix ≥ Threshold?) then (sí) break else (no) :Contar litros purga\n`TP301SyrupPrimingCount += ΔFTP302`; endif repeat while (Brix < Threshold) if (¿Litros ≥ Aux_Somma_Lt?) then (sí) :WaterCountAcheaved := TRUE; else (no) :Seguir purgando; goto repeat endif :Cerrar drenaje AVS347/348; :Redirigir flujo a TP301; :LinePrepared := TRUE; stop @enduml ``` ### 11.2 Fin de producción – Empuje del producto en la tubería (Product Pipe Run-Out) El objetivo es vaciar el tramo de tubería comprendido entre el mezclador y la llenadora sin desperdiciar producto. Modo seleccionado mediante bits HMI: | Bit | Método de empuje | Descripción de cálculo | | -------------------------- | ------------------ | ------------------------------------------------------------------------ | | `ProdPipeRunOutWaterCount` | Conteo volumétrico | Igual que en priming, usando la suma de totalizadores `FTN301 + FTP302`. | | `ProdPipeRunOutFillerBott` | Conteo de botellas | Más preciso cuando hay contador de botellas de la llenadora. | #### a) Conteo volumétrico ```pascal Prod_Pipe_RunOut.Push_Count_Init := Prod_Pipe_RunOut.Totalizer // al arrancar Prod_Pipe_RunOut.Push_Count := TotalizerActual - Push_Count_Init ProdPushDone := Push_Count > ProdPipeRunOutProdAmount // valor receta ``` #### b) Conteo de botellas ```pascal VolumenTubing_litros = FillerBottleCount * Bottle_Size_Liters Prod_Pipe_RunOut.Push_Count_Init := VolumenTubing_litros // al arrancar Prod_Pipe_RunOut.Push_Count := VolumenTubing_litros - Push_Count_Init ProdPushDone := Push_Count > ProdPipeRunOutProdAmount ``` `Bottle_Size_Liters` se toma de `Filling_Time_Tranfer_DB.Bottle_Size_Litters` y `ProdPipeRunOutProdAmount` representa el volumen que cabe entre ambas máquinas, incluyendo colectores y válvulas. #### c) Condición de final La FB `ProductPipeRunOut_Seq` finaliza cuando: ```pascal ProdPushDone = TRUE // volumen/botellas empujado OR LastbottleDone = TRUE // señal In_Flr_LastContainer recibida ``` En ese momento: * `System_RunOut_Variables.ProdPipe_RunOut.Done := TRUE` * Se habilita la carga de la siguiente receta o se inicia el enjuague, según configuración. ```plantuml @startuml title 11.2 Product Pipe Run-Out – Empuje a llenadora hide footbox skinparam ArrowHeadColor none skinparam NoteBackgroundColor #F0F0F0 skinparam NoteBorderColor #999999 skinparam ParticipantPadding 20 skinparam BoxPadding 6 skinparam WrapWidth 250 !pragma teoz true ' ==== Estilos reutilizables ==== !define VAR(x) x !define SIG(x) x !define FROM(x) x !define TO(x) x !definelong Nota($donde, $text) note over $donde $text end note !enddefinelong participant PLC as PLC participant "MFM FTN301" as FTN301 participant "MFM FTP302" as FTP302 participant "Filler" as FILL participant "Prod Pipe" as PIPE == Solicitud Run-Out == FILL -> PLC : FROM(ProdPipe_RunOut.Request) PLC -> PLC : TO(Init Push_Count_Init) Nota(PLC, "Modo seleccionado:\n• WaterCount o\n• FillerBottleCount") == Empuje de producto == loop Mientras Push_Count < Objetivo FTP302 -> PLC : SIG(ΔTot Syrup) FTN301 -> PLC : SIG(ΔTot Water) FILL -> PLC : SIG(BottleCounter) PLC -> PLC : TO(Calcula Push_Count) end Nota(PLC, "ProdPushDone = TRUE") == Final Run-Out == PLC -> PIPE : TO(Cerrar válvulas / aislar producto) PLC -> PLC : TO(ProdPipe_RunOut.Done := TRUE) FILL -> PLC : SIG(LastBottleDone) Nota(PLC, "Si LastBottleDone o PushDone -> Done\nCarga siguiente receta / CIP") @enduml ``` ```plantuml @startuml title DAR Priming & RunOut States hide footbox skinparam ArrowHeadColor none skinparam NoteBackgroundColor #F0F0F0 skinparam NoteBorderColor #999999 skinparam ParticipantPadding 100 skinparam BoxPadding 6 skinparam WrapWidth 250 !pragma teoz true ' ==== Estilos reutilizables del ejemplo ==== !define VAR(x) x !define SIG(x) x !define FROM(x) x !define TO(x) x !definelong Nota($donde, $text) note over $donde $text end note !enddefinelong !definelong NotaParalela($donde, $text) / note over $donde $text end note !enddefinelong !definelong Variable($donde, $text) hnote right $donde #AAFFFF $text end note !enddefinelong !definelong VariableRojo($donde, $text) hnote right $donde #FFBBBB $text end note !enddefinelong !definelong VariableIzquierda($donde, $text) hnote left $donde #AAFFFF $text end note !enddefinelong !definelong VariableCentro($donde, $text) hnote over $donde #AAFFFF $text end note !enddefinelong state "DAR System" as System { [*] --> Idle : System startup state "Idle" as Idle { Idle : System ready Idle : Monitoring instruments } note right of Idle #AAFFFF UR62, UR29, CTS306 Online monitoring end note state "Priming Process" as Priming { state "Init Priming" as InitPriming { InitPriming : CMD_FTP302Line_Prep InitPriming : Operator request } state "Purging Water" as PurgingWater { PurgingWater : Open drain valve PurgingWater : Start Pump P2 } note right of PurgingWater #FFBBBB UR62_Brix < Threshold Volume < Aux_Somma_Lt end note state "Syrup Detected" as SyrupDetected { SyrupDetected : BrixCutReached = TRUE SyrupDetected : WaterCountAcheaved = TRUE } note right of SyrupDetected #AAFFFF UR62_Brix ≥ SyrBrix_Threshold Volume ≥ Aux_Somma_Lt end note state "Line Prepared" as LinePrepared { LinePrepared : Close drain valve LinePrepared : Route to TP301 } note right of LinePrepared #AAFFFF LinePrepared := TRUE Syrup loading starts end note InitPriming --> PurgingWater : Start purge PurgingWater --> SyrupDetected : Brix & Volume OK SyrupDetected --> LinePrepared : Conditions met LinePrepared --> [*] : Priming complete } state "Production Mode" as Production { Production : Normal blending Production : Recipe execution } note top of Production #AAFFFF Stable operation UR29 monitoring end note state "RunOut Process" as RunOut { state "Init RunOut" as InitRunOut { InitRunOut : ProdPipe_RunOut.Request InitRunOut : TM301_RunOut.Done } note right of InitRunOut #AAFFFF Push_Count_Init method selection end note state "Method Selection" as MethodSelection { MethodSelection : Choose counting method state "Water Count Mode" as WaterCount { WaterCount : Volumetric counting } state "Bottle Count Mode" as BottleCount { BottleCount : Filler bottle counting } note left of WaterCount #AAFFFF FTN301_Tot + FTP302_Tot end note note right of BottleCount #AAFFFF FillerBottleCount × Bottle_Size end note MethodSelection --> WaterCount : ProdPipeRunOutWaterCount MethodSelection --> BottleCount : ProdPipeRunOutFillerBott } state "Product Pushing" as Pushing { Pushing : Monitor push progress Pushing : Count volume/bottles } note right of Pushing #FFBBBB Push_Count < Target NOT LastbottleDone end note state "RunOut Complete" as RunOutComplete { RunOutComplete : ProdPipe_RunOut.Done = TRUE RunOutComplete : Close product valves } note right of RunOutComplete #AAFFFF ProdPushDone = TRUE OR LastbottleDone end note InitRunOut --> MethodSelection : Request received WaterCount --> Pushing : Method selected BottleCount --> Pushing : Method selected Pushing --> RunOutComplete : Target reached RunOutComplete --> [*] : RunOut complete } state "Changeover/CIP" as Changeover { Changeover : Load next recipe Changeover : OR start CIP } note top of Changeover #AAFFFF EnableNextRecipe OR Rinse sequence end note ' Main state transitions Idle --> Priming : Operator command Priming --> Production : Line prepared Production --> RunOut : End of production RunOut --> Changeover : Pipeline empty Changeover --> Idle : Sequence complete ' Emergency transitions Priming --> Idle : Abort sequence Production --> Idle : Emergency stop RunOut --> Idle : Emergency stop } ' External notes with color coding note top of System #F0F0F0 **Sistema DAR - Diet as Regular** SAE452 San Giorgio in Bosco end note note bottom of System #AAFFFF **Instrumentos principales:** • UR62 (QTM306): Detección agua/jarabe • UR29 (QTM307): Precisión alta • CTS306: Conductividad agua end note @enduml ```