Primera version
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
FUNCTION_BLOCK "FB15152_ZC_PARO_SEC"
|
||||
TITLE = FB15152_ZC_PARO_SEC
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de funcion para la gestion de paro secuencial de dispositivos
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
MarchaSecuenciaParo : Bool; // Orden marcha secuencia de paro
|
||||
NumeroDispositivos { S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Int := 4; // Numero de dispositivos
|
||||
TiempoEntreEtapas { S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Int := 2; // Tiempo entre etapas
|
||||
ConfirmacionDisp { S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Array[1..#N_MAX] of Bool; // Confirmacion activado dispositivo
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
SecParoFinalizada : Bool; // Secuencia de paro completada
|
||||
SecReposo : Bool; // Secuencia en reposo
|
||||
ParoDispositivo { S7_HiddenAssignment := 'HideIfNoParamAssigned'} : Array[1..#N_MAX] of Bool; // Orden paro dispositivo
|
||||
END_VAR
|
||||
|
||||
VAR
|
||||
s_NumeroDispositivos { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Numero de dispositivos
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
s_EtapaActual { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Etapa actual
|
||||
s_Indice { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Indice dispositivo actual
|
||||
s_TiempoActual { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // Tiempo actual
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
N_MAX : Int := 8;
|
||||
REPOSO : Int := 0;
|
||||
PARANDO : Int := 10;
|
||||
REARMANDO : Int := 20;
|
||||
FINALIZADO : Int := 30;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2023 - 2026
|
||||
//=======================================================================
|
||||
(*
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
El bloque `FB15051_PARO_SECUENCIAL` implementa un secuenciador bidireccional para el paro ordenado de un array de dispositivos. Permite detener los dispositivos uno a uno esperando una confirmación por etapa, y rearmar la secuencia en sentido inverso si se retira la orden de marcha, continuando desde la última etapa alcanzada en lugar de reiniciar desde el inicio.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Validación del número de dispositivos: `#NumeroDispositivos` se acota entre 1 y la constante de dimensionamiento `#N_MAX`.
|
||||
- Estado `REPOSO`: bloque en espera. Al recibir `#MarchaSecuenciaParo := TRUE` se inicializa el índice y se transita a la etapa `PARANDO`.
|
||||
- Estado `PARANDO`: avanza secuencialmente por los dispositivos de menor a mayor índice. Cada dispositivo se considera parado cuando se cumple `#ConfirmacionDisp[i] = TRUE` durante `#TiempoEntreEtapas` segundos. Al confirmar, se incrementa el índice hasta superar `#s_NumeroDispositivos`, momento en el que se transita a `FINALIZADO`. Si durante esta etapa se desactiva `#MarchaSecuenciaParo`, se invierte el sentido y se pasa a `REARMANDO` sin perder la posición alcanzada.
|
||||
- Estado `REARMANDO`: retrocede secuencialmente por los dispositivos de mayor a menor índice. Cada dispositivo se considera rearmado cuando `#ConfirmacionDisp[i] = FALSE` durante `#TiempoEntreEtapas` segundos. Al rearmar, se decrementa el índice hasta alcanzar 1, momento en el que se transita a `REPOSO`. Si durante esta etapa se vuelve a activar `#MarchaSecuenciaParo`, se invierte nuevamente el sentido y se pasa a `PARANDO` desde la posición actual.
|
||||
- Estado `FINALIZADO`: secuencia de paro completa. Al retirar `#MarchaSecuenciaParo`, se rearman los dispositivos en orden inverso empezando desde el último, transitando a `REARMANDO`.
|
||||
- Mapeado dinámico de salidas: para cada dispositivo se activa `#ParoDispositivo[i] := TRUE` si su índice es menor o igual al puntero actual y la etapa es `PARANDO`; en el resto de casos se mantiene en `FALSE`. Esto garantiza que los dispositivos ya parados en la fase actual permanezcan parados durante el rearmado inverso de los posteriores.
|
||||
- Señales de estado: `#SecReposo` indica que la secuencia está en `REPOSO` y `#SecParoFinalizada` que ha terminado (`FINALIZADO`).
|
||||
- Contadores de tiempo por etapa del tipo `ZC_TIEMPO_ETAPA` con base de tiempo en segundos (`#Pulso1Seg`).
|
||||
|
||||
> **Restricciones:** PLC serie 1200/1500.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `ZC_TIEMPO_ETAPA` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 00.00.01 | 24.05.2023 | (ABH) | Primera versión. |
|
||||
| 00.00.02 | 15.12.2023 | (HCR) | Se aumentan los dispositivos de 4 a 8. |
|
||||
| 00.00.03 | 18.12.2023 | (ABH) | Se cambia UDT tiempo etapa a `ZC_TIEMPO_ETAPA`. Se añade salida `SecReposo` para indicar que está en reposo. Se añade gestión de etapas para que, en caso de estar con orden de paro y se dé marcha, siga la secuencia donde le toque evitando tener que pararla por completo y volverla a arrancar. |
|
||||
| 01.00.00 | 03.07.2026 | (ABH) | Cambio a SCL. Se refactoriza logicas para estandarizar. Se utiliza constante N_MAX para redimensionar. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LIMITES
|
||||
|
||||
#s_NumeroDispositivos := #NumeroDispositivos;
|
||||
|
||||
// Limite de seguridad
|
||||
IF #s_NumeroDispositivos > #N_MAX THEN
|
||||
#s_NumeroDispositivos := #N_MAX;
|
||||
ELSIF #s_NumeroDispositivos < 1 THEN
|
||||
#s_NumeroDispositivos := 1;
|
||||
END_IF;
|
||||
|
||||
END_REGION LIMITES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SECUENCIADOR_BIDIRECCIONAL
|
||||
|
||||
CASE #s_EtapaActual OF
|
||||
|
||||
#REPOSO:
|
||||
#s_Indice := 1;
|
||||
#s_TiempoActual := 0;
|
||||
|
||||
IF #MarchaSecuenciaParo THEN
|
||||
#s_EtapaActual := #PARANDO;
|
||||
END_IF;
|
||||
|
||||
#PARANDO:
|
||||
|
||||
// Contador de tiempo con confirmacion de dispositivo
|
||||
IF #ConfirmacionDisp[#s_Indice] AND #Pulso1Seg THEN
|
||||
#s_TiempoActual += 1;
|
||||
END_IF;
|
||||
|
||||
// Tiempo cumplido
|
||||
IF (#s_TiempoActual >= #TiempoEntreEtapas) THEN
|
||||
#s_TiempoActual := 0;
|
||||
#s_Indice += 1; // Avanzamos al siguiente dispositivo
|
||||
|
||||
// Comprobación de fin de secuencia de paro
|
||||
IF #s_Indice > #s_NumeroDispositivos THEN
|
||||
#s_EtapaActual := #FINALIZADO;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
// Si se desactiva la orden de marcha de la secuencia, comenzamos el rearme inverso
|
||||
IF NOT #MarchaSecuenciaParo THEN
|
||||
#s_TiempoActual := 0;
|
||||
#s_EtapaActual := #REARMANDO;
|
||||
END_IF;
|
||||
|
||||
|
||||
#REARMANDO:
|
||||
|
||||
// Límite de seguridad inferior
|
||||
IF #s_Indice < 1 THEN
|
||||
#s_EtapaActual := #REPOSO;
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
// Contador de tiempo sin confirmacion de dispositivo
|
||||
IF NOT #ConfirmacionDisp[#s_Indice] AND #Pulso1Seg THEN
|
||||
#s_TiempoActual += 1;
|
||||
END_IF;
|
||||
|
||||
// Tiempo cumplido
|
||||
IF (#s_TiempoActual >= #TiempoEntreEtapas) THEN
|
||||
#s_TiempoActual := 0;
|
||||
#s_Indice -= 1; // Avanzamos al dispositivo anterior
|
||||
|
||||
IF #s_Indice < 1 THEN
|
||||
#s_EtapaActual := #REPOSO;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
// Si se vuelve a dar marcha, invertimos dirección nuevamente
|
||||
IF #MarchaSecuenciaParo THEN
|
||||
#s_TiempoActual := 0;
|
||||
#s_EtapaActual := #PARANDO;
|
||||
END_IF;
|
||||
|
||||
|
||||
#FINALIZADO:
|
||||
|
||||
IF NOT #MarchaSecuenciaParo THEN
|
||||
#s_TiempoActual := 0;
|
||||
// Empezamos a rearmar desde el último dispositivo que se paro
|
||||
#s_Indice := #s_NumeroDispositivos;
|
||||
#s_EtapaActual := #REARMANDO;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#s_EtapaActual := #REPOSO;
|
||||
END_CASE;
|
||||
|
||||
END_REGION SECUENCIADOR_BIDIRECCIONAL
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION MAPEADO_DINAMICO_DE_SALIDAS
|
||||
|
||||
#SecReposo := (#s_EtapaActual = #REPOSO);
|
||||
#SecParoFinalizada := (#s_EtapaActual = #FINALIZADO);
|
||||
|
||||
// Mapeo vectorial de comandos físicos
|
||||
FOR #for_i := 1 TO #N_MAX DO
|
||||
|
||||
// Si el índice iterativo es menor que nuestro puntero de etapa actual,
|
||||
// significa que ya hemos pasado por él en la secuencia de paro y debe estar detenido.
|
||||
IF #for_i < #s_Indice THEN
|
||||
#ParoDispositivo[#for_i] := TRUE;
|
||||
|
||||
// Si el índice coincide con el puntero y estamos parando, forzamos la salida a TRUE
|
||||
ELSIF (#for_i = #s_Indice) AND (#s_EtapaActual = #PARANDO) THEN
|
||||
#ParoDispositivo[#for_i] := TRUE;
|
||||
|
||||
// Para el resto de condiciones
|
||||
ELSE
|
||||
#ParoDispositivo[#for_i] := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION MAPEADO_DINAMICO_DE_SALIDAS
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
FUNCTION_BLOCK "FB15153_ZC_MARCHA_SEC_B_MEM"
|
||||
TITLE = FB15153_ZC_MARCHA_SEC_B_MEM
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de funcion para la gestion de activacion de las bombas de de una maquina de membranas
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
MarchaSecuencia : Bool; // Orden de marcha secuencia
|
||||
EstadoBombaPresionVF : Bool; // Estado bomba Presion (Variador)
|
||||
EstadoBombaPresion : Bool; // Estado bomba Presion
|
||||
TiempoEntreBombas : Int := 10; // SP Tiempo entre bombas
|
||||
NumeroBombasPresion : Int := 2; // Numero de bombas presion (1 o 2)
|
||||
NumeroModulos : Int := 6; // Numero de modulos
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
MarchaBombaPresionVF : Bool; // Activacion bomba Presion (Variador)
|
||||
MarchaBombaPresion : Bool; // Activacion bomba Presion
|
||||
MarchaBombaModulo : Array[1..#N_MAX] of Bool; // Activacion bomba Modulo
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
s_TonPresion { S7_SetPoint := 'False'} : Array[1..2] of "UDT_ZC_DISP_TON";
|
||||
s_TonModulos { S7_SetPoint := 'False'} : Array[1..#N_MAX] of "UDT_ZC_DISP_TON";
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
t_NumBombasPresion : Int; // Numero de bombas presion
|
||||
t_NumModulos : Int; // Numero de modulos
|
||||
t_BombasPresionOk : Bool; // Bombas presion arrancadas Ok
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
N_MAX : Int := 6;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2023 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Bloque de gestión de marcha secuencial de bombas de una máquina de membranas. Implementa el arranque escalonado, en cascada y temporizado, de las bombas de presión y de las bombas de los módulos de la máquina, respetando el número de bombas y módulos configurados y utilizando temporizadores individuales no retentivos.
|
||||
|
||||
Acciones detalladas:
|
||||
- Limita el número de bombas de presión activas (`t_NumBombasPresion`) al rango válido `1`–`2`, acotando la entrada `NumeroBombasPresion`.
|
||||
- Limita el número de módulos activos (`t_NumModulos`) al rango válido `1`–`N_MAX`, acotando la entrada `NumeroModulos`.
|
||||
- Traslada el setpoint de temporización `TiempoEntreBombas` a todos los temporizadores de bombas de presión (`s_TonPresion[1..2]`) y de módulos (`s_TonModulos[1..N_MAX]`).
|
||||
- Gestiona el arranque de las bombas de presión mediante dos temporizadores en cascada: primero la bomba de variador (`s_TonPresion[1]`) y, tras su confirmación y solo si hay 2 bombas configuradas, la segunda bomba de presión (`s_TonPresion[2]`).
|
||||
- Calcula el flag `t_BombasPresionOk`, que indica que el conjunto de bombas de presión requerido está en marcha: con 1 bomba exige confirmación del variador, con 2 bombas exige confirmación de ambas.
|
||||
- Arranca el módulo 1 (`s_TonModulos[1]`) directamente cuando las bombas de presión están OK.
|
||||
- Arranca los módulos `2` a `N_MAX` en cascada, de forma que cada módulo espera a la confirmación del módulo anterior y a las bombas de presión OK; los módulos no configurados se fuerzan a `FALSE` por seguridad.
|
||||
- Ejecuta los temporizadores llamando a la `FC` de temporización individual, lo que permite disponer de un `SP`, una `IN`, una salida `Q` y un tiempo transcurrido independientes por instancia.
|
||||
- Genera las salidas finales: `MarchaBombaPresionVF` (variador), `MarchaBombaPresion` (segunda bomba) y `MarchaBombaModulo[1..N_MAX]` a partir de las salidas `Q` de los temporizadores correspondientes.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC2928_ZC_TON_INDV` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 09.05.2023 | (ABH) | Primera version. |
|
||||
| 01.00.01 | 19.05.2023 | (ABH) | Se añade parámetro de entrada para límite de número de bombas de presión. |
|
||||
| 01.00.02 | 02.10.2023 | (ABH) | Se añade `FC22028_TON_INV` para gestión de temporizadores. |
|
||||
| 01.00.03 | 02.11.2023 | (ABH) | Se añade gestión para 6 módulos. |
|
||||
| 01.00.03 | 06.07.2026 | (ABH) | Cambio a SCL. Se refactoriza numero de modulos.|
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LIMITES
|
||||
|
||||
// Limite numero de bombas presion
|
||||
#t_NumBombasPresion := #NumeroBombasPresion;
|
||||
IF #t_NumBombasPresion < 1 THEN
|
||||
#t_NumBombasPresion := 1;
|
||||
END_IF;
|
||||
IF #t_NumBombasPresion > 2 THEN
|
||||
#t_NumBombasPresion := 2;
|
||||
END_IF;
|
||||
|
||||
// Limite numero de bombas modulos
|
||||
#t_NumModulos := #NumeroModulos;
|
||||
IF #t_NumModulos < 1 THEN
|
||||
#t_NumModulos := 1;
|
||||
END_IF;
|
||||
IF #t_NumModulos > #N_MAX THEN
|
||||
#t_NumModulos := #N_MAX;
|
||||
END_IF;
|
||||
|
||||
END_REGION LIMITES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION TRASPASO_DE_PARAMETROS
|
||||
|
||||
// Traspaso de tiempos bomba presion
|
||||
FOR #for_i := 1 TO 2 DO
|
||||
#s_TonPresion[#for_i].SP := #TiempoEntreBombas;
|
||||
END_FOR;
|
||||
|
||||
// Traspaso de tiempos bomba modulos
|
||||
FOR #for_i := 1 TO #N_MAX DO
|
||||
#s_TonModulos[#for_i].SP := #TiempoEntreBombas;
|
||||
END_FOR;
|
||||
|
||||
END_REGION TRASPASO_DE_PARAMETROS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_BOMBAS_PRESION
|
||||
|
||||
// Temporizador bomba Presion (Variador)
|
||||
#s_TonPresion[1].IN := #MarchaSecuencia;
|
||||
|
||||
// Temporizador bomba Presion
|
||||
#s_TonPresion[2].IN :=
|
||||
(#t_NumBombasPresion = 2) AND
|
||||
#EstadoBombaPresionVF AND
|
||||
#s_TonPresion[1].Q;
|
||||
|
||||
// Bombas presion arrancadas Ok
|
||||
IF #t_NumBombasPresion = 1 THEN
|
||||
#t_BombasPresionOk := #EstadoBombaPresionVF AND #s_TonPresion[1].Q;
|
||||
ELSE
|
||||
#t_BombasPresionOk := #EstadoBombaPresion AND #s_TonPresion[2].Q;
|
||||
END_IF;
|
||||
|
||||
END_REGION GESTION_BOMBAS_PRESION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_BOMBAS_MODULOS
|
||||
|
||||
// El modulo 1 arranca directamente si las bombas de presion estan OK
|
||||
#s_TonModulos[1].IN := #t_BombasPresionOk;
|
||||
|
||||
// Los modulos 2 a N_MAX arrancan en cascada
|
||||
FOR #for_i := 2 TO #N_MAX DO
|
||||
|
||||
IF #for_i <= #t_NumModulos THEN
|
||||
|
||||
// Si el módulo está dentro de la configuración, evalúa la cascada (Módulo anterior Q + bombas presion Ok)
|
||||
#s_TonModulos[#for_i].IN := #s_TonModulos[#for_i - 1].Q AND #t_BombasPresionOk;
|
||||
|
||||
ELSE
|
||||
|
||||
// Forzado de seguridad a FALSE para módulos no instalados/configurados en esta máquina
|
||||
#s_TonModulos[#for_i].IN := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION GESTION_BOMBAS_MODULOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_TEMPORIZADORES
|
||||
|
||||
// Temporizadores bombas presion
|
||||
FOR #for_i := 1 TO 2 DO
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := #Pulso1Seg,
|
||||
TON := #s_TonPresion[#for_i]);
|
||||
END_FOR;
|
||||
|
||||
// Temporizadores bombas modulos
|
||||
FOR #for_i := 1 TO #N_MAX DO
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := #Pulso1Seg,
|
||||
TON := #s_TonModulos[#for_i]);
|
||||
END_FOR;
|
||||
|
||||
END_REGION GESTION_TEMPORIZADORES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SALIDAS
|
||||
|
||||
// Bombas presion
|
||||
#MarchaBombaPresionVF := #s_TonPresion[1].Q;
|
||||
#MarchaBombaPresion := #s_TonPresion[2].Q;
|
||||
|
||||
// Bombas modulos
|
||||
FOR #for_i := 1 TO #N_MAX DO
|
||||
|
||||
#MarchaBombaModulo[#for_i] := #s_TonModulos[#for_i].Q;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION SALIDAS
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
@@ -0,0 +1,403 @@
|
||||
FUNCTION "FC15151_ZC_MARCHA_PARO_SEC" : Void
|
||||
TITLE = FC15151_ZC_MARCHA_PARO_SEC
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Funcion para la gestion de marcha/paro de dispositivos secuencialmente
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
Seguridad : Bool; // Estado seguridades ok
|
||||
Marcha : Bool; // Orden de marcha
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
MP_SEC : "UDT_ZC_MARCHA_PARO_SEC";
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
REPOSO : Int := 0;
|
||||
MARCHA_1 : Int := 10;
|
||||
MARCHA_2 : Int := 20;
|
||||
MARCHA_3 : Int := 30;
|
||||
MARCHA_4 : Int := 40;
|
||||
MARCHA_5 : Int := 50;
|
||||
MARCHA_6 : Int := 60;
|
||||
MARCHA_7 : Int := 70;
|
||||
MARCHA_8 : Int := 80;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2023 - 2025
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función encargada de la gestión de secuencias de arranque y parada escalonada de hasta 8 dispositivos de forma temporizada.
|
||||
|
||||
- Evaluar dinámicamente los parámetros de configuración, limitando el número de elementos de la secuencia a un rango válido entre 1 y 8 mediante la variable `NumElementos`.
|
||||
- Gestionar el traspaso del tiempo de espera entre etapas, aplicando de forma automática los parámetros `TiempoEntreMarcha` o `TiempoEntreParo` según el estado de la orden activa en la entrada `Marcha`.
|
||||
- Ejecutar una máquina de estados para la transición secuencial de las etapas de operación, controlando el tiempo de permanencia en cada fase mediante la señal base de tiempo `Pulso1Seg`.
|
||||
- Monitorizar de forma continua la señal de `Seguridad`, forzando el reinicio seguro de la máquina de estados a la etapa de reposo y limpiando los temporizadores en caso de pérdida.
|
||||
- Calcular y activar las señales de salida operativas, incluyendo los bits individuales de activación por dispositivo (`M[1]` a `M[8]`) y las confirmaciones de ciclo finalizado (`SecMarchaCompletada` y `SecParoCompletada`).
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | ´UDT_ZC_MARCHA_PARO_SEC´ |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 24.05.2023 | (ABH) | Primera version. |
|
||||
| 01.00.01 | 28.07.2023 | (ABH) | Se añade traspaso de Set Point de tiempo de paso dentro del FC. |
|
||||
| 01.00.02 | 14.03.2025 | (ABH) | Se separan los tiempos de arranque de marcha y paro. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION TRASPASO_PARAMETROS
|
||||
|
||||
// Limite de numero de elementos
|
||||
IF #MP_SEC.NumElementos < 1 THEN
|
||||
#MP_SEC.NumElementos := 1;
|
||||
END_IF;
|
||||
|
||||
IF #MP_SEC.NumElementos > 8 THEN
|
||||
#MP_SEC.NumElementos := 8;
|
||||
END_IF;
|
||||
|
||||
// Traspaso de set point tiempo etapa
|
||||
IF #Marcha THEN
|
||||
#MP_SEC.Tiempo.SetPoint := #MP_SEC.TiempoEntreMarcha;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.SetPoint := #MP_SEC.TiempoEntreParo;
|
||||
END_IF;
|
||||
|
||||
// Seguridad
|
||||
IF NOT #Seguridad THEN
|
||||
#MP_SEC.Etapa := #MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_REGION TRASPASO_PARAMETROS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SECUENCIA
|
||||
|
||||
CASE #MP_SEC.Etapa OF
|
||||
|
||||
// ==========================================================================================================
|
||||
#REPOSO:
|
||||
IF #Marcha AND #Seguridad THEN
|
||||
#MP_SEC.Etapa := #MARCHA_1;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_1:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 1 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_2;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #REPOSO;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_2:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 2 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_3;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_1;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_3:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 3 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_4;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_2;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_4:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 4 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_5;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_3;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_5:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 5 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_6;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_4;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_6:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 6 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_7;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_5;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_7:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, si hay mas elementos saltamos a la siguiente etapa, de lo contrario, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
|
||||
IF #MP_SEC.NumElementos > 7 THEN
|
||||
#MP_SEC.Etapa := #MARCHA_8;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
ELSE
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_6;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// ==========================================================================================================
|
||||
#MARCHA_8:
|
||||
|
||||
// Activacion tiempo de etapa
|
||||
#MP_SEC.Tiempo.Activar := TRUE;
|
||||
|
||||
// Con tiempo de etapa cumplido
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint THEN
|
||||
|
||||
// Estando en marcha, reseteamos el tiempo de etapa
|
||||
IF #Marcha THEN
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #MARCHA_7;
|
||||
#MP_SEC.Tiempo.Actual := 0;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#MP_SEC.Etapa := #REPOSO;
|
||||
END_CASE;
|
||||
|
||||
|
||||
END_REGION SECUENCIA
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION TIEMPO_DE_ETAPA
|
||||
|
||||
IF #MP_SEC.Tiempo.Activar THEN
|
||||
|
||||
IF #Pulso1Seg THEN
|
||||
#MP_SEC.Tiempo.Actual += 1;
|
||||
END_IF;
|
||||
|
||||
#MP_SEC.Tiempo.Restante := #MP_SEC.Tiempo.SetPoint - #MP_SEC.Tiempo.Actual;
|
||||
|
||||
IF #MP_SEC.Tiempo.Restante <= 0 THEN
|
||||
#MP_SEC.Tiempo.Restante := 0;
|
||||
END_IF;
|
||||
|
||||
#MP_SEC.Tiempo.Activar := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION TIEMPO_DE_ETAPA
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SALIDAS
|
||||
|
||||
// Secuencia paro completada
|
||||
#MP_SEC.SecParoCompletada := #MP_SEC.Etapa = 0;
|
||||
|
||||
// Secuencia Marcha completada
|
||||
#MP_SEC.SecMarchaCompletada := FALSE;
|
||||
CASE #MP_SEC.NumElementos OF
|
||||
1:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 10 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
2:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 20 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
3:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 30 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
4:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 40 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
5:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 50 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
6:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 60 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
7:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 70 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
8:
|
||||
IF #MP_SEC.Tiempo.Actual >= #MP_SEC.Tiempo.SetPoint AND #MP_SEC.Etapa = 80 THEN
|
||||
#MP_SEC.SecMarchaCompletada := TRUE;
|
||||
END_IF;
|
||||
END_CASE;
|
||||
|
||||
// Bit marcha elementos
|
||||
#MP_SEC.M[1] := #MP_SEC.Etapa >= 10;
|
||||
#MP_SEC.M[2] := #MP_SEC.Etapa >= 20;
|
||||
#MP_SEC.M[3] := #MP_SEC.Etapa >= 30;
|
||||
#MP_SEC.M[4] := #MP_SEC.Etapa >= 40;
|
||||
#MP_SEC.M[5] := #MP_SEC.Etapa >= 50;
|
||||
#MP_SEC.M[6] := #MP_SEC.Etapa >= 60;
|
||||
#MP_SEC.M[7] := #MP_SEC.Etapa >= 70;
|
||||
#MP_SEC.M[8] := #MP_SEC.Etapa >= 80;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
Reference in New Issue
Block a user