584 lines
19 KiB
Markdown
584 lines
19 KiB
Markdown
|
||
---
|
||
|
||
# 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)<br>`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<br>`HMI_Instrument.QTM307` |
|
||
| **CTS306** | Conductivímetro Knick 2405 | Comprobar dureza (µS/cm) del agua de proceso; generar alarmas fuera de rango | 4-20 mA<br>`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) <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
|
||
```
|
||
|
||
```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) <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
|
||
```
|
||
|
||
|
||
```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) <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
|
||
``` |