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

584 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
# 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
```