Obsidean_VM/04-SIDEL/09 - SAE452 - Diet as Regul.../Notas - Sistema DAR – Diet ...

19 KiB
Raw Blame History


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

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)

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:
gSyrLinePrepCountInit := Profibus_Variables.gFTP302_Tot
  1. En cada ciclo se calcula el volumen realmente desplazado desde ese instante:
TP301SyrupPrimingCount = Profibus_Variables.gFTP302_Tot - gSyrLinePrepCountInit
  1. 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
  2. Umbral de °Brix (ver §5):
    • UR62_Brix ≥ SyrBrix_Threshold
  3. Condiciones de fin de priming (se deben cumplir ambas):
   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.

@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) <back:#F0F0F0><color:#7F6000><b>x</b></color></back>
!define SIG(x) <back:#F0F0F0><color:#005A9E><b>x</b></color></back>
!define FROM(x) <back:#FFAAAA><color:#000000><b>x</b></color></back>
!define TO(x) <back:#AAFFFF><color:#000000><b> x</b></color></back>

!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
@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

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

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:

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.
@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) <back:#F0F0F0><color:#7F6000><b>x</b></color></back>
!define SIG(x) <back:#F0F0F0><color:#005A9E><b>x</b></color></back>
!define FROM(x) <back:#FFAAAA><color:#000000><b>x</b></color></back>
!define TO(x) <back:#AAFFFF><color:#000000><b> x</b></color></back>

!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
@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) <back:#F0F0F0><color:#7F6000><b>x</b></color></back>
!define SIG(x) <back:#F0F0F0><color:#005A9E><b>x</b></color></back>
!define FROM(x) <back:#FFAAAA><color:#000000><b>x</b></color></back>
!define TO(x) <back:#AAFFFF><color:#000000><b> x</b></color></back>

!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 : <back:#FFAAAA><color:#000000><b>CMD_FTP302Line_Prep</b></color></back>
      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 : <back:#AAFFFF><color:#000000><b> BrixCutReached = TRUE</b></color></back>
      SyrupDetected : <back:#AAFFFF><color:#000000><b> WaterCountAcheaved = TRUE</b></color></back>
    }
    
    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 : <back:#F0F0F0><color:#7F6000><b>Start purge</b></color></back>
    PurgingWater --> SyrupDetected : <back:#F0F0F0><color:#005A9E><b>Brix & Volume OK</b></color></back>
    SyrupDetected --> LinePrepared : <back:#AAFFFF><color:#000000><b> Conditions met</b></color></back>
    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 : <back:#FFAAAA><color:#000000><b>ProdPipe_RunOut.Request</b></color></back>
      InitRunOut : <back:#FFAAAA><color:#000000><b>TM301_RunOut.Done</b></color></back>
    }
    
    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 : <back:#F0F0F0><color:#7F6000><b>ProdPipeRunOutWaterCount</b></color></back>
      MethodSelection --> BottleCount : <back:#F0F0F0><color:#7F6000><b>ProdPipeRunOutFillerBott</b></color></back>
    }
    
    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 : <back:#AAFFFF><color:#000000><b> ProdPipe_RunOut.Done = TRUE</b></color></back>
      RunOutComplete : Close product valves
    }
    
    note right of RunOutComplete #AAFFFF
      ProdPushDone = TRUE
      OR LastbottleDone
    end note
    
    InitRunOut --> MethodSelection : <back:#F0F0F0><color:#005A9E><b>Request received</b></color></back>
    WaterCount --> Pushing : <back:#AAFFFF><color:#000000><b> Method selected</b></color></back>
    BottleCount --> Pushing : <back:#AAFFFF><color:#000000><b> Method selected</b></color></back>
    Pushing --> RunOutComplete : <back:#F0F0F0><color:#005A9E><b>Target reached</b></color></back>
    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 : <back:#FFAAAA><color:#000000><b>Operator command</b></color></back>
  Priming --> Production : <back:#AAFFFF><color:#000000><b> Line prepared</b></color></back>
  Production --> RunOut : <back:#F0F0F0><color:#005A9E><b>End of production</b></color></back>
  RunOut --> Changeover : <back:#AAFFFF><color:#000000><b> Pipeline empty</b></color></back>
  Changeover --> Idle : <back:#F0F0F0><color:#005A9E><b>Sequence complete</b></color></back>
  
  ' Emergency transitions
  Priming --> Idle : <back:#FFAAAA><color:#000000><b>Abort sequence</b></color></back>
  Production --> Idle : <back:#FFAAAA><color:#000000><b>Emergency stop</b></color></back>
  RunOut --> Idle : <back:#FFAAAA><color:#000000><b>Emergency stop</b></color></back>
}

' 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