Reorganizacion de libreria.
This commit is contained in:
+135
@@ -0,0 +1,135 @@
|
||||
FUNCTION "FC17_ZC_GEST_ALM" : Void
|
||||
TITLE = FC17_ZC_GEST_ALM
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
VAR_INPUT
|
||||
PrimerCiclo : Bool; // Marca de primer ciclo de arranque de la CPU
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
Usuario : String; // Usuario actual
|
||||
PInt : Array[*] of "UDT_ZC_PINT"; // Array de parametro entero
|
||||
IndexTraza : Int; // Indice de texto parametro para trazabilidad
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
ValorAnterior : Array[*] of Int; // Array de valores anteriores
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : DInt; // Variable para bucles FOR
|
||||
t_IndiceSuperior : DInt; // Indice superior del array
|
||||
t_IndiceInferior : DInt; // Indice inferior del array
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2026 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** DB Optimizado.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función principal para la gestión de trazabilidad de los parámetros **enteros** del proceso.
|
||||
|
||||
Su objetivo principal es detectar cambios de valor en el array de parámetros y lanzar un registro de traza cuando esto sucede.
|
||||
|
||||
El bloque opera de la siguiente manera:
|
||||
|
||||
1. Calcula dinámicamente los límites superior e inferior del array de entrada.
|
||||
2. Si es el primer ciclo de ejecución de la CPU, inicializa los valores "anteriores" con los valores "actuales" para evitar falsos registros de traza iniciales.
|
||||
3. En ciclos normales, compara el valor actual de cada parámetro con su valor guardado en el ciclo anterior.
|
||||
4. Si detecta una diferencia, llama a la función `FC8_ZC_TRAZA_REGISTRO` para registrar el cambio y actualiza el valor anterior.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC8_ZC_TRAZA_REGISTRO` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_PINT` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 2026-03-20 | (ABH) | Primera version. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
// Calculo de los limites del array, ya que la entrada del array de parametros es variable.
|
||||
#t_IndiceInferior := LOWER_BOUND(ARR := #PInt, DIM := 1);
|
||||
#t_IndiceSuperior := UPPER_BOUND(ARR := #PInt, DIM := 1);
|
||||
|
||||
END_REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION PRIMER_ARRANQUE
|
||||
|
||||
// En el primer arranque de la CPU, recorremos el array completo y almacenamos los valores actuales como valores anteriores en el arranque de la CPU.
|
||||
// Esto se realiza ya que los valores anteriores no son remanentes, para optimizar la memoria del PLC.
|
||||
IF #PrimerCiclo THEN
|
||||
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
#ValorAnterior[#for_i] := #PInt[#for_i].Valor;
|
||||
END_FOR;
|
||||
|
||||
// Salimos inmediatamente de la funcion, para realizar la gestion de los parametros con la CPU arrancada
|
||||
RETURN;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION PRIMER_ARRANQUE
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_PARAMETROS
|
||||
|
||||
// Gestion de los cambios de valor de los parametros. Si detecta un cambio, lanza la traza
|
||||
// y actualiza el valor anterior.
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
|
||||
// En caso de detectar cambio de valor
|
||||
IF #PInt[#for_i].Valor <> #ValorAnterior[#for_i] THEN
|
||||
|
||||
// Lanzamos la trazabilidad
|
||||
"FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHora,
|
||||
Registrar := 1,
|
||||
Categoria := "TRZ_CAT_26_PINT",
|
||||
User := #Usuario,
|
||||
CodInt_1 := #IndexTraza + DINT_TO_INT(#for_i - 1),
|
||||
CodInt_2 := "TRZ_SYS_PAR_VAL_ANT",
|
||||
CodInt_3 := "TRZ_SYS_PAR_VAL_NUE",
|
||||
CodInt_4 := 0,
|
||||
CodInt_5 := 0,
|
||||
CodReal_1 := #ValorAnterior[#for_i],
|
||||
CodReal_2 := #PInt[#for_i].Valor);
|
||||
|
||||
// Actualizamos el valor anterior
|
||||
#ValorAnterior[#for_i] := #PInt[#for_i].Valor;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION GESTION_PARAMETROS
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
DATA_BLOCK "DB11_INF"
|
||||
TITLE = DB11_INFORMES
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
NON_RETAIN
|
||||
VAR RETAIN
|
||||
Gestion { S7_SetPoint := 'False'} : "UDT_ZC_INF_GESTION";
|
||||
Buffer { S7_SetPoint := 'False'} : Array[0.."N_MAX_INF_BUFFER"] of "UDT_ZC_INF_DATOS";
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
Gestion.HabilitacionGeneral := TRUE;
|
||||
Gestion.EstadoConexion := TRUE;
|
||||
Gestion.OrdenIniciar := FALSE;
|
||||
Gestion.Etapa := 0;
|
||||
Gestion.SP_Tiempo := 10;
|
||||
Gestion.TiempoActual := 0;
|
||||
Gestion.NumeroMaxIntentos := 3;
|
||||
|
||||
END_DATA_BLOCK
|
||||
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
FUNCTION_BLOCK "FB15051_ZC_INF_CPR"
|
||||
TITLE = FB15051_ZC_INF_CPR
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
VAR_INPUT
|
||||
GuardarDatos : Bool; // Orden guardar datos
|
||||
FinGuardarDatos : Bool; // Orden finalizar guardar datos
|
||||
FechaActual {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
TipoProceso : Int; // Tipo de proceso
|
||||
Destino : Int; // Destino
|
||||
Producto : Int; // Producto
|
||||
Producto1Destino : Int; // Producto 1 en destino
|
||||
Producto2Destino : Int; // Producto 2 en destino
|
||||
Nombre : String[40]; // Nombre
|
||||
Matricula : String[10]; // Matricula
|
||||
LetraQ : String[10]; // Letra Q
|
||||
KilosSP : Real; // Kilos SP
|
||||
KilosDescargados : Real; // Cantidad
|
||||
DensidadMedia : LReal; // Densidad Media
|
||||
TempMediaDescarga : LReal; // Temperatura media en descarga
|
||||
TempMediaEnfriamiento : LReal; // Temperatura media enfriamiento
|
||||
EmpujeRealizado : Bool; // Empuje realizado
|
||||
AclaradoRealizado : Bool; // Aclarado realizado
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
GuardarSQL : Bool;
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
Mux : "UDT_ZC_MUX"; // Variable Mux
|
||||
Informe : Array[*] of "UDT_ZC_INF_CPR_PROD"; // Informes de compacto
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
s_OrdenGuardarDatos : Bool; // Orden adquirir datos de informes
|
||||
s_OrdenGuardarFechaInicio : Bool; // Orden guardar fecha de inicio y dezplazar informes
|
||||
END_VAR
|
||||
VAR
|
||||
s_OrdenGuardarFechaFin : Bool; // Orden guardar fecha de fin
|
||||
s_OrdenBorrarInforme : Bool; // Orden borrar informe
|
||||
s_NumeroBorrado : Int; // -1= Todos / Valor= Numero de registro
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
s_P_Trig_TomarFechaInicio : Bool; // Pulso
|
||||
s_P_Trig_TomarFechaFin : Bool; // Pulso
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int; // Variable para bucles FOR
|
||||
t_dummyInt : Int;
|
||||
t_IndiceSuperior : Int; // Indice superior del array
|
||||
t_IndiceInferior : Int; // Indice inferior del array
|
||||
t_InformeVacio : "UDT_ZC_INF_CPR_PROD";
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
ACTUAL : Int := 1;
|
||||
TIPO_DESCARGA_PARCIAL : Int := 1; // TIPO DE PROCESO DESCARGA PARCIAL
|
||||
TIPO_DESCARGA_TOTAL : Int := 2; // TIPO DE PROCESO DESCARGA TOTAL
|
||||
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 funcion para la gestión de informes de descargas de compacto de recepcion.
|
||||
|
||||
En ella se realizan las siguientes acciones:
|
||||
|
||||
- Cálculo dinámico de indices de array de informes.
|
||||
- Gestion de ordenes de inicio y fin informe.
|
||||
- Desplazamiento y captura de datos de informe.
|
||||
- Borrado de informes.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_MUX`, `UDT_ZC_INF_CPR_PROD` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 00.00.01 | 01.08.2023 | (HCR) | Primera version. |
|
||||
| 00.00.02 | 16.04.2024 | (ABH) | Se cambian los nombre a variables para estandarizar. |
|
||||
| 01.00.02 | 13.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LIMITES_Y_MULTIPLEXADO
|
||||
|
||||
// Calculo limites array de informes
|
||||
#t_IndiceInferior := DINT_TO_INT(LOWER_BOUND(ARR := #Informe, DIM := 1));
|
||||
#t_IndiceSuperior := DINT_TO_INT(UPPER_BOUND(ARR := #Informe, DIM := 1));
|
||||
|
||||
// Si no hay informes configurados, salimos inmediatamente.
|
||||
IF #t_IndiceInferior <= 0 THEN
|
||||
#Mux.Index := 0;
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
// Limites multiplexado
|
||||
IF #Mux.Index < 1 THEN
|
||||
#Mux.Index := 0;
|
||||
END_IF;
|
||||
IF #Mux.Index > #t_IndiceSuperior THEN
|
||||
#Mux.Index := #t_IndiceSuperior;
|
||||
END_IF;
|
||||
|
||||
END_REGION LIMITES_Y_MULTIPLEXADO
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION ORDEN_INICIO_FIN
|
||||
|
||||
// Orden de inicio
|
||||
IF #GuardarDatos AND NOT #s_P_Trig_TomarFechaInicio THEN
|
||||
#s_OrdenGuardarFechaInicio := TRUE;
|
||||
#s_OrdenGuardarDatos := TRUE;
|
||||
END_IF;
|
||||
|
||||
// Orden de fin
|
||||
#GuardarSQL := FALSE;
|
||||
IF #FinGuardarDatos AND NOT #s_P_Trig_TomarFechaFin THEN
|
||||
#s_OrdenGuardarFechaFin := TRUE;
|
||||
#GuardarSQL := TRUE;
|
||||
END_IF;
|
||||
|
||||
// Estados anteriores
|
||||
#s_P_Trig_TomarFechaInicio := #GuardarDatos;
|
||||
#s_P_Trig_TomarFechaFin := #FinGuardarDatos;
|
||||
|
||||
END_REGION ORDEN_INICIO_FIN
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION ADQUISICION_DE_DATOS
|
||||
|
||||
// Con flanco de guardar datos fecha de inicio, desplazamos los registros y almacenamos la fecha de inicio
|
||||
IF #s_OrdenGuardarFechaInicio THEN
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe, COUNT := INT_TO_UDINT(#t_IndiceSuperior - 1), SRC_INDEX := 0, DEST_INDEX := 1, DEST => #Informe);
|
||||
|
||||
// Tomar valor de fecha de inicio
|
||||
#Informe[#ACTUAL].FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaActual);
|
||||
#s_OrdenGuardarFechaInicio := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Tomar datos
|
||||
IF #s_OrdenGuardarDatos THEN
|
||||
#Informe[#ACTUAL].Descarga.TipoProceso := #TipoProceso;
|
||||
#Informe[#ACTUAL].Descarga.Destino := #Destino;
|
||||
IF #TipoProceso = #TIPO_DESCARGA_PARCIAL OR #TipoProceso = #TIPO_DESCARGA_TOTAL THEN
|
||||
#Informe[#ACTUAL].Descarga.Producto := #Producto;
|
||||
#Informe[#ACTUAL].Descarga.Producto1Destino := #Producto1Destino;
|
||||
#Informe[#ACTUAL].Descarga.Producto2Destino := #Producto2Destino;
|
||||
#Informe[#ACTUAL].Descarga.KilosSP := #KilosSP;
|
||||
#Informe[#ACTUAL].Descarga.KilosDescargados := #KilosDescargados;
|
||||
#Informe[#ACTUAL].Descarga.DensidadMedia := #DensidadMedia;
|
||||
#Informe[#ACTUAL].Descarga.TemperaturaMediaDescarga := #TempMediaDescarga;
|
||||
#Informe[#ACTUAL].Descarga.TemperaturaMediaEnfriamiento := #TempMediaEnfriamiento;
|
||||
#Informe[#ACTUAL].Descarga.Nombre := #Nombre;
|
||||
#Informe[#ACTUAL].Descarga.Matricula := #Matricula;
|
||||
#Informe[#ACTUAL].Descarga.LetraQ := #LetraQ;
|
||||
END_IF;
|
||||
#Informe[#ACTUAL].Descarga.EmpujeRealizado := #EmpujeRealizado;
|
||||
#Informe[#ACTUAL].Descarga.AclaradoRealizado := #AclaradoRealizado;
|
||||
END_IF;
|
||||
|
||||
// Con flanco de guardar datos fecha de fin almacenamos la fecha de fin y resetemos guardar datos
|
||||
IF #s_OrdenGuardarFechaFin THEN
|
||||
#Informe[#ACTUAL].FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaActual);
|
||||
#s_OrdenGuardarDatos := FALSE;
|
||||
#s_OrdenGuardarFechaFin := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION ADQUISICION_DE_DATOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION BORRADO_INFORMES
|
||||
|
||||
// Borrado de todos los registros
|
||||
IF #s_OrdenBorrarInforme THEN
|
||||
IF #s_NumeroBorrado = -1 OR #s_NumeroBorrado = 0 THEN
|
||||
|
||||
// Borrado total
|
||||
FOR #for_i := 1 TO #t_IndiceSuperior DO
|
||||
#Informe[#for_i] := #t_InformeVacio;
|
||||
END_FOR;
|
||||
|
||||
ELSIF #s_NumeroBorrado >= 1 AND #s_NumeroBorrado < #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado registro especifico
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe,
|
||||
COUNT := INT_TO_UDINT(#t_IndiceSuperior - #s_NumeroBorrado),
|
||||
SRC_INDEX := #s_NumeroBorrado,
|
||||
DEST_INDEX := #s_NumeroBorrado - 1,
|
||||
DEST => #Informe);
|
||||
|
||||
// Borrado del ultimo registro
|
||||
#Informe[#t_IndiceSuperior] := #t_InformeVacio;
|
||||
|
||||
ELSIF #s_NumeroBorrado = #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado de ultimo registro
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
END_IF;
|
||||
|
||||
#s_OrdenBorrarInforme := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
|
||||
END_REGION BORRADO_INFORMES
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
FUNCTION_BLOCK "FB15052_ZC_INF_PROD_MEM"
|
||||
TITLE = FB15052_ZC_INF_PROD_MEM
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de gestion para adquisicion de datos para informe de produccion maquina membranas
|
||||
VAR_INPUT
|
||||
OrdenInicioInforme { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Orden inicio informe
|
||||
OrdenFinInforme : Bool; // Orden fin informe
|
||||
EnProduccion : Bool; // En produccion
|
||||
FechaHoraActual {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL; // Fecha y hora actual
|
||||
Producto : Int; // Producto
|
||||
DestinoConcentrado : Int; // Destino concentrado
|
||||
DestinoPermeado : Int; // Destino permeado
|
||||
LitrosEntrada : LReal; // Totalizador litros Entrada
|
||||
LitrosConcentrado : LReal; // Totalizador litros Concentrado
|
||||
Brix : LReal; // Media Brix en produccion
|
||||
Fcv : Real; // Media FCV En produccion
|
||||
TempEntrada : LReal; // Media temperatura entrada
|
||||
TempConcentrado : LReal; // Media temperatura concentrado
|
||||
TempPermeado : LReal; // Media temperatura permeado
|
||||
TiempoProduccion : "UDT_ZC_CONTADOR_TIEMPO"; // Tiempo Produccion
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
Informe : Array[*] of "UDT_ZC_INF_PROD_MEM";
|
||||
END_VAR
|
||||
|
||||
VAR
|
||||
s_OrdenInicioInforme { S7_SetPoint := 'True'} : Bool; // Orden inicio informe
|
||||
s_OrdenFinInforme { S7_SetPoint := 'True'} : Bool; // Orden fin informe
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
s_oldInicio { S7_SetPoint := 'True'} : Bool; // Estado anterior inicio
|
||||
s_oldFin { S7_SetPoint := 'True'} : Bool; // Estado anterior fin
|
||||
END_VAR
|
||||
VAR
|
||||
s_OrdenBorrarInforme : Bool; // Orden borrar informe
|
||||
s_NumeroBorrado : Int; // -1= Todos / Valor= Numero de registro
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
t_dummyInt : Int;
|
||||
t_IndiceSuperior : Int; // Indice superior del array
|
||||
t_IndiceInferior : Int; // Indice inferior del array
|
||||
t_InformeVacio : "UDT_ZC_INF_PROD_MEM";
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
ACTUAL : Int := 1;
|
||||
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
|
||||
Bloque de funcion que implementa la gestión de los datos de informe de producción de una máquina de membranas, manteniendo un histórico de hasta `#N_REGISTROS` producciones con todos los datos relevantes del proceso (volúmenes, Brix, FCV, temperaturas, tiempos, destinos y producto) para su trazabilidad y consulta desde el sistema de supervisión.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Detección de flanco ascendente en las órdenes `#OrdenInicioInforme` y `#OrdenFinInforme` mediante las variables estáticas `#s_P_Trig_Inicio` y `#s_P_Trig_Fin`, generando los pulsos internos `#s_OrdenInicioInforme` y `#s_OrdenFinInforme`.
|
||||
- Inicialización de informe: al recibir `#s_OrdenInicioInforme` se desplazan los informes existentes una posición hacia abajo mediante `MOVE_BLK_VARIANT`, se reinicializan los campos del nuevo informe activo (`#Informe[#ACTUAL]`: fechas, tiempo de producción, destinos, producto, litros, Brix, FCV y temperaturas) y se almacena la fecha/hora de inicio mediante la conversión realizada por `FC15005_ZC_DTL_TO_ZC_FECHA`.
|
||||
- Datos en curso: mientras `#EnProduccion` está activo, se copian en `#Informe[#ACTUAL]` los valores de proceso en tiempo real: tiempo de producción, destinos de concentrado y permeado, código de producto, litros (entrada, concentrado y permeado por diferencia), Brix, FCV y las tres temperaturas (concentrado, permeado y entrada), aplicando `LREAL_TO_REAL` para adaptar la precisión al tipo de dato del UDT.
|
||||
- Fin de informe: al detectar `#s_OrdenFinInforme` se registra la fecha/hora de fin en `#Informe[#ACTUAL].FechaFin`.
|
||||
- Borrado masivo: la entrada `#s_Borrar` permite limpiar completamente todos los registros del array, inicializando fechas, tiempos, litros, Brix, FCV, temperatura de concentrado y código de producto a sus valores neutros. La propia variable de orden se autodesactiva tras la operación.
|
||||
|
||||
> **Restricciones:** PLC serie 1200/1500.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_CONTADOR_TIEMPO`, `UDT_ZC_INF_PROD_MEM` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 24.05.2023 | (ABH) | Primera versión. |
|
||||
| 01.00.01 | 16.02.2024 | (ABH) | Cambios en datos de REAL a LREAL para coincidir con UDT. |
|
||||
| 01.00.02 | 23.05.2024 | (HCR) | Se añaden temperaturas de entrada, destinos concentrado y destinos permeado. |
|
||||
| 01.00.03 | 03.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LIMITES
|
||||
|
||||
// Calculo limites array de informes
|
||||
#t_IndiceInferior := DINT_TO_INT(LOWER_BOUND(ARR := #Informe, DIM := 1));
|
||||
#t_IndiceSuperior := DINT_TO_INT(UPPER_BOUND(ARR := #Informe, DIM := 1));
|
||||
|
||||
// Si no hay informes configurados, salimos inmediatamente.
|
||||
IF #t_IndiceInferior <= 0 THEN
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
END_REGION LIMITES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_ORDENES
|
||||
|
||||
// Orden de inicio
|
||||
#s_OrdenInicioInforme := #OrdenInicioInforme AND NOT #s_oldInicio;
|
||||
|
||||
// Orden de fin
|
||||
#s_OrdenFinInforme := #OrdenFinInforme AND NOT #s_oldFin;
|
||||
|
||||
// Estados anteriores
|
||||
#s_oldInicio := #OrdenInicioInforme;
|
||||
#s_oldFin := #OrdenFinInforme;
|
||||
|
||||
END_REGION GESTION_ORDENES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION INICIALIZACION
|
||||
|
||||
// Con flanco de inicio informe, desplazamos los registros, reinicializamos los datos y almacenamos la fecha y hora de inicio, todo en la poisicion 1
|
||||
IF #s_OrdenInicioInforme THEN
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe, COUNT := INT_TO_UDINT(#t_IndiceSuperior - 1), SRC_INDEX := 0, DEST_INDEX := 1, DEST => #Informe);
|
||||
|
||||
// Reinicializacion de los datos
|
||||
#Informe[#ACTUAL] := #t_InformeVacio;
|
||||
|
||||
// Guardado de fecha y hora actual
|
||||
#Informe[#ACTUAL].FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(FechaDTL := #FechaHoraActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION INICIALIZACION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
// Se guardan los datos durante la produccion
|
||||
IF #EnProduccion THEN
|
||||
|
||||
#Informe[#ACTUAL].TiempoProduccion.Hora := #TiempoProduccion.Hora;
|
||||
#Informe[#ACTUAL].TiempoProduccion.Minuto := #TiempoProduccion.Minuto;
|
||||
#Informe[#ACTUAL].TiempoProduccion.Segundo := #TiempoProduccion.Segundo;
|
||||
|
||||
#Informe[#ACTUAL].DestinoConcentrado := #DestinoConcentrado;
|
||||
#Informe[#ACTUAL].DestinoPermeado := #DestinoPermeado;
|
||||
#Informe[#ACTUAL].Producto := #Producto;
|
||||
|
||||
#Informe[#ACTUAL].LitrosEntrada := LREAL_TO_REAL(#LitrosEntrada);
|
||||
#Informe[#ACTUAL].LitrosConcentrado := LREAL_TO_REAL(#LitrosConcentrado);
|
||||
#Informe[#ACTUAL].LitrosPermeado := LREAL_TO_REAL(#LitrosEntrada - #LitrosConcentrado);
|
||||
|
||||
#Informe[#ACTUAL].Brix := LREAL_TO_REAL(#Brix);
|
||||
#Informe[#ACTUAL].FCV := #Fcv;
|
||||
|
||||
#Informe[#ACTUAL].TempConcentrado := LREAL_TO_REAL(#TempConcentrado);
|
||||
#Informe[#ACTUAL].TempPermeado := LREAL_TO_REAL(#TempPermeado);
|
||||
#Informe[#ACTUAL].TempEntrada := LREAL_TO_REAL(#TempEntrada);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION FIN_INFORME
|
||||
|
||||
// Se guardan los datos durante la produccion
|
||||
IF #s_OrdenFinInforme THEN
|
||||
|
||||
// Guardado de fecha y hora actual
|
||||
#Informe[#ACTUAL].FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(FechaDTL := #FechaHoraActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION FIN_INFORME
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION BORRADO_DATOS
|
||||
|
||||
// Borrado de todos los registros
|
||||
IF #s_OrdenBorrarInforme THEN
|
||||
IF #s_NumeroBorrado = -1 OR #s_NumeroBorrado = 0 THEN
|
||||
|
||||
FOR #for_i := 1 TO #t_IndiceSuperior DO
|
||||
#Informe[#for_i] := #t_InformeVacio;
|
||||
END_FOR;
|
||||
|
||||
ELSIF #s_NumeroBorrado >= 1 AND #s_NumeroBorrado < #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado registro especifico
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe,
|
||||
COUNT := INT_TO_UDINT(#t_IndiceSuperior - #s_NumeroBorrado),
|
||||
SRC_INDEX := #s_NumeroBorrado,
|
||||
DEST_INDEX := #s_NumeroBorrado - 1,
|
||||
DEST => #Informe);
|
||||
|
||||
// Borrado del ultimo registro
|
||||
#Informe[#t_IndiceSuperior] := #t_InformeVacio;
|
||||
|
||||
ELSIF #s_NumeroBorrado = #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado de ultimo registro
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
END_IF;
|
||||
|
||||
#s_OrdenBorrarInforme := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION BORRADO_DATOS
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
FUNCTION_BLOCK "FB15053_ZC_INF_LIMP_MAQ"
|
||||
TITLE = FB15053_ZC_INF_LIMP_MAQ
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de gestion para adquisicion de datos para informe de limpieza de maquinas
|
||||
VAR_INPUT
|
||||
EnLimpieza : Bool; // En limpieza
|
||||
LimpBasica1 : Bool; // En limpieza basica 1
|
||||
LimpAcida : Bool; // En limpieza acida
|
||||
LimpBasica2 : Bool; // En limpieza basica 2
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
FechaHoraActual {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL; // Fecha y hora actual
|
||||
TempBasica1 : LReal; // Temperatura basica 1
|
||||
CTLimpBasica1 : LReal; // Conductividad limpieza basica 1
|
||||
CTEnjBasica1 : LReal; // Conductividad enjuague basica 1
|
||||
PorcentajeQRefBasica1 : LReal; // Porcentaje Q Referencia basica 1
|
||||
TempAcida : LReal; // Temperatura acida
|
||||
CTLimpAcida : LReal; // Conductividad limpieza acida
|
||||
CTEnjAcida : LReal; // Conductividad enjuague acida
|
||||
PorcentajeQRefAcida : LReal; // Porcentaje Q Referencia acida
|
||||
TempBasica2 : LReal; // Temperatura basica 2
|
||||
CTLimpBasica2 : LReal; // Conductividad limpieza basica 2
|
||||
CTEnjBasica2 : LReal; // Conductividad enjuague basica 2
|
||||
PorcentajeQRefBasica2 : LReal; // Porcentaje Q Referencia basica 2
|
||||
TipoLimpieza : Int; // Tipo de limpieza
|
||||
TiempoLimpieza : "UDT_ZC_CONTADOR_TIEMPO"; // Tiempo de limpieza
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
Informe : Array[*] of "UDT_ZC_INF_LIMP_MAQ"; // Informe
|
||||
END_VAR
|
||||
|
||||
VAR
|
||||
s_OrdenInicioInforme { S7_SetPoint := 'True'} : Bool; // Orden inicio informe
|
||||
s_OrdenFinInforme { S7_SetPoint := 'True'} : Bool; // Orden fin informe
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
s_oldInicio { S7_SetPoint := 'True'} : Bool; // Estado anterior inicio
|
||||
s_oldFin { S7_SetPoint := 'True'} : Bool; // Estado anterior fin
|
||||
END_VAR
|
||||
VAR
|
||||
s_OrdenBorrarInforme : Bool; // Orden borrar informe
|
||||
s_NumeroBorrado : Int; // -1= Todos / Valor= Numero de registro
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
TiempoRecircBasica1 : Int; // Tiempo en recirculacion basica 1
|
||||
TiempoRecircAcida : Int; // Tiempo en recirculacion acida
|
||||
TiempoRecircBasica2 : Int; // Tiempo en recirculacion basica 2
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
t_dummyInt : Int;
|
||||
t_IndiceSuperior : Int; // Indice superior del array
|
||||
t_IndiceInferior : Int; // Indice inferior del array
|
||||
t_InformeVacio : "UDT_ZC_INF_LIMP_MAQ";
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
ACTUAL : Int := 1;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2025 - 2026
|
||||
//=======================================================================
|
||||
(*
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
Bloque de funcion que implementa la gestión de los datos de informe de limpieza de la máquina, manteniendo un histórico de hasta `#N_REGISTROS` limpiezas con todos los datos relevantes de cada fase (básica 1, ácida y básica 2): tiempo total, tipo de limpieza, temperaturas, conductividades de limpieza y enjuague, porcentaje de caudal de referencia y tiempo de recirculación por etapa. Se utiliza en máquinas de membranas para trazabilidad y consulta desde el sistema de supervisión.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Detección de flanco ascendente y descendente en `#EnLimpieza` mediante las variables estáticas `#s_P_Trig_Inicio` y `#s_P_Trig_Fin`, generando el pulso de inicio `#s_OrdenInicioInforme` y el de fin `#s_OrdenFinInforme`.
|
||||
- Inicialización del informe: al recibir `#s_OrdenInicioInforme` se desplazan los informes existentes una posición hacia abajo mediante `MOVE_BLK_VARIANT`, se reinicializan a cero los contadores internos de recirculación (`#TiempoRecircBasica1`, `#TiempoRecircAcida`, `#TiempoRecircBasica2`) y los campos del nuevo informe activo (`#Informe[1]`: tipo de limpieza, tiempos de recirculación por fase, tiempo total, temperaturas, conductividades y porcentajes de caudal de referencia de cada fase). Se almacena la fecha/hora de inicio mediante la conversión realizada por `FC15005_ZC_DTL_TO_ZC_FECHA`.
|
||||
- Datos en curso: mientras `#EnLimpieza` está activo, se incrementan los contadores de tiempo de recirculación de cada fase (`#TiempoRecircBasica1`, `#TiempoRecircAcida`, `#TiempoRecircBasica2`) cuando el pulso de 1 segundo y el flag de fase correspondiente (`#LimpBasica1`, `#LimpAcida`, `#LimpBasica2`) están activos, y se copian en `#Informe[1]` los valores de proceso en tiempo real: tipo de limpieza, tiempo total de limpieza, temperatura, conductividad de limpieza, conductividad de enjuague, porcentaje de caudal de referencia y tiempo de recirculación para cada una de las tres fases.
|
||||
- Fin de informe: al detectar `#s_OrdenFinInforme` se registra la fecha/hora de fin en `#Informe[1].FechaFin`.
|
||||
- Borrado masivo: la entrada `#s_Borrar` permite limpiar completamente todos los registros del array, inicializando fechas, tipo de limpieza, tiempos de recirculación, tiempo total, temperaturas, conductividades y porcentajes de caudal de referencia a sus valores neutros. La propia variable de orden se autodesactiva tras la operación.
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_CONTADOR_TIEMPO`, `ZC_INF_LIMP_MAQ` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 10.11.2025 | (CNR) | Primera versión. |
|
||||
| 01.00.01 | 03.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LIMITES
|
||||
|
||||
// Calculo limites array de informes
|
||||
#t_IndiceInferior := DINT_TO_INT(LOWER_BOUND(ARR := #Informe, DIM := 1));
|
||||
#t_IndiceSuperior := DINT_TO_INT(UPPER_BOUND(ARR := #Informe, DIM := 1));
|
||||
|
||||
// Si no hay informes configurados, salimos inmediatamente.
|
||||
IF #t_IndiceInferior <= 0 THEN
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
END_REGION LIMITES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_ORDENES
|
||||
|
||||
// Orden inicio produccion
|
||||
#s_OrdenInicioInforme := #EnLimpieza AND NOT #s_oldInicio;
|
||||
|
||||
// Orden fin produccion
|
||||
#s_OrdenFinInforme := NOT #EnLimpieza AND #s_oldFin;
|
||||
|
||||
// Estados anteriores
|
||||
#s_oldInicio := #EnLimpieza;
|
||||
#s_oldFin := #EnLimpieza;
|
||||
|
||||
END_REGION GESTION_ORDENES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION INICIALIZACION
|
||||
|
||||
// Con flanco de inicio informe, desplazamos los registros, reinicializamos los datos y almacenamos la fecha y hora de inicio, todo en la poisicion 1
|
||||
IF #s_OrdenInicioInforme THEN
|
||||
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe, COUNT := INT_TO_UDINT(#t_IndiceSuperior - 1), SRC_INDEX := 0, DEST_INDEX := 1, DEST => #Informe);
|
||||
|
||||
// Reinicializacion de los datos
|
||||
#Informe[#ACTUAL] := #t_InformeVacio;
|
||||
|
||||
#TiempoRecircBasica1 := 0;
|
||||
#TiempoRecircAcida := 0;
|
||||
#TiempoRecircBasica2 := 0;
|
||||
|
||||
// Guardado de fecha y hora actual
|
||||
#Informe[#ACTUAL].FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(FechaDTL := #FechaHoraActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION INICIALIZACION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
// Se guardan los datos durante la produccion
|
||||
IF #EnLimpieza THEN
|
||||
|
||||
IF #Pulso1Seg AND #LimpBasica1 THEN
|
||||
#TiempoRecircBasica1 += 1;
|
||||
END_IF;
|
||||
IF #Pulso1Seg AND #LimpAcida THEN
|
||||
#TiempoRecircAcida += 1;
|
||||
END_IF;
|
||||
IF #Pulso1Seg AND #LimpBasica2 THEN
|
||||
#TiempoRecircBasica2 += 1;
|
||||
END_IF;
|
||||
|
||||
#Informe[#ACTUAL].TipoLimpieza := #TipoLimpieza;
|
||||
|
||||
#Informe[#ACTUAL].TiempoLimpieza.Hora := #TiempoLimpieza.Hora;
|
||||
#Informe[#ACTUAL].TiempoLimpieza.Minuto := #TiempoLimpieza.Minuto;
|
||||
#Informe[#ACTUAL].TiempoLimpieza.Segundo := #TiempoLimpieza.Segundo;
|
||||
|
||||
#Informe[#ACTUAL].TempBasica1 := #TempBasica1;
|
||||
#Informe[#ACTUAL].CTLimpBasica1 := #CTLimpBasica1;
|
||||
#Informe[#ACTUAL].CTEnjBasica1 := #CTEnjBasica1;
|
||||
#Informe[#ACTUAL].PorcentajeQRefBasica1 := #PorcentajeQRefBasica1;
|
||||
#Informe[#ACTUAL].TiempoRecircBasica1 := #TiempoRecircBasica1;
|
||||
|
||||
#Informe[#ACTUAL].TempAcida := #TempAcida;
|
||||
#Informe[#ACTUAL].CTLimpAcida := #CTLimpAcida;
|
||||
#Informe[#ACTUAL].CTEnjAcida := #CTEnjAcida;
|
||||
#Informe[#ACTUAL].PorcentajeQRefAcida := #PorcentajeQRefAcida;
|
||||
#Informe[#ACTUAL].TiempoRecircAcida := #TiempoRecircAcida;
|
||||
|
||||
#Informe[#ACTUAL].TempBasica2 := #TempBasica2;
|
||||
#Informe[#ACTUAL].CTLimpBasica2 := #CTLimpBasica2;
|
||||
#Informe[#ACTUAL].CTEnjBasica2 := #CTEnjBasica2;
|
||||
#Informe[#ACTUAL].PorcentajeQRefBasica2 := #PorcentajeQRefBasica2;
|
||||
#Informe[#ACTUAL].TiempoRecircBasica2 := #TiempoRecircBasica2;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION FIN_INFORME
|
||||
|
||||
// Se guardan los datos durante la produccion
|
||||
IF #s_OrdenFinInforme THEN
|
||||
|
||||
// Guardado de fecha y hora actual
|
||||
#Informe[#ACTUAL].FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(FechaDTL := #FechaHoraActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION FIN_INFORME
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION BORRADO_DATOS
|
||||
|
||||
// Borrado de todos los registros
|
||||
IF #s_OrdenBorrarInforme THEN
|
||||
IF #s_NumeroBorrado = -1 OR #s_NumeroBorrado = 0 THEN
|
||||
|
||||
FOR #for_i := 1 TO #t_IndiceSuperior DO
|
||||
#Informe[#for_i] := #t_InformeVacio;
|
||||
END_FOR;
|
||||
|
||||
ELSIF #s_NumeroBorrado >= 1 AND #s_NumeroBorrado < #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado registro especifico
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Informe,
|
||||
COUNT := INT_TO_UDINT(#t_IndiceSuperior - #s_NumeroBorrado),
|
||||
SRC_INDEX := #s_NumeroBorrado,
|
||||
DEST_INDEX := #s_NumeroBorrado - 1,
|
||||
DEST => #Informe);
|
||||
|
||||
// Borrado del ultimo registro
|
||||
#Informe[#t_IndiceSuperior] := #t_InformeVacio;
|
||||
|
||||
ELSIF #s_NumeroBorrado = #t_IndiceSuperior THEN
|
||||
|
||||
// Borrado de ultimo registro
|
||||
#Informe[#s_NumeroBorrado] := #t_InformeVacio;
|
||||
|
||||
END_IF;
|
||||
|
||||
#s_OrdenBorrarInforme := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION BORRADO_DATOS
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+477
@@ -0,0 +1,477 @@
|
||||
FUNCTION "FC11_ZC_INF_GESTOR" : Void
|
||||
TITLE = FC11_ZC_GESTOR_INFORMES
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Funcion para gestion de informes
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int; // Variable para bucles FOR
|
||||
t_PosicionRegistro : Int; // Posicion del registro encontrado en el buffer
|
||||
t_RegistroEncontrado : Bool; // Indicador de registro encontrado
|
||||
t_RetVal : Int; // Variable para su uso en programa
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
REPOSO : Int := 0; // Etapa reposo
|
||||
ESPERA_ENTRE_AVISOS : Int := 10; // Etapa espera entre avisos
|
||||
LANZAR_AVISO : Int := 20; // Etapa lanzar aviso
|
||||
ESPERA_CONFIRMACION : Int := 30; // Etapa espera confirmacion
|
||||
FALLO : Int := 40; // Etapa fallo
|
||||
BORRAR_DATOS : Int := 50; // Etapa borrar datos
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2024 - 2024
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función para la gestión e interfaz de escritura de informes hacia el sistema SCADA/HMI mediante una máquina de estados y la lectura de un buffer.
|
||||
|
||||
Las tareas que realiza son las siguientes:
|
||||
|
||||
- Extracción de datos del buffer: Búsqueda inversa del registro más antiguo pendiente de envío evaluando la condición `Registrar` = 1 mediante un bucle `FOR`.
|
||||
- Transferencia del registro a la estructura estática `Gestion.Datos` y generación de un `Id` único basado en la fecha y hora actual.
|
||||
- Limpieza inmediata de todas las variables (Booleanos, Reales, Enteros, Fechas y Strings) en la posición original del buffer.
|
||||
- Ejecución de la etapa **REPOSO**: Activación de la secuencia ante la orden `OrdenIniciar`, siempre que se detecte conexión con el SCADA y la habilitación general esté activa.
|
||||
- Ejecución de la etapa **ESPERA_ENTRE_AVISOS**: Temporización basada en pulsos de 1 segundo (`Pulso1Seg`) antes de un reintento. Deriva a fallo si se supera el máximo de intentos.
|
||||
- Ejecución de la etapa **LANZAR_AVISO**: Activación de la señal `Aviso.Registrar` hacia el SCADA y paso a espera tras cumplirse el tiempo parametrizado.
|
||||
- Ejecución de la etapa **ESPERA_CONFIRMACION**: Monitoreo de la respuesta del sistema superior. Si `Aviso.Estado` es igual a 4, el envío es exitoso. Si hay error (estado 12) o agotamiento de tiempo, se incrementa el contador de intentos y se repite el ciclo.
|
||||
- Ejecución de la etapa **FALLO**: Generación de una traza de sistema (`TRZ_CAT_1_SYS`) registrando el código de error `TRZ_SYS_INF_ERR` ante la imposibilidad de entrega del informe.
|
||||
- Ejecución de la etapa **BORRAR_DATOS**: Reseteo íntegro de la estructura `Gestion.Datos` para preparar el sistema para el próximo ciclo de comunicación y retorno al estado de reposo.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 30.07.2024 | (ABH) | Primera version. |
|
||||
| 01.00.01 | 11.09.2024 | (ABH) | Se añade la generacion de ID con fecha y hora en el momento del guardar en SQL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_INFORMES
|
||||
|
||||
// =============================================================================
|
||||
// COPIAMOS EL ULTIMO REGISTRO (El mas antiguo) A LA VARIABLE REGISTRO QUE ES LA
|
||||
// ENCARGADA DE COMUNICARLA CON EL SCADA/HMI
|
||||
IF "DB11_INF".Gestion.HabilitacionGeneral AND "DB11_INF".Gestion.Datos.Registrar = 0 AND #Pulso1Seg THEN
|
||||
|
||||
// =============================================================================
|
||||
// Buscamos el ultimo registro
|
||||
FOR #for_i := "N_MAX_INF_BUFFER" TO 0 BY -1 DO
|
||||
|
||||
// =============================================================================
|
||||
// Registro encontrado
|
||||
IF "DB11_INF".Buffer[#for_i].Registrar = 1 THEN
|
||||
#t_PosicionRegistro := #for_i;
|
||||
#t_RegistroEncontrado := TRUE;
|
||||
EXIT;
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
// =============================================================================
|
||||
// Si hemos encontrado el registro, copiamos a variable estatica
|
||||
IF #t_RegistroEncontrado THEN
|
||||
|
||||
// =============================================================================
|
||||
// Copiamos el los datos de la traza a variable estatica para tratarla
|
||||
"DB11_INF".Gestion.Datos := "DB11_INF".Buffer[#t_PosicionRegistro];
|
||||
"DB11_INF".Gestion.Datos.Id := "FC15006_ZC_DTL_TO_STRING"(FechaDTL := "DB1_SYS".FechaHoraActual, Formato := 3);
|
||||
|
||||
// =============================================================================
|
||||
// Quitamos el registro del buffer
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Registrar := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Id := '';
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Tipo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Codigo := '';
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Ano := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Mes := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Dia := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.DiaSemana := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Hora := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Minuto := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.Segundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_1.NanoSegundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Ano := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Mes := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Dia := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.DiaSemana := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Hora := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Minuto := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.Segundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_2.NanoSegundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Ano := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Mes := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Dia := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.DiaSemana := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Hora := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Minuto := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.Segundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Fecha_3.NanoSegundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_1 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_2 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_3 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_4 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_5 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_6 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_7 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_8 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_9 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_10 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_11 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_12 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_13 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_14 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_15 := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_1 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_2 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_3 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_4 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_5 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_6 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_7 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_8 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_9 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_10 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_11 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_12 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_13 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_14 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_15 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_16 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_17 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_18 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_19 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_20 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_21 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_22 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_23 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_24 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_25 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_26 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_27 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_28 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_29 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_30 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_31 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Bool_32 := FALSE;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_1 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_2 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_3 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_4 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_5 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_6 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_7 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_8 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_9 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_10 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_11 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_12 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_13 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_14 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_15 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_16 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_17 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_18 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_19 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Real_20 := 0.0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_1 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_2 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_3 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_4 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_5 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_6 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_7 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_8 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_9 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_10 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_11 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_12 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_13 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_14 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_15 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_16 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_17 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_18 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_19 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].Int_20 := 0;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Si existe registro a trazar, lanzamos la orden de iniciar la secuencia
|
||||
IF "DB11_INF".Gestion.Datos.Registrar = 1 AND "DB11_INF".Gestion.Etapa = #REPOSO AND "DB11_INF".Gestion.EstadoConexion THEN
|
||||
|
||||
// Lanzamos la orden de iniciar la secuencia de registro
|
||||
"DB11_INF".Gestion.OrdenIniciar := TRUE;
|
||||
|
||||
END_IF;
|
||||
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SECUENCIA_INFORME
|
||||
|
||||
|
||||
IF NOT "DB11_INF".Gestion.HabilitacionGeneral AND "DB11_INF".Gestion.Etapa <> #REPOSO THEN
|
||||
"DB11_INF".Gestion.Etapa := #BORRAR_DATOS;
|
||||
END_IF;
|
||||
|
||||
|
||||
CASE "DB11_INF".Gestion.Etapa OF
|
||||
|
||||
|
||||
// =============================================================================
|
||||
#REPOSO:
|
||||
IF "DB11_INF".Gestion.OrdenIniciar THEN
|
||||
"DB11_INF".Gestion.Etapa := #LANZAR_AVISO;
|
||||
"DB11_INF".Gestion.OrdenIniciar := FALSE;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := 0;
|
||||
"DB11_INF".Gestion.TiempoActual := 0;
|
||||
"DB11_INF".Gestion.Aviso.NumeroIntentosActual := 0;
|
||||
END_IF;
|
||||
|
||||
|
||||
|
||||
// =============================================================================
|
||||
#ESPERA_ENTRE_AVISOS:
|
||||
// Contador de tiempo de etapa
|
||||
IF #Pulso1Seg THEN
|
||||
"DB11_INF".Gestion.TiempoActual += 1;
|
||||
END_IF;
|
||||
// Tiempo maximo de espera
|
||||
IF ("DB11_INF".Gestion.TiempoActual >= "DB11_INF".Gestion.SP_Tiempo) THEN
|
||||
"DB11_INF".Gestion.TiempoActual := 0;
|
||||
"DB11_INF".Gestion.Etapa := #LANZAR_AVISO;
|
||||
END_IF;
|
||||
|
||||
// Si ya se ha alcanzado el numero maximo de intentos, generamos la traza
|
||||
IF "DB11_INF".Gestion.Aviso.NumeroIntentosActual >= "DB11_INF".Gestion.NumeroMaxIntentos THEN
|
||||
"DB11_INF".Gestion.Etapa := #FALLO;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := 0;
|
||||
END_IF;
|
||||
|
||||
|
||||
|
||||
// =============================================================================
|
||||
#LANZAR_AVISO:
|
||||
|
||||
IF #Pulso1Seg THEN
|
||||
"DB11_INF".Gestion.TiempoActual += 1;
|
||||
END_IF;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := TRUE;
|
||||
|
||||
|
||||
|
||||
IF ("DB11_INF".Gestion.TiempoActual >= "DB11_INF".Gestion.SP_Tiempo) THEN
|
||||
"DB11_INF".Gestion.Etapa := #ESPERA_CONFIRMACION;
|
||||
END_IF;
|
||||
|
||||
|
||||
// =============================================================================
|
||||
#ESPERA_CONFIRMACION:
|
||||
|
||||
IF #Pulso1Seg THEN
|
||||
"DB11_INF".Gestion.TiempoActual += 1;
|
||||
END_IF;
|
||||
|
||||
// Confirmacion desde SCADA OK
|
||||
IF "DB11_INF".Gestion.Aviso.Estado = 4 THEN
|
||||
"DB11_INF".Gestion.TiempoActual := 0;
|
||||
"DB11_INF".Gestion.Aviso.Estado := 0;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := FALSE;
|
||||
"DB11_INF".Gestion.Etapa := #BORRAR_DATOS;
|
||||
END_IF;
|
||||
|
||||
// Tiempo maximo de espera
|
||||
IF ("DB11_INF".Gestion.TiempoActual >= "DB11_INF".Gestion.SP_Tiempo)
|
||||
OR
|
||||
("DB11_INF".Gestion.Aviso.Estado = 12)
|
||||
THEN
|
||||
"DB11_INF".Gestion.TiempoActual := 0;
|
||||
"DB11_INF".Gestion.Aviso.Estado := 0;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := FALSE;
|
||||
"DB11_INF".Gestion.Etapa := #ESPERA_ENTRE_AVISOS;
|
||||
"DB11_INF".Gestion.Aviso.NumeroIntentosActual += 1;
|
||||
END_IF;
|
||||
|
||||
|
||||
// =============================================================================
|
||||
#BORRAR_DATOS:
|
||||
|
||||
"DB11_INF".Gestion.Datos.Registrar := 0;
|
||||
"DB11_INF".Gestion.Datos.Id := '';
|
||||
"DB11_INF".Gestion.Datos.Tipo := 0;
|
||||
"DB11_INF".Gestion.Datos.Codigo := '';
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Ano := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Mes := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Dia := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.DiaSemana := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Hora := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Minuto := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.Segundo := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_1.NanoSegundo := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Ano := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Mes := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Dia := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.DiaSemana := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Hora := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Minuto := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.Segundo := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_2.NanoSegundo := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Ano := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Mes := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Dia := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.DiaSemana := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Hora := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Minuto := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.Segundo := 0;
|
||||
"DB11_INF".Gestion.Datos.Fecha_3.NanoSegundo := 0;
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_1 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_2 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_3 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_4 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_5 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_6 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_7 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_8 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_9 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_10 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_11 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_12 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_13 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_14 :=
|
||||
"DB11_INF".Buffer[#t_PosicionRegistro].CodString_15 := 0;
|
||||
"DB11_INF".Gestion.Datos.Bool_1 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_2 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_3 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_4 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_5 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_6 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_7 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_8 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_9 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_10 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_11 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_12 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_13 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_14 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_15 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_16 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_17 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_18 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_19 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_20 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_21 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_22 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_23 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_24 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_25 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_26 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_27 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_28 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_29 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_30 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_31 :=
|
||||
"DB11_INF".Gestion.Datos.Bool_32 := FALSE;
|
||||
"DB11_INF".Gestion.Datos.Real_1 :=
|
||||
"DB11_INF".Gestion.Datos.Real_2 :=
|
||||
"DB11_INF".Gestion.Datos.Real_3 :=
|
||||
"DB11_INF".Gestion.Datos.Real_4 :=
|
||||
"DB11_INF".Gestion.Datos.Real_5 :=
|
||||
"DB11_INF".Gestion.Datos.Real_6 :=
|
||||
"DB11_INF".Gestion.Datos.Real_7 :=
|
||||
"DB11_INF".Gestion.Datos.Real_8 :=
|
||||
"DB11_INF".Gestion.Datos.Real_9 :=
|
||||
"DB11_INF".Gestion.Datos.Real_10 :=
|
||||
"DB11_INF".Gestion.Datos.Real_11 :=
|
||||
"DB11_INF".Gestion.Datos.Real_12 :=
|
||||
"DB11_INF".Gestion.Datos.Real_13 :=
|
||||
"DB11_INF".Gestion.Datos.Real_14 :=
|
||||
"DB11_INF".Gestion.Datos.Real_15 :=
|
||||
"DB11_INF".Gestion.Datos.Real_16 :=
|
||||
"DB11_INF".Gestion.Datos.Real_17 :=
|
||||
"DB11_INF".Gestion.Datos.Real_18 :=
|
||||
"DB11_INF".Gestion.Datos.Real_19 :=
|
||||
"DB11_INF".Gestion.Datos.Real_20 := 0.0;
|
||||
"DB11_INF".Gestion.Datos.Int_1 :=
|
||||
"DB11_INF".Gestion.Datos.Int_2 :=
|
||||
"DB11_INF".Gestion.Datos.Int_3 :=
|
||||
"DB11_INF".Gestion.Datos.Int_4 :=
|
||||
"DB11_INF".Gestion.Datos.Int_5 :=
|
||||
"DB11_INF".Gestion.Datos.Int_6 :=
|
||||
"DB11_INF".Gestion.Datos.Int_7 :=
|
||||
"DB11_INF".Gestion.Datos.Int_8 :=
|
||||
"DB11_INF".Gestion.Datos.Int_9 :=
|
||||
"DB11_INF".Gestion.Datos.Int_10 :=
|
||||
"DB11_INF".Gestion.Datos.Int_11 :=
|
||||
"DB11_INF".Gestion.Datos.Int_12 :=
|
||||
"DB11_INF".Gestion.Datos.Int_13 :=
|
||||
"DB11_INF".Gestion.Datos.Int_14 :=
|
||||
"DB11_INF".Gestion.Datos.Int_15 :=
|
||||
"DB11_INF".Gestion.Datos.Int_16 :=
|
||||
"DB11_INF".Gestion.Datos.Int_17 :=
|
||||
"DB11_INF".Gestion.Datos.Int_18 :=
|
||||
"DB11_INF".Gestion.Datos.Int_19 :=
|
||||
"DB11_INF".Gestion.Datos.Int_20 := 0;
|
||||
"DB11_INF".Gestion.Aviso.Registrar := 0;
|
||||
"DB11_INF".Gestion.Etapa := #REPOSO;
|
||||
|
||||
// =============================================================================
|
||||
#FALLO:
|
||||
|
||||
"FC8_ZC_TRZ_REGISTRO"(FechaHora := "DB1_SYS".FechaHoraActual,
|
||||
Registrar := 1,
|
||||
Categoria := "TRZ_CAT_1_SYS",
|
||||
User := '',
|
||||
CodInt_1 := "TRZ_SYS_INF_ERR",
|
||||
CodInt_2 := 0,
|
||||
CodInt_3 := 0,
|
||||
CodInt_4 := 0,
|
||||
CodInt_5 := 0,
|
||||
CodReal_1 := 0.0,
|
||||
CodReal_2 := 0.0);
|
||||
"DB11_INF".Gestion.Datos.Registrar := 0;
|
||||
"DB11_INF".Gestion.Etapa := #REPOSO;
|
||||
|
||||
END_CASE;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+365
@@ -0,0 +1,365 @@
|
||||
FUNCTION "FC12_ZC_INF_REGISTRO" : Void
|
||||
TITLE = FC12_ZC_INFORME_REGISTRO
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Funcion para almacenar una traza en el buffer de informes
|
||||
VAR_INPUT
|
||||
Registrar : USInt; // Orden registrar (0= no registrar / 1= registrar)
|
||||
Tipo : Int; // Tipo
|
||||
Codigo : String; // Codigo produccion
|
||||
Fecha_1_Ano : UInt; // Fecha 1 Año
|
||||
Fecha_1_Mes : USInt; // Fecha 1 Mes
|
||||
Fecha_1_Dia : USInt; // Fecha 1 Dia
|
||||
Fecha_1_DiaSemana : USInt; // Fecha 1 Dia de la semana
|
||||
Fecha_1_Hora : USInt; // Fecha 1 Hora
|
||||
Fecha_1_Minuto : USInt; // Fecha 1 Minuto
|
||||
Fecha_1_Segundo : USInt; // Fecha 1 Segundo
|
||||
Fecha_1_NanoSegundo : UDInt; // Fecha 1 Nanosegundo
|
||||
Fecha_2_Ano : UInt; // Fecha 2 Año
|
||||
Fecha_2_Mes : USInt; // Fecha 2 Mes
|
||||
Fecha_2_Dia : USInt; // Fecha 2 Dia
|
||||
Fecha_2_DiaSemana : USInt; // Fecha 2 Dia de la semana
|
||||
Fecha_2_Hora : USInt; // Fecha 2 Hora
|
||||
Fecha_2_Minuto : USInt; // Fecha 2 Minuto
|
||||
Fecha_2_Segundo : USInt; // Fecha 2 Segundo
|
||||
Fecha_2_NanoSegundo : UDInt; // Fecha 2 Nanosegundo
|
||||
Fecha_3_Ano : UInt; // Fecha 3 Año
|
||||
Fecha_3_Mes : USInt; // Fecha 3 Mes
|
||||
Fecha_3_Dia : USInt; // Fecha 3 Dia
|
||||
Fecha_3_DiaSemana : USInt; // Fecha 3 Dia de la semana
|
||||
Fecha_3_Hora : USInt; // Fecha 3 Hora
|
||||
Fecha_3_Minuto : USInt; // Fecha 3 Minuto
|
||||
Fecha_3_Segundo : USInt; // Fecha 3 Segundo
|
||||
Fecha_3_NanoSegundo : UDInt; // Fecha 3 Nanosegundo
|
||||
Fecha_4_Ano : UInt; // Fecha 4 Año
|
||||
Fecha_4_Mes : USInt; // Fecha 4 Mes
|
||||
Fecha_4_Dia : USInt; // Fecha 4 Dia
|
||||
Fecha_4_DiaSemana : USInt; // Fecha 4 Dia de la semana
|
||||
Fecha_4_Hora : USInt; // Fecha 4 Hora
|
||||
Fecha_4_Minuto : USInt; // Fecha 4 Minuto
|
||||
Fecha_4_Segundo : USInt; // Fecha 4 Segundo
|
||||
Fecha_4_NanoSegundo : UDInt; // Fecha 4 Nanosegundo
|
||||
CodString_1 : Int; // Codigo string 1
|
||||
CodString_2 : Int; // Codigo string 2
|
||||
CodString_3 : Int; // Codigo string 3
|
||||
CodString_4 : Int; // Codigo string 4
|
||||
CodString_5 : Int; // Codigo string 5
|
||||
CodString_6 : Int; // Codigo string 6
|
||||
CodString_7 : Int; // Codigo string 7
|
||||
CodString_8 : Int; // Codigo string 8
|
||||
CodString_9 : Int; // Codigo string 9
|
||||
CodString_10 : Int; // Codigo string 10
|
||||
CodString_11 : Int; // Codigo string 11
|
||||
CodString_12 : Int; // Codigo string 12
|
||||
CodString_13 : Int; // Codigo string 13
|
||||
CodString_14 : Int; // Codigo string 14
|
||||
CodString_15 : Int; // Codigo string 15
|
||||
Bool_1 : Bool; // Valor booleano 1
|
||||
Bool_2 : Bool; // Valor booleano 2
|
||||
Bool_3 : Bool; // Valor booleano 3
|
||||
Bool_4 : Bool; // Valor booleano 4
|
||||
Bool_5 : Bool; // Valor booleano 5
|
||||
Bool_6 : Bool; // Valor booleano 6
|
||||
Bool_7 : Bool; // Valor booleano 7
|
||||
Bool_8 : Bool; // Valor booleano 8
|
||||
Bool_9 : Bool; // Valor booleano 9
|
||||
Bool_10 : Bool; // Valor booleano 10
|
||||
Bool_11 : Bool; // Valor booleano 11
|
||||
Bool_12 : Bool; // Valor booleano 12
|
||||
Bool_13 : Bool; // Valor booleano 13
|
||||
Bool_14 : Bool; // Valor booleano 14
|
||||
Bool_15 : Bool; // Valor booleano 15
|
||||
Bool_16 : Bool; // Valor booleano 16
|
||||
Bool_17 : Bool; // Valor booleano 17
|
||||
Bool_18 : Bool; // Valor booleano 18
|
||||
Bool_19 : Bool; // Valor booleano 19
|
||||
Bool_20 : Bool; // Valor booleano 20
|
||||
Bool_21 : Bool; // Valor booleano 21
|
||||
Bool_22 : Bool; // Valor booleano 22
|
||||
Bool_23 : Bool; // Valor booleano 23
|
||||
Bool_24 : Bool; // Valor booleano 24
|
||||
Bool_25 : Bool; // Valor booleano 25
|
||||
Bool_26 : Bool; // Valor booleano 26
|
||||
Bool_27 : Bool; // Valor booleano 27
|
||||
Bool_28 : Bool; // Valor booleano 28
|
||||
Bool_29 : Bool; // Valor booleano 29
|
||||
Bool_30 : Bool; // Valor booleano 30
|
||||
Bool_31 : Bool; // Valor booleano 31
|
||||
Bool_32 : Bool; // Valor booleano 32
|
||||
Real_1 : Real; // Valor real 1
|
||||
Real_2 : Real; // Valor real 2
|
||||
Real_3 : Real; // Valor real 3
|
||||
Real_4 : Real; // Valor real 4
|
||||
Real_5 : Real; // Valor real 5
|
||||
Real_6 : Real; // Valor real 6
|
||||
Real_7 : Real; // Valor real 7
|
||||
Real_8 : Real; // Valor real 8
|
||||
Real_9 : Real; // Valor real 9
|
||||
Real_10 : Real; // Valor real 10
|
||||
Real_11 : Real; // Valor real 11
|
||||
Real_12 : Real; // Valor real 12
|
||||
Real_13 : Real; // Valor real 13
|
||||
Real_14 : Real; // Valor real 14
|
||||
Real_15 : Real; // Valor real 15
|
||||
Real_16 : Real; // Valor real 16
|
||||
Real_17 : Real; // Valor real 17
|
||||
Real_18 : Real; // Valor real 18
|
||||
Real_19 : Real; // Valor real 19
|
||||
Real_20 : Real; // Valor real 20
|
||||
Int_1 : Int; // Valor entero 1
|
||||
Int_2 : Int; // Valor entero 2
|
||||
Int_3 : Int; // Valor entero 3
|
||||
Int_4 : Int; // Valor entero 4
|
||||
Int_5 : Int; // Valor entero 5
|
||||
Int_6 : Int; // Valor entero 6
|
||||
Int_7 : Int; // Valor entero 7
|
||||
Int_8 : Int; // Valor entero 8
|
||||
Int_9 : Int; // Valor entero 9
|
||||
Int_10 : Int; // Valor entero 10
|
||||
Int_11 : Int; // Valor entero 11
|
||||
Int_12 : Int; // Valor entero 12
|
||||
Int_13 : Int; // Valor entero 13
|
||||
Int_14 : Int; // Valor entero 14
|
||||
Int_15 : Int; // Valor entero 15
|
||||
Int_16 : Int; // Valor entero 16
|
||||
Int_17 : Int; // Valor entero 17
|
||||
Int_18 : Int; // Valor entero 18
|
||||
Int_19 : Int; // Valor entero 19
|
||||
Int_20 : Int; // Valor entero 20
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
t_dummy : Int;
|
||||
t_fecha_vacia {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2024 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función para el almacenamiento y estructuración masiva de registros de trazabilidad dentro del buffer de informes del sistema.
|
||||
|
||||
En ella se realizan las siguientes acciones:
|
||||
|
||||
- Comprobación de habilitación: Verificación de la variable de permiso `HabilitacionGeneral`; si no se encuentra activa, se omite la ejecución del bloque mediante un retorno anticipado.
|
||||
- Desplazamiento de datos (FIFO):
|
||||
- Ejecución de la instrucción de bloque para desplazar todos los registros existentes en el Buffer una posición hacia abajo.
|
||||
- Liberación del índice 0 del array para permitir la inserción del nuevo registro sin sobrescribir el histórico reciente.
|
||||
- Gestión e inserción del nuevo registro:
|
||||
- Generación y asignación de un identificador único (Id) transformando la fecha y hora actual del sistema a formato cadena.
|
||||
- Escritura de los metadatos de control y catalogación (Registrar, Tipo, Codigo) en la primera posición del buffer.
|
||||
- Procesamiento y validación de hasta 4 marcas de tiempo dinámicas (Fecha_1 a Fecha_4), forzando una fecha por defecto (01/01/1970) si el año recibido es 0.
|
||||
- Mapeo y transferencia masiva de todas las variables de proceso vinculadas al evento, incluyendo cadenas de texto (CodString_1 a 15), booleanos (Bool_1 a 32), reales (Real_1 a 20) y enteros (Int_1 a 20).
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.01 | 30.07.2024 | (ABH) | Primera version. |
|
||||
| 01.00.02 | 11.09.2024 | (ABH) | Se elimina la generacion de ID, para que lo genere el gestor. |
|
||||
| 01.00.03 | 06.11.2025 | (ABH) | Fix escritura de hora si año seleccionado es 0. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION COMPROBACION_HABILITACION
|
||||
|
||||
// Si no esta habilitado los informes, salimos de la funcion.
|
||||
IF NOT "DB11_INF".Gestion.HabilitacionGeneral THEN
|
||||
RETURN;
|
||||
END_IF;
|
||||
|
||||
END_REGION COMPROBACION_HABILITACION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION DESPLAZAMIENTO_DE_DATOS
|
||||
|
||||
// Desplazamos los datos del buffer una posicion hacia abajo
|
||||
#t_dummy := MOVE_BLK_VARIANT(SRC := "DB11_INF".Buffer, COUNT := INT_TO_UDINT(("N_MAX_INF_BUFFER")), SRC_INDEX := 0, DEST_INDEX := 1, DEST => "DB11_INF".Buffer);
|
||||
|
||||
END_REGION DESPLAZAMIENTO_DE_DATOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_REGISTRO_INFORME
|
||||
|
||||
// Grabamos el nuevo registro
|
||||
"DB11_INF".Buffer[0].Registrar := #Registrar;
|
||||
"DB11_INF".Buffer[0].Id := "FC15006_ZC_DTL_TO_STRING"(FechaDTL := "DB1_SYS".FechaHoraActual, Formato := 3);
|
||||
"DB11_INF".Buffer[0].Tipo := #Tipo;
|
||||
"DB11_INF".Buffer[0].Codigo := #Codigo;
|
||||
IF #Fecha_1_Ano = 0 THEN
|
||||
"DB11_INF".Buffer[0].Fecha_1.Ano := 1970;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Mes := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Dia := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_1.DiaSemana := 5;
|
||||
ELSE
|
||||
"DB11_INF".Buffer[0].Fecha_1.Ano := #Fecha_1_Ano;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Mes := #Fecha_1_Mes;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Dia := #Fecha_1_Dia;
|
||||
"DB11_INF".Buffer[0].Fecha_1.DiaSemana := #Fecha_1_DiaSemana;
|
||||
END_IF;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Hora := #Fecha_1_Hora;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Minuto := #Fecha_1_Minuto;
|
||||
"DB11_INF".Buffer[0].Fecha_1.Segundo := #Fecha_1_Segundo;
|
||||
"DB11_INF".Buffer[0].Fecha_1.NanoSegundo := #Fecha_1_NanoSegundo;
|
||||
IF #Fecha_2_Ano = 0 THEN
|
||||
"DB11_INF".Buffer[0].Fecha_2.Ano := 1970;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Mes := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Dia := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_2.DiaSemana := 5;
|
||||
ELSE
|
||||
"DB11_INF".Buffer[0].Fecha_2.Ano := #Fecha_2_Ano;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Mes := #Fecha_2_Mes;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Dia := #Fecha_2_Dia;
|
||||
"DB11_INF".Buffer[0].Fecha_2.DiaSemana := #Fecha_2_DiaSemana;
|
||||
END_IF;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Hora := #Fecha_2_Hora;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Minuto := #Fecha_2_Minuto;
|
||||
"DB11_INF".Buffer[0].Fecha_2.Segundo := #Fecha_2_Segundo;
|
||||
"DB11_INF".Buffer[0].Fecha_2.NanoSegundo := #Fecha_2_NanoSegundo;
|
||||
IF #Fecha_3_Ano = 0 THEN
|
||||
"DB11_INF".Buffer[0].Fecha_3.Ano := 1970;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Mes := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Dia := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_3.DiaSemana := 5;
|
||||
ELSE
|
||||
"DB11_INF".Buffer[0].Fecha_3.Ano := #Fecha_3_Ano;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Mes := #Fecha_3_Mes;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Dia := #Fecha_3_Dia;
|
||||
"DB11_INF".Buffer[0].Fecha_3.DiaSemana := #Fecha_3_DiaSemana;
|
||||
END_IF;
|
||||
IF #Fecha_4_Ano = 0 THEN
|
||||
"DB11_INF".Buffer[0].Fecha_4.Ano := 1970;
|
||||
"DB11_INF".Buffer[0].Fecha_4.Mes := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_4.Dia := 1;
|
||||
"DB11_INF".Buffer[0].Fecha_4.DiaSemana := 5;
|
||||
ELSE
|
||||
"DB11_INF".Buffer[0].Fecha_4.Ano := #Fecha_4_Ano;
|
||||
"DB11_INF".Buffer[0].Fecha_4.Mes := #Fecha_4_Mes;
|
||||
"DB11_INF".Buffer[0].Fecha_4.Dia := #Fecha_4_Dia;
|
||||
"DB11_INF".Buffer[0].Fecha_4.DiaSemana := #Fecha_4_DiaSemana;
|
||||
END_IF;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Hora := #Fecha_3_Hora;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Minuto := #Fecha_3_Minuto;
|
||||
"DB11_INF".Buffer[0].Fecha_3.Segundo := #Fecha_3_Segundo;
|
||||
"DB11_INF".Buffer[0].Fecha_3.NanoSegundo := #Fecha_3_NanoSegundo;
|
||||
"DB11_INF".Buffer[0].CodString_1 := #CodString_1;
|
||||
"DB11_INF".Buffer[0].CodString_2 := #CodString_2;
|
||||
"DB11_INF".Buffer[0].CodString_3 := #CodString_3;
|
||||
"DB11_INF".Buffer[0].CodString_4 := #CodString_4;
|
||||
"DB11_INF".Buffer[0].CodString_5 := #CodString_5;
|
||||
"DB11_INF".Buffer[0].CodString_6 := #CodString_6;
|
||||
"DB11_INF".Buffer[0].CodString_7 := #CodString_7;
|
||||
"DB11_INF".Buffer[0].CodString_8 := #CodString_8;
|
||||
"DB11_INF".Buffer[0].CodString_9 := #CodString_9;
|
||||
"DB11_INF".Buffer[0].CodString_10 := #CodString_10;
|
||||
"DB11_INF".Buffer[0].CodString_11 := #CodString_11;
|
||||
"DB11_INF".Buffer[0].CodString_12 := #CodString_12;
|
||||
"DB11_INF".Buffer[0].CodString_13 := #CodString_13;
|
||||
"DB11_INF".Buffer[0].CodString_14 := #CodString_14;
|
||||
"DB11_INF".Buffer[0].CodString_15 := #CodString_15;
|
||||
"DB11_INF".Buffer[0].Bool_1 := #Bool_1;
|
||||
"DB11_INF".Buffer[0].Bool_2 := #Bool_2;
|
||||
"DB11_INF".Buffer[0].Bool_3 := #Bool_3;
|
||||
"DB11_INF".Buffer[0].Bool_4 := #Bool_4;
|
||||
"DB11_INF".Buffer[0].Bool_5 := #Bool_5;
|
||||
"DB11_INF".Buffer[0].Bool_6 := #Bool_6;
|
||||
"DB11_INF".Buffer[0].Bool_7 := #Bool_7;
|
||||
"DB11_INF".Buffer[0].Bool_8 := #Bool_8;
|
||||
"DB11_INF".Buffer[0].Bool_9 := #Bool_9;
|
||||
"DB11_INF".Buffer[0].Bool_10 := #Bool_10;
|
||||
"DB11_INF".Buffer[0].Bool_11 := #Bool_11;
|
||||
"DB11_INF".Buffer[0].Bool_12 := #Bool_12;
|
||||
"DB11_INF".Buffer[0].Bool_13 := #Bool_13;
|
||||
"DB11_INF".Buffer[0].Bool_14 := #Bool_14;
|
||||
"DB11_INF".Buffer[0].Bool_15 := #Bool_15;
|
||||
"DB11_INF".Buffer[0].Bool_16 := #Bool_16;
|
||||
"DB11_INF".Buffer[0].Bool_17 := #Bool_17;
|
||||
"DB11_INF".Buffer[0].Bool_18 := #Bool_18;
|
||||
"DB11_INF".Buffer[0].Bool_19 := #Bool_19;
|
||||
"DB11_INF".Buffer[0].Bool_20 := #Bool_20;
|
||||
"DB11_INF".Buffer[0].Bool_21 := #Bool_21;
|
||||
"DB11_INF".Buffer[0].Bool_22 := #Bool_22;
|
||||
"DB11_INF".Buffer[0].Bool_23 := #Bool_23;
|
||||
"DB11_INF".Buffer[0].Bool_24 := #Bool_24;
|
||||
"DB11_INF".Buffer[0].Bool_25 := #Bool_25;
|
||||
"DB11_INF".Buffer[0].Bool_26 := #Bool_26;
|
||||
"DB11_INF".Buffer[0].Bool_27 := #Bool_27;
|
||||
"DB11_INF".Buffer[0].Bool_28 := #Bool_28;
|
||||
"DB11_INF".Buffer[0].Bool_29 := #Bool_29;
|
||||
"DB11_INF".Buffer[0].Bool_30 := #Bool_30;
|
||||
"DB11_INF".Buffer[0].Bool_31 := #Bool_31;
|
||||
"DB11_INF".Buffer[0].Bool_32 := #Bool_32;
|
||||
"DB11_INF".Buffer[0].Real_1 := #Real_1;
|
||||
"DB11_INF".Buffer[0].Real_2 := #Real_2;
|
||||
"DB11_INF".Buffer[0].Real_3 := #Real_3;
|
||||
"DB11_INF".Buffer[0].Real_4 := #Real_4;
|
||||
"DB11_INF".Buffer[0].Real_5 := #Real_5;
|
||||
"DB11_INF".Buffer[0].Real_6 := #Real_6;
|
||||
"DB11_INF".Buffer[0].Real_7 := #Real_7;
|
||||
"DB11_INF".Buffer[0].Real_8 := #Real_8;
|
||||
"DB11_INF".Buffer[0].Real_9 := #Real_9;
|
||||
"DB11_INF".Buffer[0].Real_10 := #Real_10;
|
||||
"DB11_INF".Buffer[0].Real_11 := #Real_11;
|
||||
"DB11_INF".Buffer[0].Real_12 := #Real_12;
|
||||
"DB11_INF".Buffer[0].Real_13 := #Real_13;
|
||||
"DB11_INF".Buffer[0].Real_14 := #Real_14;
|
||||
"DB11_INF".Buffer[0].Real_15 := #Real_15;
|
||||
"DB11_INF".Buffer[0].Real_16 := #Real_16;
|
||||
"DB11_INF".Buffer[0].Real_17 := #Real_17;
|
||||
"DB11_INF".Buffer[0].Real_18 := #Real_18;
|
||||
"DB11_INF".Buffer[0].Real_19 := #Real_19;
|
||||
"DB11_INF".Buffer[0].Real_20 := #Real_20;
|
||||
"DB11_INF".Buffer[0].Int_1 := #Int_1;
|
||||
"DB11_INF".Buffer[0].Int_2 := #Int_2;
|
||||
"DB11_INF".Buffer[0].Int_3 := #Int_3;
|
||||
"DB11_INF".Buffer[0].Int_4 := #Int_4;
|
||||
"DB11_INF".Buffer[0].Int_5 := #Int_5;
|
||||
"DB11_INF".Buffer[0].Int_6 := #Int_6;
|
||||
"DB11_INF".Buffer[0].Int_7 := #Int_7;
|
||||
"DB11_INF".Buffer[0].Int_8 := #Int_8;
|
||||
"DB11_INF".Buffer[0].Int_9 := #Int_9;
|
||||
"DB11_INF".Buffer[0].Int_10 := #Int_10;
|
||||
"DB11_INF".Buffer[0].Int_11 := #Int_11;
|
||||
"DB11_INF".Buffer[0].Int_12 := #Int_12;
|
||||
"DB11_INF".Buffer[0].Int_13 := #Int_13;
|
||||
"DB11_INF".Buffer[0].Int_14 := #Int_14;
|
||||
"DB11_INF".Buffer[0].Int_15 := #Int_15;
|
||||
"DB11_INF".Buffer[0].Int_16 := #Int_16;
|
||||
"DB11_INF".Buffer[0].Int_17 := #Int_17;
|
||||
"DB11_INF".Buffer[0].Int_18 := #Int_18;
|
||||
"DB11_INF".Buffer[0].Int_19 := #Int_19;
|
||||
"DB11_INF".Buffer[0].Int_20 := #Int_20;
|
||||
|
||||
END_REGION GESTION_REGISTRO_INFORME
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
FUNCTION "FC15_ZC_GEST_PREAL" : Void
|
||||
TITLE = FC15_ZC_GEST_PREAL
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
VAR_INPUT
|
||||
PrimerCiclo : Bool; // Marca de primer ciclo de arranque de la CPU
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
Usuario : String; // Usuario actual
|
||||
PReal : Array[*] of "UDT_ZC_PREAL"; // Array de parametro real
|
||||
IndexTraza : Int; // Indice de texto parametro para trazabilidad
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
ValorAnterior : Array[*] of Real; // Array de valores anteriores
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : DInt; // Variable para bucles FOR
|
||||
t_IndiceSuperior : DInt; // Indice superior del array
|
||||
t_IndiceInferior : DInt; // Indice inferior del array
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2026 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** DB Optimizado.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función principal para la gestión de trazabilidad de los parámetros **reales** del proceso.
|
||||
|
||||
Su objetivo principal es detectar cambios de valor en el array de parámetros y lanzar un registro de traza cuando esto sucede.
|
||||
|
||||
El bloque opera de la siguiente manera:
|
||||
|
||||
1. Calcula dinámicamente los límites superior e inferior del array de entrada.
|
||||
2. Si es el primer ciclo de ejecución de la CPU, inicializa los valores "anteriores" con los valores "actuales" para evitar falsos registros de traza iniciales.
|
||||
3. En ciclos normales, compara el valor actual de cada parámetro con su valor guardado en el ciclo anterior.
|
||||
4. Si detecta una diferencia, llama a la función `FC8_ZC_TRAZA_REGISTRO` para registrar el cambio y actualiza el valor anterior.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC8_ZC_TRAZA_REGISTRO` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_PREAL` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 2026-03-20 | (ABH) | Primera version. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
// Calculo de los limites del array, ya que la entrada del array de parametros es variable.
|
||||
#t_IndiceInferior := LOWER_BOUND(ARR := #PReal, DIM := 1);
|
||||
#t_IndiceSuperior := UPPER_BOUND(ARR := #PReal, DIM := 1);
|
||||
|
||||
END_REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION PRIMER_ARRANQUE
|
||||
|
||||
// En el primer arranque de la CPU, recorremos el array completo y almacenamos los valores actuales como valores anteriores en el arranque de la CPU.
|
||||
// Esto se realiza ya que los valores anteriores no son remanentes, para optimizar la memoria del PLC.
|
||||
IF #PrimerCiclo THEN
|
||||
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
#ValorAnterior[#for_i] := #PReal[#for_i].Valor;
|
||||
END_FOR;
|
||||
|
||||
// Salimos inmediatamente de la funcion, para realizar la gestion de los parametros con la CPU arrancada
|
||||
RETURN;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION PRIMER_ARRANQUE
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_PARAMETROS
|
||||
|
||||
// Gestion de los cambios de valor de los parametros. Si detecta un cambio, lanza la traza
|
||||
// y actualiza el valor anterior.
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
|
||||
// En caso de detectar cambio de valor
|
||||
IF #PReal[#for_i].Valor <> #ValorAnterior[#for_i] THEN
|
||||
|
||||
// Lanzamos la trazabilidad
|
||||
"FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHora,
|
||||
Registrar := 1,
|
||||
Categoria := "TRZ_CAT_25_PREAL",
|
||||
User := #Usuario,
|
||||
CodInt_1 := #IndexTraza + DINT_TO_INT(#for_i - 1),
|
||||
CodInt_2 := "TRZ_SYS_PAR_VAL_ANT",
|
||||
CodInt_3 := "TRZ_SYS_PAR_VAL_NUE",
|
||||
CodInt_4 := 0,
|
||||
CodInt_5 := 0,
|
||||
CodReal_1 := #ValorAnterior[#for_i],
|
||||
CodReal_2 := #PReal[#for_i].Valor);
|
||||
|
||||
// Actualizamos el valor anterior
|
||||
#ValorAnterior[#for_i] := #PReal[#for_i].Valor;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION GESTION_PARAMETROS
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
FUNCTION "FC16_ZC_GEST_PINT" : Void
|
||||
TITLE = FC16_ZC_GEST_PINT
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
VAR_INPUT
|
||||
PrimerCiclo : Bool; // Marca de primer ciclo de arranque de la CPU
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
Usuario : String; // Usuario actual
|
||||
PInt : Array[*] of "UDT_ZC_PINT"; // Array de parametro entero
|
||||
IndexTraza : Int; // Indice de texto parametro para trazabilidad
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
ValorAnterior : Array[*] of Int; // Array de valores anteriores
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : DInt; // Variable para bucles FOR
|
||||
t_IndiceSuperior : DInt; // Indice superior del array
|
||||
t_IndiceInferior : DInt; // Indice inferior del array
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2026 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** DB Optimizado.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función principal para la gestión de trazabilidad de los parámetros **enteros** del proceso.
|
||||
|
||||
Su objetivo principal es detectar cambios de valor en el array de parámetros y lanzar un registro de traza cuando esto sucede.
|
||||
|
||||
El bloque opera de la siguiente manera:
|
||||
|
||||
1. Calcula dinámicamente los límites superior e inferior del array de entrada.
|
||||
2. Si es el primer ciclo de ejecución de la CPU, inicializa los valores "anteriores" con los valores "actuales" para evitar falsos registros de traza iniciales.
|
||||
3. En ciclos normales, compara el valor actual de cada parámetro con su valor guardado en el ciclo anterior.
|
||||
4. Si detecta una diferencia, llama a la función `FC8_ZC_TRAZA_REGISTRO` para registrar el cambio y actualiza el valor anterior.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC8_ZC_TRAZA_REGISTRO` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_PINT` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 2026-03-20 | (ABH) | Primera version. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
// Calculo de los limites del array, ya que la entrada del array de parametros es variable.
|
||||
#t_IndiceInferior := LOWER_BOUND(ARR := #PInt, DIM := 1);
|
||||
#t_IndiceSuperior := UPPER_BOUND(ARR := #PInt, DIM := 1);
|
||||
|
||||
END_REGION CALCULO_LIMITES_ARRAY
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION PRIMER_ARRANQUE
|
||||
|
||||
// En el primer arranque de la CPU, recorremos el array completo y almacenamos los valores actuales como valores anteriores en el arranque de la CPU.
|
||||
// Esto se realiza ya que los valores anteriores no son remanentes, para optimizar la memoria del PLC.
|
||||
IF #PrimerCiclo THEN
|
||||
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
#ValorAnterior[#for_i] := #PInt[#for_i].Valor;
|
||||
END_FOR;
|
||||
|
||||
// Salimos inmediatamente de la funcion, para realizar la gestion de los parametros con la CPU arrancada
|
||||
RETURN;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION PRIMER_ARRANQUE
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_PARAMETROS
|
||||
|
||||
// Gestion de los cambios de valor de los parametros. Si detecta un cambio, lanza la traza
|
||||
// y actualiza el valor anterior.
|
||||
FOR #for_i := #t_IndiceInferior TO #t_IndiceSuperior DO
|
||||
|
||||
// En caso de detectar cambio de valor
|
||||
IF #PInt[#for_i].Valor <> #ValorAnterior[#for_i] THEN
|
||||
|
||||
// Lanzamos la trazabilidad
|
||||
"FC8_ZC_TRZ_REGISTRO"(FechaHora := #FechaHora,
|
||||
Registrar := 1,
|
||||
Categoria := "TRZ_CAT_26_PINT",
|
||||
User := #Usuario,
|
||||
CodInt_1 := #IndexTraza + DINT_TO_INT(#for_i - 1),
|
||||
CodInt_2 := "TRZ_SYS_PAR_VAL_ANT",
|
||||
CodInt_3 := "TRZ_SYS_PAR_VAL_NUE",
|
||||
CodInt_4 := 0,
|
||||
CodInt_5 := 0,
|
||||
CodReal_1 := #ValorAnterior[#for_i],
|
||||
CodReal_2 := #PInt[#for_i].Valor);
|
||||
|
||||
// Actualizamos el valor anterior
|
||||
#ValorAnterior[#for_i] := #PInt[#for_i].Valor;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION GESTION_PARAMETROS
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
FUNCTION_BLOCK "FB15200_ZC_SYNC_RECETA_PANEL"
|
||||
TITLE = FB15200_ZC_SYNC_RECETA_PANEL
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Sincronizacion de recetas desde Scada (BBDD) a paneles
|
||||
VAR_INPUT
|
||||
HabilitarBorrado : Bool := FALSE; // Habilita el borrado de ficheros
|
||||
RutaCarpetaRecetas { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String[25] := '\temp\RecetasScada\';
|
||||
FechaHoraActual {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
|
||||
TiempoRetardoInicio : Time := T#20s;
|
||||
TiempoRetardoHmi : Time := T#10s;
|
||||
TiempoComprobacion : Time := T#500ms;
|
||||
TiempoError : Time := T#8s;
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT RETAIN
|
||||
ErrorImportar : Bool;
|
||||
ErrorBorrar : Bool;
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
s_ExisteRecetaNueva : Bool;
|
||||
s_OrdenSincHMI : Bool;
|
||||
s_OrdenBorrarHMI : Bool;
|
||||
s_EstadoImportar : Int;
|
||||
s_EstadoBorrar : Int;
|
||||
s_RutaCarpeta : String;
|
||||
s_Iniciar { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
||||
s_Etapa { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
|
||||
s_EtapaSiguiente { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
|
||||
UltimaSincronizacion {InstructionName := 'DTL'; LibVersion := '1.0'; S7_SetPoint := 'True'} : DTL;
|
||||
END_VAR
|
||||
VAR
|
||||
TON_OrdenInicio {InstructionName := 'TON_TIME'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TON_TIME;
|
||||
TON_RetardoImportarHmi {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||||
TON_RetardoBorrarHmi {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||||
TON_EstadoImportar {InstructionName := 'TON_TIME'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : TON_TIME;
|
||||
TON_ErrorImportar {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||||
TON_EstadoBorrar {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||||
TON_ErrorBorrar {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
ETAPA_0_REPOSO : Int := 0;
|
||||
ETAPA_10_IMPORTAR_ORDEN_HMI : Int := 10;
|
||||
ETAPA_20_IMPORTAR_ESPERA_HMI : Int := 20;
|
||||
ETAPA_30_IMPORTAR_COMPROBACION : Int := 30;
|
||||
ETAPA_40_BORRAR_ORDEN_HMI : Int := 40;
|
||||
ETAPA_50_BORRAR_ESPERA_HMI : Int := 50;
|
||||
ETAPA_60_BORRAR_COMPROBACION : Int := 60;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2022 - 2022
|
||||
//=======================================================================
|
||||
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
Función central para la gestión de la sincronización de recetas con el HMI. Implementa una máquina de estados que coordina la importación (y borrado opcional) de recetas desde el HMI, gestionando las temporizaciones de espera, las señales de confirmación y los códigos de estado/error, así como el registro de la última sincronización correcta.
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
Acciones detalladas:
|
||||
- Gestiona los temporizadores generales del bloque: retardo de inicio (`TON_OrdenInicio`), retardos de orden de importar/borrar desde HMI (`TON_RetardoImportarHmi`, `TON_RetardoBorrarHmi`), temporizadores de espera de estado (`TON_EstadoImportar`, `TON_EstadoBorrar`) y temporizadores de error (`TON_ErrorImportar`, `TON_ErrorBorrar`).
|
||||
- Estado `ETAPA_0_REPOSO`: si existe receta nueva (`s_ExisteRecetaNueva`) y la etapa actual es reposo, arranca la temporización de inicio. Una vez cumplido el tiempo, se activa `s_Iniciar`, se inicializan los estados de importar/borrar, se carga la `RutaCarpetaRecetas` en `s_RutaCarpeta` y se pasa a la etapa de orden de importar al HMI.
|
||||
- Estado `ETAPA_10_IMPORTAR_ORDEN_HMI`: activa la marca `s_OrdenSincHMI` cuando se recibe desde HMI o cuando expira `TON_RetardoImportarHmi`, y transiciona a la etapa de espera de importación.
|
||||
- Estado `ETAPA_20_IMPORTAR_ESPERA_HMI`: espera a que finalice la temporización de estado (`TON_EstadoImportar`) o de error (`TON_ErrorImportar`) para pasar a la etapa de comprobación.
|
||||
- Estado `ETAPA_30_IMPORTAR_COMPROBACION`: evalúa el código de estado de importación (`s_EstadoImportar`). Si es correcto (`4`), resetea `s_ExisteRecetaNueva` y `ErrorImportar`, registra la `UltimaSincronizacion` y, si está habilitado el borrado (`HabilitarBorrado`), continúa con la etapa de borrado; en caso contrario, vuelve a `ETAPA_0_REPOSO`. Si el estado no es correcto, marca `ErrorImportar` y vuelve a reposo.
|
||||
- Estado `ETAPA_40_BORRAR_ORDEN_HMI`: activa `s_OrdenBorrarHMI` cuando se recibe desde HMI o cuando expira `TON_RetardoBorrarHmi`, y transiciona a la etapa de espera de borrado.
|
||||
- Estado `ETAPA_50_BORRAR_ESPERA_HMI`: espera a que finalice la temporización de estado (`TON_EstadoBorrar`) o de error (`TON_ErrorBorrar`) para pasar a la etapa de comprobación de borrado.
|
||||
- Estado `ETAPA_60_BORRAR_COMPROBACION`: evalúa el código de estado de borrado (`s_EstadoBorrar`). Si es correcto (`4`), resetea `s_ExisteRecetaNueva` y `ErrorBorrar`; si no, activa `ErrorBorrar`. En ambos casos, resetea los flags de estado y orden y vuelve a `ETAPA_0_REPOSO`.
|
||||
- En cada ciclo se actualiza la etapa en curso (`s_Etapa := s_EtapaSiguiente`), manteniendo la coherencia de la máquina de estados.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 03.11.2022 | (ABH) | Primera versión. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_TEMPORIZADORES
|
||||
|
||||
// Retardo inicio sincronizacion
|
||||
#TON_OrdenInicio(IN := #s_ExisteRecetaNueva AND (#s_Etapa = #ETAPA_0_REPOSO),
|
||||
PT := #TiempoRetardoInicio);
|
||||
IF #TON_OrdenInicio.Q THEN
|
||||
#s_Iniciar := true;
|
||||
END_IF;
|
||||
|
||||
// Retardo orden importar hmi
|
||||
#TON_RetardoImportarHmi(IN := (#s_Etapa = #ETAPA_10_IMPORTAR_ORDEN_HMI),
|
||||
PT := #TiempoRetardoHmi);
|
||||
|
||||
// Retardo estado/error importar
|
||||
#TON_EstadoImportar(IN := (#s_Etapa = #ETAPA_20_IMPORTAR_ESPERA_HMI) AND ((#s_EstadoImportar = 4) OR (#s_EstadoImportar = 12)),
|
||||
PT := #TiempoComprobacion);
|
||||
#TON_ErrorImportar(IN := (#s_Etapa = #ETAPA_20_IMPORTAR_ESPERA_HMI),
|
||||
PT := #TiempoError);
|
||||
|
||||
// Retardo orden borrar hmi
|
||||
#TON_RetardoBorrarHmi(IN := (#s_Etapa = #ETAPA_40_BORRAR_ORDEN_HMI),
|
||||
PT := #TiempoRetardoHmi);
|
||||
|
||||
// Retardo borrar estado
|
||||
#TON_EstadoBorrar(IN := (#s_Etapa = #ETAPA_50_BORRAR_ESPERA_HMI) AND ((#s_EstadoImportar = 4) OR (#s_EstadoImportar = 12)),
|
||||
PT := #TiempoComprobacion);
|
||||
#TON_ErrorBorrar(IN := (#s_Etapa = #ETAPA_50_BORRAR_ESPERA_HMI),
|
||||
PT := #TiempoError);
|
||||
|
||||
END_REGION GESTION_TEMPORIZADORES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION LOGICA
|
||||
|
||||
CASE #s_Etapa OF
|
||||
|
||||
#ETAPA_0_REPOSO:
|
||||
#s_RutaCarpeta := '';
|
||||
REGION REPOSO
|
||||
|
||||
IF #s_Iniciar THEN
|
||||
#s_Iniciar := FALSE;
|
||||
#s_EstadoImportar := 0;
|
||||
#s_EstadoBorrar := 0;
|
||||
#s_RutaCarpeta := #RutaCarpetaRecetas;
|
||||
#s_EtapaSiguiente := #ETAPA_10_IMPORTAR_ORDEN_HMI;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
#ETAPA_10_IMPORTAR_ORDEN_HMI:
|
||||
|
||||
REGION IMPORTAR_ORDEN_HMI
|
||||
|
||||
IF #s_OrdenSincHMI THEN
|
||||
#s_EtapaSiguiente := #ETAPA_20_IMPORTAR_ESPERA_HMI;
|
||||
END_IF;
|
||||
|
||||
IF #TON_RetardoImportarHmi.Q THEN
|
||||
#s_OrdenSincHMI := TRUE;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
#ETAPA_20_IMPORTAR_ESPERA_HMI:
|
||||
|
||||
REGION IMPORTAR_ESPERA_HMI
|
||||
|
||||
IF #TON_EstadoImportar.Q OR #TON_ErrorImportar.Q THEN
|
||||
#s_EtapaSiguiente := #ETAPA_30_IMPORTAR_COMPROBACION;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
#ETAPA_30_IMPORTAR_COMPROBACION:
|
||||
|
||||
REGION IMPORTAR_COMPROBACION
|
||||
|
||||
// Si se ejecuta correctamente, reseteamos marca que indica que hay recetas nuevas que sincronizar
|
||||
// y guardamos la fecha y hora de la ultima sincronizacion
|
||||
IF #s_EstadoImportar = 4 THEN
|
||||
|
||||
#s_ExisteRecetaNueva :=
|
||||
#ErrorImportar := FALSE;
|
||||
#UltimaSincronizacion := #FechaHoraActual;
|
||||
IF #HabilitarBorrado THEN
|
||||
#s_EtapaSiguiente := #ETAPA_40_BORRAR_ORDEN_HMI;
|
||||
ELSE
|
||||
#s_EtapaSiguiente := #ETAPA_0_REPOSO;
|
||||
END_IF;
|
||||
ELSE
|
||||
#ErrorImportar := TRUE;
|
||||
#s_EtapaSiguiente := #ETAPA_0_REPOSO;
|
||||
END_IF;
|
||||
|
||||
#s_OrdenSincHMI := FALSE;
|
||||
#s_EstadoImportar := 0;
|
||||
|
||||
|
||||
END_REGION
|
||||
|
||||
#ETAPA_40_BORRAR_ORDEN_HMI:
|
||||
|
||||
REGION BORRAR_ORDEN_HMI
|
||||
|
||||
IF #s_OrdenBorrarHMI THEN
|
||||
#s_EtapaSiguiente := #ETAPA_50_BORRAR_ESPERA_HMI;
|
||||
END_IF;
|
||||
|
||||
IF #TON_RetardoBorrarHmi.Q THEN
|
||||
#s_OrdenBorrarHMI := TRUE;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
#ETAPA_50_BORRAR_ESPERA_HMI:
|
||||
|
||||
REGION BORRAR_ESPERA_HMI
|
||||
|
||||
IF #TON_EstadoBorrar.Q OR #TON_ErrorBorrar.Q THEN
|
||||
#s_EtapaSiguiente := #ETAPA_60_BORRAR_COMPROBACION;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
#ETAPA_60_BORRAR_COMPROBACION:
|
||||
|
||||
REGION IMPORTAR_COMPROBACION
|
||||
|
||||
// Si se ejecuta correctamente, reseteamos marca que indica que hay recetas nuevas que sincronizar
|
||||
// y guardamos la fecha y hora de la ultima sincronizacion
|
||||
IF #s_EstadoBorrar = 4 THEN
|
||||
|
||||
#s_ExisteRecetaNueva :=
|
||||
#ErrorBorrar := FALSE;
|
||||
|
||||
ELSE
|
||||
#ErrorBorrar := TRUE;
|
||||
END_IF;
|
||||
|
||||
#s_EstadoBorrar := 0;
|
||||
#s_OrdenBorrarHMI := FALSE;
|
||||
#s_EtapaSiguiente := #ETAPA_0_REPOSO;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
ELSE
|
||||
|
||||
#s_EtapaSiguiente := #ETAPA_0_REPOSO;
|
||||
|
||||
END_CASE;
|
||||
|
||||
#s_Etapa := #s_EtapaSiguiente;
|
||||
|
||||
END_REGION LOGICA
|
||||
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
FUNCTION_BLOCK "FB15050_ZC_CHEQUEO"
|
||||
TITLE = FB15050_ZC_CHEQUEO
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
VAR_INPUT
|
||||
GuardarRegistro : Bool; // Orden guardado registro nuevo
|
||||
ComprobarBajoChequeo : Bool; // Orden comprobacion Alarma bajo chequeo
|
||||
ResetBajoChequeo : Bool; // Reset alarma bajo chequeo
|
||||
TomarDatoChequeo : Bool; // Orden para visualizacion tomar datos en HMI
|
||||
PorcentajeBomba : Real; // Porcentaje bomba
|
||||
Temperatura : Real; // Temperatura
|
||||
Caudal : Real; // Caudal
|
||||
CaudalPermeado : Real; // Caudal permeado
|
||||
Conductividad : Real; // Conductividad
|
||||
Presion : Real; // Presion
|
||||
SP_Caudal_100por100 : Real; // Set Point caudal 100%
|
||||
SP_CaudalMinimoChequeo : Real; // Set Point caudal minimo
|
||||
FechaActual {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
EstadoChequeoActual : Bool; // Estado chequeo actual
|
||||
AlarmaBajoChequeo : Bool; // Alarma bajo chequeo
|
||||
VisDatoChequeo : Bool; // Visibilidad tomar datos en HMI
|
||||
PorcentajeChequeoActual : Real; // Estado porcentaje actual
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
s_PorcentajeChequeoOK { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Real := 80.0;
|
||||
END_VAR
|
||||
VAR
|
||||
s_OrdenGuardarRegistro { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
||||
s_OrdenBorrarRegistros { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
||||
s_NumeroBorrado { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int; // -1= Todos / Valor= Numero de registro
|
||||
s_OldGuardar { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
Registro { S7_SetPoint := 'False'} : Array[1..#N_REGISTROS] of "UDT_ZC_INF_CHEQUEO";
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
t_dummyInt : Int;
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
N_REGISTROS : Int := 20;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2024 - 2026
|
||||
//=======================================================================
|
||||
(*
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
El bloque `FB15050_ZC_CHEQUEO` implementa la gestión de los datos de chequeo de un sistema de membranas, manteniendo un histórico circular de hasta `#N_REGISTROS` mediciones y evaluando el rendimiento de la instalación comparando el caudal de permeado real con un valor de referencia al 100% de la bomba.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Detección de flanco ascendente en la orden de guardado: `#s_OrdenGuardarRegistro` se activa con un pulso de `#GuardarRegistro` mediante la variable estática `#s_P_Trig_Guardar`, evitando registros duplicados por nivel alto mantenido.
|
||||
- Adquisición de datos: al recibir la orden de guardado, se desplazan los registros existentes una posición hacia abajo mediante `MOVE_BLK_VARIANT` y se almacena en `#Registro[1]` el conjunto de variables de proceso (`PorcentajeBomba`, `Temperatura`, `Caudal`, `CaudalPermeado`, `Conductividad`, `Presion`), junto con el `ResultadoChequeo` calculado como el porcentaje de caudal de permeado frente a `SP_Caudal_100por100`, y la fecha actual convertida con `FC15005_ZC_DTL_TO_ZC_FECHA` a la estructura `ZC_FECHA`.
|
||||
- Cálculo del porcentaje de chequeo en tiempo real: `PorcentajeChequeoActual` se obtiene como el cociente entre el `CaudalPermeado` actual y `SP_Caudal_100por100`, y `EstadoChequeoActual` se activa cuando dicho porcentaje alcanza o supera `#s_PorcentajeChequeoOK`.
|
||||
- Alarma de bajo chequeo: se activa `#AlarmaBajoChequeo` cuando `#ComprobarBajoChequeo` está habilitado y el `Caudal` cae por debajo de `#SP_CaudalMinimoChequeo`. Se desactiva con `#ResetBajoChequeo`.
|
||||
- Animación de resultados: para cada registro se evalúa `ResultadoAnimacion`, que se activa cuando el `ResultadoChequeo` del registro es igual o superior a 80.0%, permitiendo al HMI colorear el histórico de forma intuitiva.
|
||||
- Visibilidad de toma de dato en HMI: `VisDatoChequeo` refleja el estado de `#TomarDatoChequeo` para señalizar al operador que la fase de toma de datos está activa.
|
||||
- Borrado de registros selectivo: según el valor de `#s_NumeroBorrado` se distingue entre borrado total (`0` o `-1`), borrado de un registro intermedio (con desplazamiento hacia abajo para mantener la trazabilidad) y borrado del último registro. En todos los casos se inicializan a cero todos los campos del registro (analógicos y de fecha).
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `ZC_FECHA`, `ZC_CHEQUEO` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 18.07.2023 | (ABH) | Primera versión. |
|
||||
| 01.00.01 | 21.07.2023 | (ABH) | Se eliminan entradas `Etapa actual` y `tiempo restante`. La gestión de guardado y comprobación de bajo chequeo se realiza mediante entradas BOOL. |
|
||||
| 01.00.02 | 11.10.2023 | (HCR) | Se añaden entradas `TomarDatoChequeo` y salida `VisDatoChequeo` para mostrar en HMI la toma de datos por parte del operador. |
|
||||
| 01.00.02 | 03.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION ORDEN_GUARDAR
|
||||
|
||||
// Orden guardar registro
|
||||
#s_OrdenGuardarRegistro := #GuardarRegistro AND NOT #s_OldGuardar;
|
||||
|
||||
// Estado anterior
|
||||
#s_OldGuardar := #GuardarRegistro;
|
||||
|
||||
END_REGION ORDEN_GUARDAR
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION ADQUISICION_DE_DATOS
|
||||
|
||||
// Con flanco de guardar datos, desplazamos los registros y almacenamos los datos del chequeo en la poisicion 1
|
||||
IF #s_OrdenGuardarRegistro THEN
|
||||
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Registro, COUNT := INT_TO_UDINT(#N_REGISTROS - 1), SRC_INDEX := 0, DEST_INDEX := 1, DEST => #Registro);
|
||||
|
||||
// Adquisicion de datos
|
||||
#Registro[1].PorcentajeBomba := #PorcentajeBomba;
|
||||
#Registro[1].Temperatura := #Temperatura;
|
||||
#Registro[1].Caudal := #Caudal;
|
||||
#Registro[1].CaudalPermeado := #CaudalPermeado;
|
||||
#Registro[1].Conductividad := #Conductividad;
|
||||
#Registro[1].Presion := #Presion;
|
||||
#Registro[1].ResultadoChequeo := #CaudalPermeado / #SP_Caudal_100por100 * 100.0;
|
||||
|
||||
#Registro[1].Fecha := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION ADQUISICION_DE_DATOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULO_%_CHEQUEO
|
||||
|
||||
// Calculo porcentaje del chequeo
|
||||
IF #SP_Caudal_100por100 > 0.0 THEN
|
||||
#PorcentajeChequeoActual := (#Registro[1].CaudalPermeado / #SP_Caudal_100por100) * 100.0;
|
||||
ELSE
|
||||
#PorcentajeChequeoActual := 0.0;
|
||||
END_IF;
|
||||
|
||||
// Estado del chequeo actual
|
||||
#EstadoChequeoActual := #PorcentajeChequeoActual >= #s_PorcentajeChequeoOK;
|
||||
|
||||
END_REGION CALCULO_%_CHEQUEO
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION VISIBILIDADES
|
||||
|
||||
// Visibilidad bajo chequeo
|
||||
IF #ComprobarBajoChequeo AND (#Caudal < #SP_CaudalMinimoChequeo) THEN
|
||||
#AlarmaBajoChequeo := TRUE;
|
||||
END_IF;
|
||||
IF #ResetBajoChequeo THEN
|
||||
#AlarmaBajoChequeo := FALSE;
|
||||
END_IF;
|
||||
|
||||
// Visibilidad Resultado Chequeo
|
||||
FOR #for_i := 1 TO #N_REGISTROS DO
|
||||
#Registro[#for_i].ResultadoAnimacion := (#Registro[#for_i].ResultadoChequeo >= 80.0);
|
||||
END_FOR;
|
||||
|
||||
// Visibilidad tomar dato chequeo en HMI
|
||||
#VisDatoChequeo := #TomarDatoChequeo;
|
||||
|
||||
END_REGION VISIBILIDADES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION BORRADO
|
||||
|
||||
// Borrado de todos los registros
|
||||
IF #s_OrdenBorrarRegistros THEN
|
||||
IF #s_NumeroBorrado = -1 OR #s_NumeroBorrado = 0 THEN
|
||||
// ==============================================================================
|
||||
// Borrado total
|
||||
FOR #for_i := 1 TO #N_REGISTROS DO
|
||||
#Registro[#for_i].PorcentajeBomba := 0.0;
|
||||
#Registro[#for_i].Temperatura := 0.0;
|
||||
#Registro[#for_i].Caudal := 0.0;
|
||||
#Registro[#for_i].CaudalPermeado := 0.0;
|
||||
#Registro[#for_i].Conductividad := 0.0;
|
||||
#Registro[#for_i].Presion := 0.0;
|
||||
#Registro[#for_i].ResultadoChequeo := 0.0;
|
||||
#Registro[#for_i].Fecha.Ano := 0;
|
||||
#Registro[#for_i].Fecha.Mes := 0;
|
||||
#Registro[#for_i].Fecha.Dia := 0;
|
||||
#Registro[#for_i].Fecha.DiaSemana := 0;
|
||||
#Registro[#for_i].Fecha.Hora := 0;
|
||||
#Registro[#for_i].Fecha.Minuto := 0;
|
||||
#Registro[#for_i].Fecha.Segundo := 0;
|
||||
#Registro[#for_i].Fecha.NanoSegundo := 0;
|
||||
END_FOR;
|
||||
ELSIF #s_NumeroBorrado >= 1 AND #s_NumeroBorrado < #N_REGISTROS THEN
|
||||
// ==============================================================================
|
||||
// Borrado registro especifico
|
||||
#Registro[#s_NumeroBorrado].PorcentajeBomba := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Temperatura := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Caudal := 0.0;
|
||||
#Registro[#s_NumeroBorrado].CaudalPermeado := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Conductividad := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Presion := 0.0;
|
||||
#Registro[#s_NumeroBorrado].ResultadoChequeo := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Ano := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Mes := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Dia := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.DiaSemana := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Hora := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Minuto := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Segundo := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.NanoSegundo := 0;
|
||||
// ==============================================================================
|
||||
// Desplazamiento de datos
|
||||
#t_dummyInt := MOVE_BLK_VARIANT(SRC := #Registro,
|
||||
COUNT := INT_TO_UDINT(#N_REGISTROS - #s_NumeroBorrado),
|
||||
SRC_INDEX := #s_NumeroBorrado,
|
||||
DEST_INDEX := #s_NumeroBorrado - 1,
|
||||
DEST => #Registro);
|
||||
// ==============================================================================
|
||||
// Borrado del ultimo registro
|
||||
#Registro[#N_REGISTROS].PorcentajeBomba := 0.0;
|
||||
#Registro[#N_REGISTROS].Temperatura := 0.0;
|
||||
#Registro[#N_REGISTROS].Caudal := 0.0;
|
||||
#Registro[#N_REGISTROS].CaudalPermeado := 0.0;
|
||||
#Registro[#N_REGISTROS].Conductividad := 0.0;
|
||||
#Registro[#N_REGISTROS].Presion := 0.0;
|
||||
#Registro[#N_REGISTROS].ResultadoChequeo := 0.0;
|
||||
#Registro[#N_REGISTROS].Fecha.Ano := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.Mes := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.Dia := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.DiaSemana := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.Hora := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.Minuto := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.Segundo := 0;
|
||||
#Registro[#N_REGISTROS].Fecha.NanoSegundo := 0;
|
||||
ELSIF #s_NumeroBorrado = #N_REGISTROS THEN
|
||||
// ==============================================================================
|
||||
// Borrado de ultimo registro
|
||||
#Registro[#s_NumeroBorrado].PorcentajeBomba := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Temperatura := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Caudal := 0.0;
|
||||
#Registro[#s_NumeroBorrado].CaudalPermeado := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Conductividad := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Presion := 0.0;
|
||||
#Registro[#s_NumeroBorrado].ResultadoChequeo := 0.0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Ano := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Mes := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Dia := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.DiaSemana := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Hora := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Minuto := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.Segundo := 0;
|
||||
#Registro[#s_NumeroBorrado].Fecha.NanoSegundo := 0;
|
||||
END_IF;
|
||||
#s_OrdenBorrarRegistros := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION BORRADO
|
||||
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
FUNCTION_BLOCK "FB15055_ZC_HORAS_MAQUINA"
|
||||
TITLE = FB15055_ZC_HORAS_MAQUINA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de funcion para la gestion de horas de funcionamiento
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso 1 Segundo
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
IniciarTiempoMaquina : Bool; // Orden Contar tiempo maquina
|
||||
IniciarTiempoProd : Bool; // Orden contar tiempo produccion
|
||||
IniciarTiempoRecirc : Bool; // Orden contar tiempo recirculacion
|
||||
IniciarTiempoEnzim : Bool; // Orden contar tiempo planta con enzimatico
|
||||
IniciarTiempoCIP : Bool;
|
||||
IniciarTiempoPausa : Bool;
|
||||
ResetTiempoEnzim : Bool; // Orden reset tiempo planta con enzimatico
|
||||
END_VAR
|
||||
VAR_INPUT RETAIN
|
||||
HabilitarMant : Bool; // Habilitar gestion mantenimiento
|
||||
SP_HorasAlarma : UDInt; // Numero de Horas para alarmas
|
||||
SP_MinutosAlarma : USInt; // Numero de Minutos para alarmas
|
||||
END_VAR
|
||||
VAR_INPUT
|
||||
ProcesoID : Int; // ID Proceso para trazabilidad
|
||||
END_VAR
|
||||
VAR_INPUT RETAIN
|
||||
Usuario : String[25]; // Usuario actual
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
ParoMantenimiento : Bool; // Paro maquina por horas de mantenimiento
|
||||
VisTiempoRecirculacion : Bool; // Visibilidad tiempo recirculacion
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
TiempoMaquina { S7_SetPoint := 'False'} : "UDT_ZC_CONTADOR_TIEMPO"; // Horas totales de la maquina
|
||||
TiempoMantenimiento { S7_SetPoint := 'False'} : "UDT_ZC_CONTADOR_TIEMPO"; // Horas totales mantenimiento
|
||||
TiempoProduccionActual : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
TiempoProduccionTotal : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
TiempoRecirculacion : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
TiempoEnzimatica : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
TiempoLimpieza : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
TiempoPausa : "UDT_ZC_CONTADOR_TIEMPO";
|
||||
END_VAR
|
||||
VAR
|
||||
Pulsador : "UDT_ZC_PULSADOR"; // Pulsador reset mantenimiento
|
||||
PasswordHMI : UInt; // Contraseña HMI
|
||||
s_OldAvisoHoras { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // Pulso alarma horas
|
||||
s_OldInicioProduccion : Bool; // Pulso inicio produccion
|
||||
s_OldInicioCIP : Bool;
|
||||
s_OldInicioPausa : Bool;
|
||||
s_OldCondicionParo { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
|
||||
s_PasswordCalculado { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt; // Contraseña calculada de mantenimiento
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
t_OrdenReset : Bool; // Orden Reset contador de horas
|
||||
t_CondicionParo : Bool;
|
||||
t_ResetProdActual : Bool;
|
||||
t_ResetLimpieza : Bool;
|
||||
t_ResetPausa : Bool;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2024 - 2026
|
||||
//=======================================================================
|
||||
(*
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
El bloque `FB15055_ZC_HORAS_MAQUINA` implementa la gestión integral de las horas de funcionamiento de la máquina, llevando el conteo de tiempo acumulado de operación, tiempos de producción (actual y total), mantenimiento, recirculación, limpieza, pausa y tiempo de planta parada con enzimático. Incluye además la gestión del pulsador de reset de mantenimiento protegido por contraseña HMI y la gestión de los avisos por horas alcanzadas.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Conteo de horas de funcionamiento de la máquina (`TiempoMaquina`) mediante el bloque `FC15025_ZC_CONTADOR_TIEMPO` con estructura `UDT_ZC_CONTADOR_TIEMPO`.
|
||||
- Conteo diferenciado de tiempo de producción actual (`TiempoProduccionActual`), producción total (`TiempoProduccionTotal`), tiempo de mantenimiento (`TiempoMantenimiento`), tiempo de recirculación (`TiempoRecirculacion`), tiempo de enzimática (`TiempoEnzimatica`), tiempo de limpieza (`TiempoLimpieza`) y tiempo de pausa (`TiempoPausa`), todos basados en `UDT_ZC_CONTADOR_TIEMPO`.
|
||||
- Gestión del pulsador de reset de mantenimiento (`Pulsador` tipo `UDT_ZC_PULSADOR`) con cálculo y verificación de contraseña HMI (`PasswordHMI` / `PasswordCalculado`).
|
||||
- Gestión de los flancos de inicio de producción, inicio de CIP e inicio de pausa mediante variables estáticas `s_P_Trig_*` para detección de pulsos de activación.
|
||||
- Activación de la alarma y el paro de mantenimiento (`OutputParoMantenimiento`) por horas acumuladas, con flag de aviso (`s_Trig_AvisoHoras`).
|
||||
- Señales de visibilidad HMI para los distintos tiempos (`VisTiempoRecirculacion`, etc.) y para el paro de mantenimiento.
|
||||
- Orden interna de reset de tiempos (`t_OrdenReset`) que se activa tras la pulsación autorizada del reset de mantenimiento, reinicializando los contadores pertinentes.
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15025_ZC_CONTADOR_TIEMPO` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_CONTADOR_TIEMPO`, `UDT_ZC_PULSADOR` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 28.07.2023 | (HCR/ABH) | Primera versión. Cambio en lógica funcionamiento del bloque. Además de la gestión de alarma mantenimiento, se añade gestión de horas de funcionamiento totales de la máquina. Se añade tiempo de planta parada con enzimático de la máquina. |
|
||||
| 01.00.01 | 04.03.2024 | (ABH) | Se corrige gestión de tiempo total de producción. |
|
||||
| 01.00.02 | 23.05.2024 | (HCR) | Se añade salida visibilidad para tiempo de recirculación. |
|
||||
| 01.00.03 | 29.10.2025 | (ABH) | Se corrige gestión de reset tiempo enzimática. |
|
||||
| 01.00.04 | 03.12.2025 | (ABH) | Se añade tiempo de limpieza y tiempo de pausa. |
|
||||
| 01.01.00 | 03.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION PULSADORES
|
||||
|
||||
// Pulsador comprobacion contraseña
|
||||
"FC15026_ZC_PULSADOR"(Pulso1Seg:=#Pulso1Seg,
|
||||
SP_Tiempo:=2,
|
||||
TrazaCategoria:="TRZ_CAT_4_PRO_PUL",
|
||||
TrazaIdProceso:=#ProcesoID,
|
||||
TrazaIdPulsador:="TRZ_SYS_PUL_HOR_MAQ_RST",
|
||||
Usuario:=#Usuario,
|
||||
FechaHoraActual:=#FechaHora,
|
||||
Pulsador:=#Pulsador);
|
||||
|
||||
END_REGION PULSADORES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION PARO_MANTENIMIENTO
|
||||
|
||||
// Condicion de paro por mantenimiento
|
||||
#t_CondicionParo :=
|
||||
#HabilitarMant AND
|
||||
(#TiempoMantenimiento.Hora = #SP_HorasAlarma) AND
|
||||
(#FechaHora.MINUTE = #SP_MinutosAlarma);
|
||||
|
||||
// Con paro por mantenimiento, activamos la marca de paro
|
||||
IF #t_CondicionParo AND NOT #s_OldCondicionParo THEN
|
||||
#s_PasswordCalculado := 0;
|
||||
#ParoMantenimiento := TRUE;
|
||||
END_IF;
|
||||
|
||||
// Estado anterior condicion paro por mantenimiento
|
||||
#s_OldCondicionParo := #t_CondicionParo;
|
||||
|
||||
|
||||
// Ligica de paro y calculo de contraseña
|
||||
IF #ParoMantenimiento THEN
|
||||
|
||||
// Calculo de contraseña
|
||||
#s_PasswordCalculado := #FechaHora.YEAR + #FechaHora.MONTH + #FechaHora.DAY;
|
||||
#Pulsador.Permiso := TRUE;
|
||||
#Pulsador.Visibilidad := TRUE;
|
||||
|
||||
// Comprobacion de contraseñas desde HMI
|
||||
IF #Pulsador.Plc THEN
|
||||
|
||||
// Contraseña correcta, reseteamos todo
|
||||
IF #s_PasswordCalculado = #PasswordHMI THEN
|
||||
#s_PasswordCalculado := 0;
|
||||
#PasswordHMI := 0;
|
||||
#ParoMantenimiento := FALSE;
|
||||
#t_OrdenReset := TRUE;
|
||||
|
||||
ELSE
|
||||
// Contraseña incorrecta
|
||||
#PasswordHMI := 0;
|
||||
#t_OrdenReset := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
#t_OrdenReset := FALSE;
|
||||
END_IF;
|
||||
|
||||
ELSE
|
||||
// Reset de estados si no tenemos la señal de paro por mantenimiento
|
||||
#Pulsador.Permiso := FALSE;
|
||||
#Pulsador.Visibilidad := FALSE;
|
||||
#t_OrdenReset := FALSE;
|
||||
|
||||
END_IF;
|
||||
|
||||
// Si no esta habilitado el paro por mantenimiento, reseteamos
|
||||
IF NOT #HabilitarMant THEN
|
||||
#ParoMantenimiento := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION PARO_MANTENIMIENTO
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CONTADORES
|
||||
|
||||
// Resolución de flancos en memoria temporal para Clean Code
|
||||
#t_ResetProdActual := #IniciarTiempoProd AND NOT #s_OldInicioProduccion;
|
||||
#s_OldInicioProduccion := #IniciarTiempoProd;
|
||||
|
||||
#t_ResetLimpieza := #IniciarTiempoCIP AND NOT #s_OldInicioCIP;
|
||||
#s_OldInicioCIP := #IniciarTiempoCIP;
|
||||
|
||||
#t_ResetPausa := #IniciarTiempoPausa AND NOT #s_OldInicioPausa;
|
||||
#s_OldInicioPausa := #IniciarTiempoPausa;
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de mantenimiento
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg:=#Pulso1Seg,
|
||||
Iniciar:=#HabilitarMant AND #IniciarTiempoMaquina,
|
||||
Reset:=#t_OrdenReset OR NOT #HabilitarMant,
|
||||
Contador:=#TiempoMantenimiento);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo total Maquina
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoMaquina,
|
||||
Reset := FALSE,
|
||||
Contador := #TiempoMaquina);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de produccion actual
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoProd,
|
||||
Reset := #t_ResetProdActual,
|
||||
Contador := #TiempoProduccionActual);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de produccion total
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoProd,
|
||||
Reset := FALSE,
|
||||
Contador := #TiempoProduccionTotal);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de recirculacion
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoRecirc,
|
||||
Reset := NOT #IniciarTiempoRecirc,
|
||||
Contador := #TiempoRecirculacion);
|
||||
// Visibilidad tiempo recirculacion
|
||||
#VisTiempoRecirculacion := #IniciarTiempoRecirc;
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de planta con enzimatico
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoEnzim,
|
||||
Reset := #ResetTiempoEnzim,
|
||||
Contador := #TiempoEnzimatica);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo de limpieza
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoCIP,
|
||||
Reset := #t_ResetLimpieza,
|
||||
Contador := #TiempoLimpieza);
|
||||
|
||||
// ==========================================================================================================
|
||||
// Contador de tiempo en pausa
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #IniciarTiempoPausa,
|
||||
Reset := #t_ResetPausa,
|
||||
Contador := #TiempoPausa);
|
||||
|
||||
END_REGION CONTADORES
|
||||
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
FUNCTION_BLOCK "FB15056_ZC_SIVE_MEMBRANA_CARE"
|
||||
TITLE = FB15056_ZC_REGISTRO_MEMBRANAS
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : HCR
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de funcion para la gestion del registro de membranas
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso 1 Segundo
|
||||
OrdenRegistroGeneral : Bool; // OrdenRegistroGeneral
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
Iniciar : Bool; // Orden contador de tiempo
|
||||
END_VAR
|
||||
VAR_INPUT RETAIN
|
||||
Usuario : String[25]; // Usuario
|
||||
END_VAR
|
||||
VAR_INPUT
|
||||
TecnicoRegistroGeneral : String[20]; // Tecnico registro general
|
||||
END_VAR
|
||||
VAR_INPUT RETAIN
|
||||
TiempoAvisoOn : Int; // Tiempo indicación aviso On
|
||||
TiempoAvisoOff : Int; // Tiempo indicación aviso Off
|
||||
TiempoAlarmaOn : Int; // Tiempo indicación alarma On
|
||||
TiempoAlarmaOff : Int; // Tiempo indicación alarma Off
|
||||
HorasAviso : Int; // Horas para aviso
|
||||
HorasAlarma : Int; // Horas para alarma
|
||||
HorasAlarmaCritica : Int; // Horas para alarma critica
|
||||
END_VAR
|
||||
|
||||
VAR_OUTPUT
|
||||
Aviso : Bool; // Estado de aviso
|
||||
Alarma : Bool; // Estado de alarma
|
||||
AlarmaCritica : Bool; // Estado de alarma critica
|
||||
Estado : Int; // Estado
|
||||
TiempoMembranaRestante : UDInt; // Tiempo membrana restante
|
||||
END_VAR
|
||||
|
||||
VAR_IN_OUT
|
||||
OrdenBorrar : Bool; // Ordrn borrar registros
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
Registros { S7_SetPoint := 'False'} : Array[1..#N_REGISTROS] of "UDT_ZC_SIVE_MEMBRANA_CARE";
|
||||
END_VAR
|
||||
VAR
|
||||
Pulsador { S7_SetPoint := 'False'} : "UDT_ZC_PULSADOR"; // Pulsador nuevo registro
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
Tiempo { S7_SetPoint := 'False'} : "UDT_ZC_CONTADOR_TIEMPO"; // Tiempo actual membranas
|
||||
s_PuestaMarchaAno : UInt; // Fecha de puesta en marcha
|
||||
s_PuestaMarchaMes : Int; // Fecha de puesta en marcha
|
||||
s_PuestaMarchaDia : Int; // Fecha de puesta en marcha
|
||||
s_Indice : Int := 1; // Indice registro
|
||||
s_TecnicoNuevoRegistro : String[20]; // Nombre tecnico nuevo registro
|
||||
s_FlipFlopAviso { S7_SetPoint := 'False'} : "UDT_ZC_DISP_FF";
|
||||
s_FlipFlopAlarma { S7_SetPoint := 'False'} : "UDT_ZC_DISP_FF";
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int; // Bucle para recorrer los registros
|
||||
t_OrdenReset : Bool; // Orden Reset contador de horas
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
N_REGISTROS : Int := 10; // Número de registros
|
||||
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 `FB15056_ZC_REGISTRO_MEMBRANAS` implementa la gestión integral del registro y vida útil de las membranas. Mantiene un histórico circular de intervenciones (`Registros[i]`), controla el tiempo de uso acumulado y genera los avisos, alarmas y alarma crítica en función de las horas restantes, incluyendo la posibilidad de registrar cambios generales de forma masiva.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Registro de intervención por pulsador: el bloque gestiona un pulsador (`FC15026_ZC_PULSADOR`) con permiso dependiente de que haya un técnico introducido en `#s_TecnicoNuevoRegistro`. Al confirmarse la pulsación (`Pulsador.Plc`), se almacena en `#Registros[#s_Indice]` la fecha/hora convertida con `FC15005_ZC_DTL_TO_ZC_FECHA`, el técnico y el tiempo de membrana (`#Tiempo.Hora`), se limpia el técnico y se dispara la orden interna `#t_OrdenReset` para reiniciar el contador de tiempo. El índice avanza de forma circular hasta `#N_REGISTROS`.
|
||||
- Registro general: la entrada `#OrdenRegistroGeneral` permite registrar un cambio de membrana sin pulsador físico, asociando el técnico definido en `#TecnicoRegistroGeneral` y siguiendo la misma lógica circular de índice.
|
||||
- Contador de tiempo de membrana: mediante `FC15025_ZC_CONTADOR_TIEMPO` se acumula el tiempo de uso en horas, con posibilidad de reset a través de `#t_OrdenReset`.
|
||||
- Cálculo de horas restantes: `#TiempoMembranaRestante` se calcula como la diferencia entre `#HorasAlarmaCritica` y `#Tiempo.Hora`, acotado a `0` para evitar desbordamientos cuando se supera el umbral crítico.
|
||||
- Borrado de registros: la entrada `#OrdenBorrar` limpia completamente el array de registros (fecha, hora, técnico y tiempo de membrana) y reinicia el índice de escritura a `1`.
|
||||
- Estado global por tramos: clasificación del estado en `#Estado` (0: Normal, 1: Aviso, 2: Alarma, 3: Alarma crítica) según el rango de horas acumulado frente a `#HorasAviso`, `#HorasAlarma` y `#HorasAlarmaCritica`.
|
||||
- Aviso y Alarma intermitentes: se generan mediante dos Flip-Flop (`FC2926_ZC_FF_INDV`) con tiempos de encendido/apagado configurables (`#TiempoAvisoOn/Off`, `#TiempoAlarmaOn/Off`) para producir señales parpadeantes. La alarma crítica (`AlarmaCritica`) es continua y se activa definitivamente al alcanzar `#HorasAlarmaCritica`.
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15026_ZC_PULSADOR`, `FC15025_ZC_CONTADOR_TIEMPO`, `FC2926_ZC_FF_INDV`, `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `ZC_FECHA`, `UDT_ZC_PULSADOR`, `UDT_ZC_CONTADOR_TIEMPO`. `UDT_ZC_SIVE_MEMBRANA_CARE` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 10.05.2023 | (HCR) | Primera versión. |
|
||||
| 01.00.01 | 02.10.2023 | (ABH) | Cambio nombre a SIVE MEMBRANA CARE. Se corrigen permisos variables estáticas. Se corrigen nombres de variables. Se crea UDT `registro membranas`. Se cambia tipo de dato fecha/hora string a `ZC_FECHA`. Se quitan temporizadores y se utiliza Flip-Flop individual. Se eliminan variables innecesarias. |
|
||||
| 01.00.02 | 16.01.2024 | (ABH) | Se limita el tiempo restante de las membranas para que no se desborde. |
|
||||
| 01.00.03 | 02.12.2025 | (ABH) | Se corrige cálculo tiempo horas restantes. |
|
||||
| 01.00.04 | 10.01.2026 | (CNR) | Se añade orden y gestión de registro general. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// =============================================================================
|
||||
REGION ORDEN_REGISTRO
|
||||
|
||||
#Pulsador.Permiso := (#s_TecnicoNuevoRegistro <> '');
|
||||
"FC15026_ZC_PULSADOR"(Pulso1Seg := #Pulso1Seg,
|
||||
SP_Tiempo := 2,
|
||||
TrazaCategoria:=0,
|
||||
TrazaIdProceso:=0,
|
||||
TrazaIdPulsador:=0,
|
||||
Usuario := #Usuario,
|
||||
FechaHoraActual := #FechaHora,
|
||||
Pulsador := #Pulsador);
|
||||
|
||||
// Orden pulsador
|
||||
IF #Pulsador.Plc THEN
|
||||
|
||||
#Registros[#s_Indice].FechaHora := "FC15005_ZC_DTL_TO_ZC_FECHA"( #FechaHora);
|
||||
#Registros[#s_Indice].Tecnico := #s_TecnicoNuevoRegistro;
|
||||
#Registros[#s_Indice].TiempoMembrana := #Tiempo.Hora;
|
||||
|
||||
// Reset valor técnico y orden reset tiempo
|
||||
#s_TecnicoNuevoRegistro := '';
|
||||
|
||||
#t_OrdenReset := TRUE;
|
||||
|
||||
// Incrementamos indice y si es mayor que el número máximo de registro lo ponemos en la posición inicial
|
||||
#s_Indice += 1;
|
||||
IF #s_Indice > #N_REGISTROS THEN
|
||||
#s_Indice := 1;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
// Orden registro general
|
||||
IF #OrdenRegistroGeneral THEN
|
||||
|
||||
#Registros[#s_Indice].FechaHora := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHora);
|
||||
#Registros[#s_Indice].Tecnico := #TecnicoRegistroGeneral;
|
||||
#Registros[#s_Indice].TiempoMembrana := #Tiempo.Hora;
|
||||
|
||||
// Reset valor técnico y orden reset tiempo
|
||||
#t_OrdenReset := TRUE;
|
||||
|
||||
// Incrementamos indice y si es mayor que el número máximo de registro lo ponemos en la posición inicial
|
||||
#s_Indice += 1;
|
||||
IF #s_Indice > #N_REGISTROS THEN
|
||||
#s_Indice := 1;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_REGION ORDEN_REGISTRO
|
||||
|
||||
|
||||
// =============================================================================
|
||||
REGION TIEMPO_MEMBRANAS
|
||||
|
||||
// Contador de tiempo
|
||||
"FC15025_ZC_CONTADOR_TIEMPO"(Pulso1seg := #Pulso1Seg,
|
||||
Iniciar := #Iniciar,
|
||||
Contador := #Tiempo,
|
||||
Reset := #t_OrdenReset);
|
||||
|
||||
// Horas Restante
|
||||
IF INT_TO_UDINT(#HorasAlarmaCritica) > #Tiempo.Hora THEN
|
||||
#TiempoMembranaRestante := INT_TO_UDINT(#HorasAlarmaCritica) - #Tiempo.Hora;
|
||||
ELSE
|
||||
#TiempoMembranaRestante := 0;
|
||||
END_IF;
|
||||
|
||||
END_REGION TIEMPO_MEMBRANAS
|
||||
|
||||
|
||||
// =============================================================================
|
||||
REGION BORRAR_REGISTROS
|
||||
|
||||
IF #OrdenBorrar THEN
|
||||
|
||||
FOR #for_i := 1 TO #N_REGISTROS DO
|
||||
|
||||
#Registros[#for_i].FechaHora.Ano := 0;
|
||||
#Registros[#for_i].FechaHora.Mes := 0;
|
||||
#Registros[#for_i].FechaHora.Dia := 0;
|
||||
#Registros[#for_i].FechaHora.Hora := 0;
|
||||
#Registros[#for_i].FechaHora.Minuto := 0;
|
||||
#Registros[#for_i].FechaHora.Segundo := 0;
|
||||
#Registros[#for_i].FechaHora.NanoSegundo := 0;
|
||||
|
||||
#Registros[#for_i].Tecnico := '';
|
||||
#Registros[#for_i].TiempoMembrana := 0;
|
||||
#s_Indice := 1;
|
||||
|
||||
END_FOR;
|
||||
|
||||
#OrdenBorrar := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION BORRAR_REGISTROS
|
||||
|
||||
|
||||
// =============================================================================
|
||||
REGION ESTADO
|
||||
|
||||
#s_FlipFlopAviso.Orden_Activar := FALSE;
|
||||
#s_FlipFlopAviso.Config_SetPointTiempoFlip := #TiempoAvisoOn;
|
||||
#s_FlipFlopAviso.Config_SetPointTiempoFlop := #TiempoAvisoOff;
|
||||
#s_FlipFlopAlarma.Orden_Activar := FALSE;
|
||||
#s_FlipFlopAlarma.Config_SetPointTiempoFlip := #TiempoAlarmaOn;
|
||||
#s_FlipFlopAlarma.Config_SetPointTiempoFlop := #TiempoAlarmaOff;
|
||||
|
||||
// Estado Aviso
|
||||
#Estado := 0;
|
||||
|
||||
IF #Tiempo.Hora >= #HorasAviso AND #Tiempo.Hora < #HorasAlarma THEN
|
||||
#s_FlipFlopAviso.Orden_Activar := TRUE;
|
||||
#Aviso := #s_FlipFlopAviso.#Estado_Flip;
|
||||
#Estado := 1;
|
||||
ELSE
|
||||
#Aviso := FALSE;
|
||||
END_IF;
|
||||
|
||||
|
||||
// Estado Alarma
|
||||
IF #Tiempo.Hora >= #HorasAlarma AND #Tiempo.Hora < #HorasAlarmaCritica THEN
|
||||
#s_FlipFlopAlarma.Orden_Activar := TRUE;
|
||||
#Alarma := #s_FlipFlopAlarma.#Estado_Flip;
|
||||
#Estado := 2;
|
||||
ELSE
|
||||
#Alarma := FALSE;
|
||||
END_IF;
|
||||
|
||||
|
||||
// Estado Alarma Crítica
|
||||
IF #Tiempo.Hora >= #HorasAlarmaCritica THEN
|
||||
#AlarmaCritica := TRUE;
|
||||
#Estado := 3;
|
||||
ELSE
|
||||
#AlarmaCritica := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION ESTADO
|
||||
|
||||
|
||||
// =============================================================================
|
||||
REGION GESTION_FF
|
||||
|
||||
// =============================================================================
|
||||
// Flip Flop aviso
|
||||
"FC2926_ZC_FF_INDV"(Pulso1Seg := #Pulso1Seg,
|
||||
FF := #s_FlipFlopAviso);
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Flip Flop alarma
|
||||
"FC2926_ZC_FF_INDV"(Pulso1Seg := #Pulso1Seg,
|
||||
FF := #s_FlipFlopAlarma);
|
||||
|
||||
|
||||
END_REGION GESTION_FF
|
||||
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
FUNCTION_BLOCK "FB15057_ZC_CONT_PROD_MEM"
|
||||
TITLE = FB15057_ZC_CONT_PROD_MEM
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Bloque de funcion para gestion de contadores de produccion maquinas membranas
|
||||
VAR_INPUT
|
||||
InicioProduccion : Bool; // En etapa inicio produccion
|
||||
EnProduccion : Bool; // En etapas de produccion
|
||||
FinProduccion : Bool; // En etapa fin de produccion
|
||||
FechaHoraActual {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL; // Fecha y hora actual
|
||||
LitrosEntrada : LReal; // Totalizador litros entrada
|
||||
LitrosConcentrado : LReal; // Totalizador litros concentrado
|
||||
LitrosPermeado : LReal; // Totalizador litros permeado
|
||||
FCV : Real; // Factor de concentradion
|
||||
Brix : LReal; // Media de grados BRIX
|
||||
TempAlimentacion : LReal; // Temperatura alimentacion
|
||||
TempConcentrado : LReal; // Temperatura Concentrado
|
||||
TempPermeado : LReal; // Temperatura Permeado
|
||||
BorrarParcial : Bool; // Borrar datos parciales
|
||||
END_VAR
|
||||
|
||||
VAR RETAIN
|
||||
Ultima { S7_SetPoint := 'False'} : "UDT_ZC_CONT_PROD_MEM";
|
||||
Penultima { S7_SetPoint := 'False'} : "UDT_ZC_CONT_PROD_MEM";
|
||||
Parcial { S7_SetPoint := 'False'} : "UDT_ZC_CONT_PROD_MEM";
|
||||
Total { S7_SetPoint := 'False'} : "UDT_ZC_CONT_PROD_MEM";
|
||||
END_VAR
|
||||
VAR
|
||||
s_OldInicioProd { S7_SetPoint := 'True'} : Bool;
|
||||
s_OldFinProd { S7_SetPoint := 'True'} : Bool;
|
||||
s_InicioProduccion : Bool; // Orden inicio produccion
|
||||
s_FinProduccion : Bool; // Orden fin de produccion
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
//=======================================================================
|
||||
// (C)Copyright ZeusControl 2024 - 2026
|
||||
//=======================================================================
|
||||
(*
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
Bloque de funcion que implementa la gestión de los contadores y totalizadores de producción de una máquina de membranas, manteniendo la trazabilidad histórica de la última y penúltima producción, así como los acumulados parciales y totales, junto con el cálculo del factor de conversión volumétrica (FCV) asociado a cada periodo.
|
||||
|
||||
Funcionalidades principales:
|
||||
- Detección de flanco ascendente en las órdenes `#InicioProduccion` y `#FinProduccion` mediante las variables estáticas `#s_P_Trig_InicioProd` y `#s_P_Trig_FinProd`, generando los pulsos internos `#s_InicioProduccion` y `#s_FinProduccion` para evitar disparos múltiples por nivel mantenido.
|
||||
- Inicio de producción: al recibir `#s_InicioProduccion` se trasladan los datos de la última producción a la estructura `#Penultima`, se inicializan a cero los campos analíticos y de fecha de `#Ultima`, y se registra la fecha/hora de inicio en `#Ultima.FechaInicio` mediante la conversión realizada por `FC15005_ZC_DTL_TO_ZC_FECHA`.
|
||||
- Datos en curso: mientras `#EnProduccion` está activo, se copian en `#Ultima` las variables de proceso (`LitrosEntrada`, `LitrosConcentrado`, `Brix`, `TempAlimentacion`, `TempConcentrado`, `TempPermeado`), manteniendo actualizada la instantánea de la producción en marcha.
|
||||
- Fin de producción: al detectar `#s_FinProduccion` se registra la fecha/hora de fin en `#Ultima.FechaFin` y se acumulan los valores de la producción actual sobre los contadores `#Parcial` y `#Total`, tanto de litros de entrada como de concentrado.
|
||||
- Cálculo de litros de permeado por diferencia (`LitrosEntrada - LitrosConcentrado`) para las cuatro estructuras: `#Ultima`, `#Penultima`, `#Parcial` y `#Total`.
|
||||
- Cálculo del factor de conversión volumétrica (FCV) para cada estructura con protección frente a división por cero (cuando `#LitrosEntrada` o `#LitrosConcentrado` son menores o iguales a `0.0`, el resultado se fija en `0.0`).
|
||||
- Reset de la producción parcial: la entrada `#BorrarParcial` reinicia los litros del contador parcial y actualiza `#Parcial.FechaInicio` con la fecha/hora actual.
|
||||
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15005_ZC_DTL_TO_ZC_FECHA` |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_CONTADORES_PRODUCCION` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 01.00.00 | 29.09.2023 | (ABH) | Primera versión. |
|
||||
| 01.00.01 | 04.03.2024 | (ABH) | Se corrige gestión de marca fin de producción. |
|
||||
| 01.00.02 | 03.07.2026 | (ABH) | Cambio a SCL. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_ORDENES
|
||||
|
||||
// Inicio de produccion
|
||||
#s_InicioProduccion := #InicioProduccion AND NOT #s_OldInicioProd;
|
||||
|
||||
// Fin de produccion
|
||||
#s_FinProduccion := #FinProduccion AND NOT #s_OldFinProd;
|
||||
|
||||
// Estados anteriores
|
||||
#s_OldInicioProd := #InicioProduccion;
|
||||
#s_OldFinProd := #FinProduccion;
|
||||
|
||||
END_REGION GESTION_ORDENES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION MOVIMIENTO_DE_DATOS
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION INICIO_PRODUCCION
|
||||
|
||||
IF #s_InicioProduccion THEN
|
||||
|
||||
// =================================================================================================
|
||||
// Traspaso de datos de ultima produccion a penultima produccion
|
||||
#Penultima.LitrosEntrada := #Ultima.LitrosEntrada;
|
||||
#Penultima.LitrosConcentrado := #Ultima.LitrosConcentrado;
|
||||
#Penultima.Brix := #Ultima.Brix;
|
||||
#Penultima.TempAlimentacion := #Ultima.TempAlimentacion;
|
||||
#Penultima.TempConcentrado := #Ultima.TempConcentrado;
|
||||
#Penultima.FechaInicio := #Ultima.FechaInicio;
|
||||
#Penultima.FechaFin := #Ultima.FechaFin;
|
||||
|
||||
|
||||
// =================================================================================================
|
||||
// Reset datos ultima produccion
|
||||
#Ultima.LitrosEntrada := 0.0;
|
||||
#Ultima.LitrosConcentrado := 0.0;
|
||||
#Ultima.Brix := 0.0;
|
||||
#Ultima.TempAlimentacion := 0.0;
|
||||
#Ultima.TempConcentrado := 0.0;
|
||||
#Ultima.FechaInicio.Ano := 0;
|
||||
#Ultima.FechaInicio.Mes := 0;
|
||||
#Ultima.FechaInicio.Dia := 0;
|
||||
#Ultima.FechaInicio.Hora := 0;
|
||||
#Ultima.FechaInicio.Minuto := 0;
|
||||
#Ultima.FechaInicio.Segundo := 0;
|
||||
#Ultima.FechaFin.Ano := 0;
|
||||
#Ultima.FechaFin.Mes := 0;
|
||||
#Ultima.FechaFin.Dia := 0;
|
||||
#Ultima.FechaFin.Hora := 0;
|
||||
#Ultima.FechaFin.Minuto := 0;
|
||||
#Ultima.FechaFin.Segundo := 0;
|
||||
|
||||
|
||||
// =================================================================================================
|
||||
// Guardamos la fecha y hora de inicio de la produccion
|
||||
#Ultima.FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION INICIO_PRODUCCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
// Movimientos de datos durante la produccion
|
||||
IF #EnProduccion THEN
|
||||
|
||||
#Ultima.LitrosEntrada := #LitrosEntrada;
|
||||
#Ultima.LitrosConcentrado := #LitrosConcentrado;
|
||||
#Ultima.Brix := #Brix;
|
||||
#Ultima.TempAlimentacion := #TempAlimentacion;
|
||||
#Ultima.TempConcentrado := #TempConcentrado;
|
||||
#Ultima.TempPermeado := #TempPermeado;
|
||||
END_IF;
|
||||
|
||||
END_REGION DATOS_DURANTE_PRODUCCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION DATOS_AL_FIN_PRODUCCION
|
||||
|
||||
// Movimiento de datos al finalizar la produccion
|
||||
IF #s_FinProduccion THEN
|
||||
|
||||
// Fecha fin
|
||||
#Ultima.FechaFin := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
|
||||
|
||||
// Suma de datos parciales y totales
|
||||
#Parcial.LitrosEntrada := #Ultima.LitrosEntrada + #Parcial.LitrosEntrada;
|
||||
#Parcial.LitrosConcentrado := #Ultima.LitrosConcentrado + #Parcial.LitrosConcentrado;
|
||||
#Total.LitrosEntrada := #Ultima.LitrosEntrada + #Total.LitrosEntrada;
|
||||
#Total.LitrosConcentrado := #Ultima.LitrosConcentrado + #Total.LitrosConcentrado;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION DATOS_AL_FIN_PRODUCCION
|
||||
|
||||
|
||||
|
||||
END_REGION MOVIMIENTO_DE_DATOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION TOTALIZADORES
|
||||
|
||||
// Ultima produccion
|
||||
#Ultima.LitrosPermeado := #Ultima.LitrosEntrada - #Ultima.LitrosConcentrado;
|
||||
|
||||
// Penultima produccion
|
||||
#Penultima.LitrosPermeado := #Penultima.LitrosEntrada - #Penultima.LitrosConcentrado;
|
||||
|
||||
// Produccion parcial
|
||||
#Parcial.LitrosPermeado := #Parcial.LitrosEntrada - #Parcial.LitrosConcentrado;
|
||||
|
||||
// Produccion total
|
||||
#Total.LitrosPermeado := #Total.LitrosEntrada - #Total.LitrosConcentrado;
|
||||
|
||||
END_REGION TOTALIZADORES
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION FCV
|
||||
|
||||
// FCV Ultima produccion
|
||||
IF #Ultima.LitrosEntrada > 0.0 AND #Ultima.LitrosConcentrado > 0.0 THEN
|
||||
#Ultima.FCV := LREAL_TO_REAL(#Ultima.LitrosEntrada / #Ultima.LitrosConcentrado);
|
||||
ELSE
|
||||
#Ultima.FCV := 0.0;
|
||||
END_IF;
|
||||
|
||||
// FCV Penultima produccion
|
||||
IF #Penultima.LitrosEntrada > 0.0 AND #Penultima.LitrosConcentrado > 0.0 THEN
|
||||
#Penultima.FCV := LREAL_TO_REAL(#Penultima.LitrosEntrada / #Penultima.LitrosConcentrado);
|
||||
ELSE
|
||||
#Penultima.FCV := 0.0;
|
||||
END_IF;
|
||||
|
||||
// FCV Produccion parcial
|
||||
IF #Parcial.LitrosEntrada > 0.0 AND #Parcial.LitrosConcentrado > 0.0 THEN
|
||||
#Parcial.FCV := LREAL_TO_REAL(#Parcial.LitrosEntrada / #Parcial.LitrosConcentrado);
|
||||
ELSE
|
||||
#Parcial.FCV := 0.0;
|
||||
END_IF;
|
||||
|
||||
// FCV Produccion Total
|
||||
IF #Total.LitrosEntrada > 0.0 AND #Total.LitrosConcentrado > 0.0 THEN
|
||||
#Total.FCV := LREAL_TO_REAL(#Total.LitrosEntrada / #Total.LitrosConcentrado);
|
||||
ELSE
|
||||
#Total.FCV := 0.0;
|
||||
END_IF;
|
||||
|
||||
END_REGION FCV
|
||||
|
||||
END_REGION CALCULOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION RESET_DATOS
|
||||
|
||||
// Reset produccion parcial
|
||||
IF #BorrarParcial THEN
|
||||
#Parcial.LitrosEntrada := 0.0;
|
||||
#Parcial.LitrosConcentrado := 0.0;
|
||||
#Parcial.FechaInicio := "FC15005_ZC_DTL_TO_ZC_FECHA"(#FechaHoraActual);
|
||||
END_IF;
|
||||
|
||||
END_REGION RESET_DATOS
|
||||
|
||||
END_FUNCTION_BLOCK
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
FUNCTION "FC15106_ZC_GESTION_LISTA" : Void
|
||||
TITLE = FC15106_ZC_GESTION_LISTA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Funcion de gestion listas
|
||||
VAR_IN_OUT
|
||||
Lista : Array[*] of "UDT_ZC_LISTA_ORIG_DEST";
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
for_j : Int;
|
||||
t_Index : Int;
|
||||
t_LowerBound : Int;
|
||||
t_UpperBound : Int;
|
||||
t_YaExiste : Bool;
|
||||
t_ListaTemporal : Array[0..100] of "UDT_ZC_LISTA_ORIG_DEST";
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2025 - 2025
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Límite de listas de tipo `UDT_ZC_LISTA_ORIG_DEST` con 100 posiciones.
|
||||
|
||||
Función encargada de gestionar, limpiar y compactar listas de valores enteros.
|
||||
|
||||
- Calcular dinámicamente los límites del array de entrada `#Lista` mediante las instrucciones `LOWER_BOUND` y `UPPER_BOUND`.
|
||||
- Inicializar a cero una lista temporal interna (`#t_ListaTemporal`) adaptada a la longitud del array procesado.
|
||||
- Analizar cíclicamente los elementos de la `#Lista` para filtrar y omitir de forma automática aquellos que posean valor cero.
|
||||
- Identificar y suprimir las entradas duplicadas para garantizar un conjunto final de datos compuesto exclusivamente por valores únicos.
|
||||
- Compactar los datos filtrados y transferirlos de vuelta a la `#Lista` original, reescribiendo los valores secuencialmente desde su límite inferior.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | - |
|
||||
| UDT | `UDT_ZC_LISTA_ORIG_DEST` |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 00.00.01 | 27.06.2025 | (ABH) | Primera version. |
|
||||
| 01.00.00 | 03.07.2026 | (ABH) | Cambio en tipo de datos de INT a `UDT_ZC_LISTA_ORIG_DEST`. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION CALCULOS
|
||||
|
||||
// Obtener límites reales del array
|
||||
#t_LowerBound := DINT_TO_INT(LOWER_BOUND(ARR := #Lista, DIM := 1));
|
||||
#t_UpperBound := DINT_TO_INT(UPPER_BOUND(ARR := #Lista, DIM := 1));
|
||||
|
||||
// Inicializar lista temporal
|
||||
FOR #for_i := 1 TO DINT_TO_INT((#t_UpperBound - #t_LowerBound + 1)) DO
|
||||
#t_ListaTemporal[#for_i].Id := 0;
|
||||
#t_ListaTemporal[#for_i].Consigna := 0;
|
||||
END_FOR;
|
||||
|
||||
END_REGION CALCULOS
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_LISTA
|
||||
|
||||
// Compactar y eliminar duplicados
|
||||
#t_Index := 1;
|
||||
FOR #for_i := #t_LowerBound TO #t_UpperBound DO
|
||||
IF #Lista[#for_i].Id <> 0 THEN
|
||||
#t_YaExiste := FALSE;
|
||||
|
||||
FOR #for_j := 1 TO #t_Index - 1 DO
|
||||
IF #t_ListaTemporal[#for_j].Id = #Lista[#for_i].Id THEN
|
||||
#t_YaExiste := TRUE;
|
||||
EXIT;
|
||||
END_IF;
|
||||
END_FOR;
|
||||
|
||||
IF NOT #t_YaExiste THEN
|
||||
#t_ListaTemporal[#t_Index] := #Lista[#for_i];
|
||||
#t_Index := #t_Index + 1;
|
||||
END_IF;
|
||||
END_IF;
|
||||
END_FOR;
|
||||
|
||||
// Copiar de vuelta a lista original
|
||||
FOR #for_i := #t_LowerBound TO #t_UpperBound DO
|
||||
#Lista[#for_i] := #t_ListaTemporal[#for_i - #t_LowerBound + 1];
|
||||
END_FOR;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
DATA_BLOCK "DB20_GESTION_SCADA"
|
||||
TITLE = DB16_GESTION_SCADA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
NON_RETAIN
|
||||
VAR
|
||||
BitDevida : Array[0.."N_MAX_SCADA"] of Bool;
|
||||
ConexionOk : Array[0.."N_MAX_SCADA"] of Bool;
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
Maestro : Int; // -1= NINGUNO / 10= SCADA01 / 11= SCADA02
|
||||
END_VAR
|
||||
VAR
|
||||
PermisoInformes : Array[0.."N_MAX_SCADA"] of Bool;
|
||||
Sincronizacion : Struct
|
||||
AmbosConectados : Bool;
|
||||
Informes : Array[0.."N_MAX_SCADA"] of Int;
|
||||
CIP : Array[0.."N_MAX_SCADA"] of Int;
|
||||
Fermentadores : Array[0.."N_MAX_SCADA"] of Int;
|
||||
Cocina1 : Array[0.."N_MAX_SCADA"] of Int;
|
||||
END_STRUCT;
|
||||
BitVida : Array[0.."N_MAX_SCADA"] of Struct
|
||||
TON_ON { S7_SetPoint := 'False'} : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
TON_OFF : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
END_STRUCT;
|
||||
END_VAR
|
||||
VAR RETAIN
|
||||
TON_CIP_ESTADO : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
TON_INFORME_ESTADO : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
TON_FERM_ESTADO : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
TON_COCINA1_ESTADO : Array[0..1] of "UDT_ZC_DISP_TON";
|
||||
END_VAR
|
||||
VAR
|
||||
Aux : Struct
|
||||
OldAmbosConectados : Bool;
|
||||
END_STRUCT;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
BitDevida[0] := TRUE;
|
||||
ConexionOk[0] := TRUE;
|
||||
Maestro := 10;
|
||||
PermisoInformes[0] := TRUE;
|
||||
Sincronizacion.AmbosConectados := FALSE;
|
||||
Sincronizacion.Informes[0] := 0;
|
||||
Sincronizacion.CIP[0] := 0;
|
||||
Sincronizacion.Fermentadores[0] := 0;
|
||||
Sincronizacion.Cocina1[0] := 0;
|
||||
Aux.OldAmbosConectados := FALSE;
|
||||
|
||||
END_DATA_BLOCK
|
||||
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
FUNCTION "FC20_GESTION_SCADA" : Void
|
||||
TITLE = FC21_GESTION_SCADA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Gestor de conexiones con SCADA, para determinar quien es el maestro en un sistema de dos equipos monopuesto
|
||||
VAR_TEMP
|
||||
for_i : Int;
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
(* (*
|
||||
ZEUS CONTROL, S.A.
|
||||
(c)Copyright (2024) All Rights Reserved
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
Software: TIA Portal 18
|
||||
Restricciones: PLC serie 1200/1500
|
||||
|
||||
Nombre: FC10_GESTION_SCADA
|
||||
Descripcion: Gestor de conexiones con SCADA, para determinar quien es el maestro en un sistema de
|
||||
dos equipos monopuesto
|
||||
|
||||
Dependencias:
|
||||
FC: FC2928_ZC_TON_INDV
|
||||
FC2929_ZC_TOF_INDV
|
||||
FB: -
|
||||
DB: -
|
||||
UDT: -
|
||||
|
||||
Change log:
|
||||
|
||||
Version Fecha Tecnico a cargo Descripcion
|
||||
|
||||
01.00.00 30.08.2024 (ABH) Primera version.
|
||||
|
||||
//=====================================================================================
|
||||
*)
|
||||
|
||||
|
||||
REGION GESTION_CONEXION_OK
|
||||
|
||||
// ====================================================================================
|
||||
// Gestion bit de vida
|
||||
FOR #for_i := 1 TO "N_MAX_SCADA" DO
|
||||
|
||||
"DB21_GESTION_SCADA".ConexionOk[#for_i] := FALSE;
|
||||
"DB21_GESTION_SCADA".TON_ON[#for_i].SP := 3;
|
||||
"DB21_GESTION_SCADA".TON_OFF[#for_i].SP := 3;
|
||||
|
||||
"DB21_GESTION_SCADA".TON_ON[#for_i].IN := "DB21_GESTION_SCADA".BitDevida[#for_i];
|
||||
"DB21_GESTION_SCADA".TON_OFF[#for_i].IN := NOT "DB21_GESTION_SCADA".BitDevida[#for_i];
|
||||
IF "DB21_GESTION_SCADA".TON_ON[#for_i].Q OR "DB21_GESTION_SCADA".TON_OFF[#for_i].Q THEN
|
||||
"DB21_GESTION_SCADA".ConexionOk[#for_i] := FALSE;
|
||||
ELSE
|
||||
"DB21_GESTION_SCADA".ConexionOk[#for_i] := TRUE;
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
REGION DEFINICION_MAESTRO
|
||||
|
||||
// Si no estan las conexion OK con ninguno de los dos SCADAS, ponemos el maestro a -1
|
||||
IF NOT "DB21_GESTION_SCADA".ConexionOk[0] AND NOT "DB21_GESTION_SCADA".ConexionOk[1] THEN
|
||||
"DB21_GESTION_SCADA".Maestro := -1;
|
||||
END_IF;
|
||||
|
||||
// Si todavia no se ha seleccionado ningun maestro, comprobamos el estado de la conexion con los dos Scadas.
|
||||
IF "DB21_GESTION_SCADA".Maestro = -1 THEN
|
||||
|
||||
// Si esta OK la conexion con SCADA01, lo marcamos como el maestro actual
|
||||
IF "DB21_GESTION_SCADA".ConexionOk[0] THEN
|
||||
"DB21_GESTION_SCADA".Maestro := 10;
|
||||
END_IF;
|
||||
|
||||
// Si esta OK la conexion con SCADA02 y el SCADA01 esta NO OK, lo marcamos como el maestro actual
|
||||
IF NOT "DB21_GESTION_SCADA".ConexionOk[0] AND "DB21_GESTION_SCADA".ConexionOk[1] THEN
|
||||
"DB21_GESTION_SCADA".Maestro := 11;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
// Reset seleccion maestro si pierde la conexion
|
||||
CASE "DB21_GESTION_SCADA".Maestro OF
|
||||
10:
|
||||
IF NOT "DB21_GESTION_SCADA".ConexionOk[0] THEN
|
||||
"DB21_GESTION_SCADA".Maestro := -1;
|
||||
END_IF;
|
||||
11:
|
||||
IF NOT "DB21_GESTION_SCADA".ConexionOk[1] THEN
|
||||
"DB21_GESTION_SCADA".Maestro := -1;
|
||||
END_IF;
|
||||
END_CASE;
|
||||
|
||||
// Gestion marcas para ejecucion de scripts
|
||||
"DB21_GESTION_SCADA".PermisoInformes[0] := "DB21_GESTION_SCADA".Maestro = 10;
|
||||
"DB21_GESTION_SCADA".PermisoInformes[1] := "DB21_GESTION_SCADA".Maestro = 11;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
REGION DEFICION_SINCRONIZACION
|
||||
|
||||
|
||||
// ====================================================================================
|
||||
// Comprobamos que estan ambos Scadas conectados
|
||||
"DB21_GESTION_SCADA".Sincronizacion.AmbosConectados := "DB21_GESTION_SCADA".ConexionOk[0] AND "DB21_GESTION_SCADA".ConexionOk[1];
|
||||
|
||||
|
||||
// ====================================================================================
|
||||
// Reseteamos ordenes de sincronizacion.
|
||||
// Si estan ambos conectados, quitamos las ordenes de sincronizacion
|
||||
IF NOT "DB21_GESTION_SCADA".Sincronizacion.AmbosConectados THEN
|
||||
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Informes[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.CIP[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Fermentadores[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Cocina1[0] := 0;
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Informes[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.CIP[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Fermentadores[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Cocina1[1] := 0;
|
||||
|
||||
END_IF;
|
||||
|
||||
|
||||
|
||||
// ====================================================================================
|
||||
// Cuando se conecten los dos SCADAs, lanzamos orden para que se sincronicen
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.AmbosConectados AND NOT "DB21_GESTION_SCADA".Aux.OldAmbosConectados THEN
|
||||
IF "DB21_GESTION_SCADA".Maestro = 10 THEN
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Informes[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.CIP[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Fermentadores[1] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Cocina1[1] := 2;
|
||||
END_IF;
|
||||
IF "DB21_GESTION_SCADA".Maestro = 11 THEN
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Informes[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.CIP[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Fermentadores[0] :=
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Cocina1[0] := 2;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
"DB21_GESTION_SCADA".Aux.OldAmbosConectados := "DB21_GESTION_SCADA".Sincronizacion.AmbosConectados;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
REGION GESTION_ESTADO_OK
|
||||
|
||||
// ====================================================================================
|
||||
// Gestion estado sinronizacion OK
|
||||
FOR #for_i := 0 TO 1 DO
|
||||
|
||||
"DB21_GESTION_SCADA".TON_CIP_ESTADO[#for_i].SP :=
|
||||
"DB21_GESTION_SCADA".TON_INFORME_ESTADO[#for_i].SP :=
|
||||
"DB21_GESTION_SCADA".TON_COCINA1_ESTADO[#for_i].SP :=
|
||||
"DB21_GESTION_SCADA".TON_FERM_ESTADO[#for_i].SP := 2;
|
||||
|
||||
|
||||
|
||||
"DB21_GESTION_SCADA".TON_CIP_ESTADO[#for_i].IN := "DB21_GESTION_SCADA".Sincronizacion.CIP[#for_i] = 4 OR "DB21_GESTION_SCADA".Sincronizacion.CIP[#for_i] = 12;
|
||||
IF "DB21_GESTION_SCADA".TON_CIP_ESTADO[#for_i].Q THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.CIP[#for_i] = 12 THEN
|
||||
"FC8_ZC_TRAZA_REGISTRO"(FechaHora:="DB1_SYS".FechaHoraActual,
|
||||
Registrar:=1,
|
||||
Categoria:="TRAZA_CAT_1_SISTEMA",
|
||||
User:='',
|
||||
Codigo1:=0,
|
||||
Codigo2:=0,
|
||||
Codigo3:=0,
|
||||
Texto:='Fallo al sincronizar registros CIP',
|
||||
CodInt_1:=_int_in_,
|
||||
CodInt_2:=_int_in_,
|
||||
CodInt_3:=_int_in_,
|
||||
CodInt_4:=_int_in_,
|
||||
CodInt_5:=_int_in_,
|
||||
CodReal_1:=_real_in_,
|
||||
CodReal_2:=_real_in_);
|
||||
END_IF;
|
||||
"DB21_GESTION_SCADA".Sincronizacion.CIP[#for_i] := 0;
|
||||
END_IF;
|
||||
|
||||
"DB21_GESTION_SCADA".TON_INFORME_ESTADO[#for_i].IN := "DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] = 4 OR "DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] = 12;
|
||||
IF "DB21_GESTION_SCADA".TON_INFORME_ESTADO[#for_i].Q THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] = 12 THEN
|
||||
"FC8_ZC_TRAZA_REGISTRO"(FechaHora := "DB1_SYS".FechaHoraActual,
|
||||
Registrar := 1,
|
||||
Categoria := "TRAZA_CAT_1_SISTEMA",
|
||||
User := '',
|
||||
Codigo1 := 0,
|
||||
Codigo2 := 0,
|
||||
Codigo3 := 0,
|
||||
Texto := 'Fallo al sincronizar registros CIP',
|
||||
CodInt_1:=_int_in_,
|
||||
CodInt_2:=_int_in_,
|
||||
CodInt_3:=_int_in_,
|
||||
CodInt_4:=_int_in_,
|
||||
CodInt_5:=_int_in_,
|
||||
CodReal_1:=_real_in_,
|
||||
CodReal_2:=_real_in_);
|
||||
END_IF;
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] := 0;
|
||||
END_IF;
|
||||
|
||||
"DB21_GESTION_SCADA".TON_COCINA1_ESTADO[#for_i].IN := "DB21_GESTION_SCADA".Sincronizacion.Cocina1[#for_i] = 4 OR "DB21_GESTION_SCADA".Sincronizacion.Cocina1[#for_i] = 12;
|
||||
IF "DB21_GESTION_SCADA".TON_COCINA1_ESTADO[#for_i].Q THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.Cocina1[#for_i] = 12 THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] = 12 THEN
|
||||
"FC8_ZC_TRAZA_REGISTRO"(FechaHora := "DB1_SYS".FechaHoraActual,
|
||||
Registrar := 1,
|
||||
Categoria := "TRAZA_CAT_1_SISTEMA",
|
||||
User := '',
|
||||
Codigo1 := 0,
|
||||
Codigo2 := 0,
|
||||
Codigo3 := 0,
|
||||
Texto := 'Fallo al sincronizar registros CIP',
|
||||
CodInt_1:=_int_in_,
|
||||
CodInt_2:=_int_in_,
|
||||
CodInt_3:=_int_in_,
|
||||
CodInt_4:=_int_in_,
|
||||
CodInt_5:=_int_in_,
|
||||
CodReal_1:=_real_in_,
|
||||
CodReal_2:=_real_in_);
|
||||
END_IF;
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Cocina1[#for_i] := 0;
|
||||
END_IF;
|
||||
END_IF;
|
||||
"DB21_GESTION_SCADA".TON_FERM_ESTADO[#for_i].IN := "DB21_GESTION_SCADA".Sincronizacion.Fermentadores[#for_i] = 4 OR "DB21_GESTION_SCADA".Sincronizacion.Fermentadores[#for_i] = 12;
|
||||
IF "DB21_GESTION_SCADA".TON_FERM_ESTADO[#for_i].Q THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.Fermentadores[#for_i] = 12 THEN
|
||||
IF "DB21_GESTION_SCADA".Sincronizacion.Informes[#for_i] = 12 THEN
|
||||
"FC8_ZC_TRAZA_REGISTRO"(FechaHora := "DB1_SYS".FechaHoraActual,
|
||||
Registrar := 1,
|
||||
Categoria := "TRAZA_CAT_1_SISTEMA",
|
||||
User := '',
|
||||
Codigo1 := 0,
|
||||
Codigo2 := 0,
|
||||
Codigo3 := 0,
|
||||
Texto := 'Fallo al sincronizar registros CIP',
|
||||
CodInt_1:=_int_in_,
|
||||
CodInt_2:=_int_in_,
|
||||
CodInt_3:=_int_in_,
|
||||
CodInt_4:=_int_in_,
|
||||
CodInt_5:=_int_in_,
|
||||
CodReal_1:=_real_in_,
|
||||
CodReal_2:=_real_in_);
|
||||
END_IF;
|
||||
"DB21_GESTION_SCADA".Sincronizacion.Fermentadores[#for_i] := 0;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
REGION GESTION_TEMPORIZADORES
|
||||
|
||||
// ====================================================================================
|
||||
// Gestion de marcas de bit de vida, reinicializamos los valores
|
||||
FOR #for_i := 0 TO 1 DO
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_ON[#for_i]);
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_OFF[#for_i]);
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_CIP_ESTADO[#for_i]);
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_INFORME_ESTADO[#for_i]);
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_COCINA1_ESTADO[#for_i]);
|
||||
"FC2928_ZC_TON_INDV"(Pulso1seg := "DB1_SYS".Pulso1seg,
|
||||
TON := "DB21_GESTION_SCADA".TON_FERM_ESTADO[#for_i]);
|
||||
END_FOR;
|
||||
|
||||
END_REGION
|
||||
*)
|
||||
END_FUNCTION
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
DATA_BLOCK "DB7_TRZ"
|
||||
TITLE = DB7_TRAZA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
NON_RETAIN
|
||||
//Bloque de datos encargado de la trazabilidad.
|
||||
VAR RETAIN
|
||||
Gestion { S7_SetPoint := 'False'} : "UDT_ZC_TRZ_GESTION";
|
||||
Buffer { S7_SetPoint := 'False'} : Array[0.."N_MAX_TRAZA_BUFFER"] of "UDT_ZC_TRZ_DATOS";
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
Gestion.HabilitacionGeneral := TRUE;
|
||||
Gestion.EstadoConexion := TRUE;
|
||||
Gestion.OrdenIniciar := FALSE;
|
||||
Gestion.HabilitarCategoria[0] := TRUE;
|
||||
Gestion.HabilitarCategoria[1] := TRUE;
|
||||
Gestion.HabilitarCategoria[2] := TRUE;
|
||||
Gestion.HabilitarCategoria[3] := TRUE;
|
||||
Gestion.HabilitarCategoria[4] := TRUE;
|
||||
Gestion.HabilitarCategoria[5] := TRUE;
|
||||
Gestion.HabilitarCategoria[6] := TRUE;
|
||||
Gestion.HabilitarCategoria[7] := TRUE;
|
||||
Gestion.HabilitarCategoria[8] := TRUE;
|
||||
Gestion.HabilitarCategoria[9] := TRUE;
|
||||
Gestion.HabilitarCategoria[10] := TRUE;
|
||||
Gestion.HabilitarCategoria[11] := TRUE;
|
||||
Gestion.HabilitarCategoria[12] := TRUE;
|
||||
Gestion.HabilitarCategoria[13] := TRUE;
|
||||
Gestion.HabilitarCategoria[14] := TRUE;
|
||||
Gestion.HabilitarCategoria[15] := TRUE;
|
||||
Gestion.HabilitarCategoria[16] := TRUE;
|
||||
Gestion.HabilitarCategoria[17] := TRUE;
|
||||
Gestion.HabilitarCategoria[18] := TRUE;
|
||||
Gestion.HabilitarCategoria[19] := TRUE;
|
||||
Gestion.HabilitarCategoria[20] := TRUE;
|
||||
Gestion.HabilitarCategoria[21] := TRUE;
|
||||
Gestion.HabilitarCategoria[22] := TRUE;
|
||||
Gestion.HabilitarCategoria[23] := TRUE;
|
||||
Gestion.HabilitarCategoria[24] := TRUE;
|
||||
Gestion.HabilitarCategoria[25] := TRUE;
|
||||
Gestion.HabilitarCategoria[26] := TRUE;
|
||||
Gestion.HabilitarCategoria[27] := TRUE;
|
||||
Gestion.HabilitarCategoria[28] := TRUE;
|
||||
Gestion.HabilitarCategoria[29] := TRUE;
|
||||
Gestion.HabilitarCategoria[30] := TRUE;
|
||||
Gestion.HabilitarCategoria[31] := TRUE;
|
||||
Gestion.Etapa := 0;
|
||||
Gestion.SP_Tiempo := 2;
|
||||
Gestion.TiempoActual := 0;
|
||||
Buffer[0].Registrar := 0;
|
||||
Buffer[0].Categoria := 0;
|
||||
Buffer[0].User := '';
|
||||
Buffer[1].Registrar := 0;
|
||||
Buffer[1].Categoria := 0;
|
||||
Buffer[1].User := '';
|
||||
|
||||
END_DATA_BLOCK
|
||||
|
||||
+411
@@ -0,0 +1,411 @@
|
||||
FUNCTION "FC7_ZC_TRZ_GESTOR" : Void
|
||||
TITLE = FC7_GESTOR_TRAZA
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 2.0
|
||||
//Funcion para gestion de trazabilidad
|
||||
VAR_INPUT
|
||||
Pulso1Seg : Bool; // Pulso de 1 segundo
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
for_i : Int; // Variable para bucles FOR
|
||||
t_PosicionRegistro : Int; // Posicion del registro encontrado en el buffer
|
||||
t_RegistroEncontrado : Bool; // Indicador de registro encontrado
|
||||
t_TextoGenerado : Bool; // Indicador de texto generado en todos los Scadas
|
||||
END_VAR
|
||||
|
||||
VAR CONSTANT
|
||||
REPOSO : Int := 0; // ETAPA EN REPOSO
|
||||
COMPROBACION_INICIAL : Int := 10; // ETAPA COMPROBACIONES INICIALES
|
||||
GENERAR_TEXTO : Int := 20; // ETAPA GENERAR TEXTO
|
||||
LANZAR_AVISO : Int := 30; // ETAPA LANZAR AVISO
|
||||
ESPERA : Int := 40; // ETAPA ESPERA
|
||||
BORRAR_TEXTO : Int := 50; // ETAPA BORRAR TEXTO
|
||||
QUITAR_AVISO : Int := 60; // ETAPA QUITAR AVISO
|
||||
BORRAR_DATOS : Int := 70; // ETAPA BORRAR DATOS
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2022 - 2026
|
||||
|
||||
---
|
||||
### Información del Sistema
|
||||
| Hardware Compatible | Entorno de Ingeniería |
|
||||
|---------------------|-----------------------|
|
||||
| PLC serie 1200/1500 | TIA Portal 18 |
|
||||
|
||||
---
|
||||
> **Restricciones:** Ninguna.
|
||||
|
||||
---
|
||||
### Descripción Funcional
|
||||
|
||||
Función principal para la gestión de mensajes de trazabilidad y su envío estructurado a los sistemas de supervisión.
|
||||
|
||||
Las tareas que realiza son las siguientes:
|
||||
|
||||
- Búsqueda en orden inverso dentro del buffer para localizar y extraer el último registro con orden de registrar.
|
||||
- Transferencia del registro a variables de gestión estáticas, formateo de cadenas de tiempo y usuario, y liberación de la posición ocupada en el buffer.
|
||||
- Ejecución de la **Etapa Reposo**: Con un registro habilitado y conexión activa, lanza la orden de inicio de secuencia.
|
||||
- Ejecución de la **Etapa Comprobaciones Iniciales**: Valida que la categoría del evento se encuentre en los límites permitidos (forzando una categoría de usuario si excede el índice), limpia las confirmaciones previas y espera la actualización temporal.
|
||||
- Ejecución de la **Etapa Generar Texto**: Envía la orden de generación de textos a los SCADAs habilitados, transitando al recibir la confirmación de todos o al superar un tiempo de espera de seguridad.
|
||||
- Ejecución de la **Etapa Lanzar Aviso**: Activa la señal de aviso correspondiente a la categoría de la trazabilidad procesada.
|
||||
- Ejecución de la **Etapa Espera**: Retiene el aviso activo durante el tiempo configurado para garantizar su captura en los sistemas de supervisión.
|
||||
- Ejecución de la **Etapa Borrar Texto**: Lanza la orden de limpieza de textos en pantalla a todos los SCADAs.
|
||||
- Ejecución de la **Etapa Quitar Aviso**: Desactiva la señal de aviso y verifica mediante un tiempo corto que el evento ha caído.
|
||||
- Ejecución de la **Etapa Borrar Datos**: Inicializa por completo los valores, códigos y textos del aviso actual, regresando a la etapa de reposo.
|
||||
- Mapeo final de las activaciones de alarma a nivel de bit, agrupándolas en dos variables tipo `Word` para las 32 categorías y aplicando sus respectivas máscaras de habilitación individual.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | - |
|
||||
| FB | - |
|
||||
| DB | `DB7_TRAZA` |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 00.00.01 | 31.08.2022 | (ABH) | Primera version. |
|
||||
| 01.00.00 | 18.09.2023 | (ABH) | Se añade gestion de bits para 16 categorias. |
|
||||
| 02.00.00 | 25.03.2026 | (ABH) | Se eliminan `String`. Se añaden 32 categorias. Se añade gestion de generacion de textos para Scada. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_TRAZA
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_ULTIMO_REGISTRO
|
||||
|
||||
// Si la gestion esta habilitada, se busca el ultimo registro y se mueve a la variable de gestion de avisos para
|
||||
// los sistemas de supervision
|
||||
IF "DB7_TRZ".Gestion.HabilitacionGeneral AND #Pulso1Seg AND "DB7_TRZ".Gestion.Etapa = #REPOSO THEN
|
||||
|
||||
// Buscamos el ultimo registro
|
||||
FOR #for_i := "N_MAX_TRAZA_BUFFER" TO 0 BY -1 DO
|
||||
|
||||
// Registro encontrado
|
||||
IF "DB7_TRZ".Buffer[#for_i].Registrar = 1 THEN
|
||||
#t_PosicionRegistro := #for_i;
|
||||
#t_RegistroEncontrado := TRUE;
|
||||
EXIT;
|
||||
END_IF;
|
||||
|
||||
END_FOR;
|
||||
|
||||
|
||||
// Si hemos encontrado el registro, copiamos a variable estatica
|
||||
IF #t_RegistroEncontrado THEN
|
||||
|
||||
// Copiamos el los datos de la traza a variable estatica para tratarla
|
||||
"DB7_TRZ".Gestion.Aviso.Datos := "DB7_TRZ".Buffer[#t_PosicionRegistro];
|
||||
|
||||
// Quitamos el registro del buffer
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].Registrar := 0;
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].Categoria :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodInt_1 :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodInt_2 :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodInt_3 :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodInt_4 :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodInt_5 := 0;
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodReal_1 :=
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].CodReal_2 := 0.0;
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].TimeStamp := DTL#1970-01-01-00:00:00;
|
||||
"DB7_TRZ".Buffer[#t_PosicionRegistro].User := '';
|
||||
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION GESTION_ULTIMO_REGISTRO
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_ORDEN_INICIAR
|
||||
|
||||
// =============================================================================
|
||||
// Si existe registro a trazar, lanzamos la orden de iniciar la secuencia
|
||||
IF "DB7_TRZ".Gestion.Aviso.Datos.Registrar = 1 AND "DB7_TRZ".Gestion.Etapa = #REPOSO AND "DB7_TRZ".Gestion.EstadoConexion THEN
|
||||
|
||||
// Lanzamos la orden de iniciar la secuencia de registro
|
||||
"DB7_TRZ".Gestion.OrdenIniciar := TRUE;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION GESTION_ORDEN_INICIAR
|
||||
|
||||
END_REGION GESTION_TRAZA
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION SECUENCIA_TRAZA
|
||||
|
||||
// En caso de deshabilitar la trazabilidad, ponemos el estado en borrar datos.
|
||||
IF NOT "DB7_TRZ".Gestion.HabilitacionGeneral AND "DB7_TRZ".Gestion.Etapa <> #REPOSO THEN
|
||||
"DB7_TRZ".Gestion.Etapa := #BORRAR_DATOS;
|
||||
END_IF;
|
||||
|
||||
// Gestion trazabilidad
|
||||
CASE "DB7_TRZ".Gestion.Etapa OF
|
||||
|
||||
// =============================================================================
|
||||
// Etapa reposo
|
||||
#REPOSO:
|
||||
REGION #REPOSO
|
||||
|
||||
// Con orden de iniciar, vamos a etapa comprobaciones iniciales
|
||||
IF "DB7_TRZ".Gestion.OrdenIniciar THEN
|
||||
"DB7_TRZ".Gestion.Etapa := #COMPROBACION_INICIAL;
|
||||
"DB7_TRZ".Gestion.OrdenIniciar := FALSE;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
// =============================================================================
|
||||
// Etapa comprobaciones iniciales
|
||||
#COMPROBACION_INICIAL:
|
||||
REGION #COMPROBACION_INICIAL
|
||||
|
||||
// Si el registro actual no tiene orden de registrar, lo borramos yendo a etapa borrar datos
|
||||
IF "DB7_TRZ".Gestion.Aviso.Datos.Registrar = 0 THEN
|
||||
"DB7_TRZ".Gestion.Etapa := #BORRAR_DATOS;
|
||||
ELSE
|
||||
// Esperamos a que tenga los datos actualizados en scada/hmi
|
||||
IF #Pulso1Seg THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual += 1;
|
||||
IF "DB7_TRZ".Gestion.TiempoActual >= "DB7_TRZ".Gestion.SP_Tiempo THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
|
||||
// En caso de tener una categoria fuera de indices, formazos a categoria usuario
|
||||
IF "DB7_TRZ".Gestion.Aviso.Datos.Categoria < "TRZ_CAT_1_SYS" OR "DB7_TRZ".Gestion.Aviso.Datos.Categoria > "TRZ_CAT_32_USER" THEN
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.Categoria := "TRZ_CAT_32_USER";
|
||||
END_IF;
|
||||
|
||||
// Limpiamos las confirmaciones de texto generado por seguridad antes de esperar
|
||||
FOR #for_i := 0 TO "N_MAX_SCADA" DO
|
||||
"DB7_TRZ".Gestion.Aviso.TextoGenerado[#for_i] := FALSE;
|
||||
END_FOR;
|
||||
|
||||
"DB7_TRZ".Gestion.Etapa := #GENERAR_TEXTO;
|
||||
END_IF;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
// =============================================================================
|
||||
// Etapa generar texto
|
||||
#GENERAR_TEXTO:
|
||||
REGION #GENERAR_TEXTO
|
||||
|
||||
// Lanzamos la orden de generar textos a sistemas scada que esten habilitados
|
||||
FOR #for_i := 0 TO "N_MAX_SCADA" DO
|
||||
"DB7_TRZ".Gestion.Aviso.GenerarTexto[#for_i] := "DB7_TRZ".Gestion.Aviso.HabilitarHmiScada[#for_i];
|
||||
END_FOR;
|
||||
|
||||
// Activamos marca de texto generado OK desde Scada, antes de realizar las comprobaciones.
|
||||
#t_TextoGenerado := TRUE;
|
||||
|
||||
// Comprobamos si los Scadas estan habilitados y tenemos confirmacion de que el texto se ha generado correctamente
|
||||
FOR #for_i := 0 TO "N_MAX_SCADA" DO
|
||||
IF "DB7_TRZ".Gestion.Aviso.HabilitarHmiScada[#for_i] AND NOT "DB7_TRZ".Gestion.Aviso.TextoGenerado[#for_i] THEN
|
||||
#t_TextoGenerado := FALSE;
|
||||
END_IF;
|
||||
END_FOR;
|
||||
|
||||
|
||||
// Comprobacion de fin etapa
|
||||
IF #t_TextoGenerado THEN
|
||||
|
||||
// Tenemos confirmacion de todos los Scadas que han generado el texto correctamente
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
"DB7_TRZ".Gestion.Etapa := #LANZAR_AVISO;
|
||||
|
||||
// Reseteamos las ordenes de generar texto
|
||||
FOR #for_i := 0 TO "N_MAX_SCADA" DO
|
||||
"DB7_TRZ".Gestion.Aviso.GenerarTexto[#for_i] := FALSE;
|
||||
END_FOR;
|
||||
|
||||
ELSE
|
||||
|
||||
// Esperamos un tiempo de seguridad si no tenemos respuesta desde Scadas
|
||||
IF #Pulso1Seg THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual += 1;
|
||||
|
||||
IF "DB7_TRZ".Gestion.TiempoActual >= "DB7_TRZ".Gestion.SP_TiempoTexto THEN
|
||||
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
|
||||
// Reseteamos las ordenes de generar texto
|
||||
FOR #for_i := 0 TO "N_MAX_SCADA" DO
|
||||
"DB7_TRZ".Gestion.Aviso.GenerarTexto[#for_i] := FALSE;
|
||||
END_FOR;
|
||||
|
||||
"DB7_TRZ".Gestion.Etapa := #LANZAR_AVISO;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
// =============================================================================
|
||||
// Etapa lanzar aviso
|
||||
#LANZAR_AVISO:
|
||||
REGION #LANZAR_AVISO
|
||||
|
||||
// Activamos orden de lanzar el aviso
|
||||
"DB7_TRZ".Gestion.Aviso.Aviso["DB7_TRZ".Gestion.Aviso.Datos.Categoria] := TRUE;
|
||||
"DB7_TRZ".Gestion.Etapa := #ESPERA;
|
||||
|
||||
END_REGION
|
||||
|
||||
// =============================================================================
|
||||
// Etapa espera
|
||||
#ESPERA:
|
||||
REGION #ESPERA
|
||||
|
||||
// Esperamos un tiempo para que el aviso se haya registrado en todos los sistemas de supervision
|
||||
IF #Pulso1Seg THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual += 1;
|
||||
IF "DB7_TRZ".Gestion.TiempoActual >= "DB7_TRZ".Gestion.SP_Tiempo THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
"DB7_TRZ".Gestion.Etapa := #BORRAR_TEXTO;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Etapa borrar texto
|
||||
#BORRAR_TEXTO:
|
||||
REGION #BORRAR_TEXTO
|
||||
|
||||
// Lanzamos orden de borrar texto a todos los Scadas
|
||||
"DB7_TRZ".Gestion.Aviso.BorrarTexto := TRUE;
|
||||
|
||||
// Reseteamos los valores del aviso actual
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.Registrar := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_1 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_2 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_3 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_4 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_5 := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodReal_1 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodReal_2 := 0.0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.User := '';
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.TimeStamp := DTL#1970-01-01-00:00:00;
|
||||
|
||||
// Saltamos de etapa tras un tiempo
|
||||
IF #Pulso1Seg THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual += 1;
|
||||
IF "DB7_TRZ".Gestion.TiempoActual >= "DB7_TRZ".Gestion.SP_Tiempo THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.BorrarTexto := FALSE;
|
||||
"DB7_TRZ".Gestion.Etapa := #QUITAR_AVISO;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
// =============================================================================
|
||||
// Etapa quitar aviso
|
||||
#QUITAR_AVISO:
|
||||
REGION #QUITAR_AVISO
|
||||
|
||||
// Desactivamos el aviso
|
||||
"DB7_TRZ".Gestion.Aviso.Aviso["DB7_TRZ".Gestion.Aviso.Datos.Categoria] := FALSE;
|
||||
|
||||
// Saltamos de etapa tras un tiempo
|
||||
IF #Pulso1Seg THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual += 1;
|
||||
IF "DB7_TRZ".Gestion.TiempoActual >= 2 AND NOT "DB7_TRZ".Gestion.Aviso.Aviso["DB7_TRZ".Gestion.Aviso.Datos.Categoria] THEN
|
||||
"DB7_TRZ".Gestion.TiempoActual := 0;
|
||||
"DB7_TRZ".Gestion.Etapa := #BORRAR_DATOS;
|
||||
END_IF;
|
||||
END_IF;
|
||||
|
||||
END_REGION
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Etapa borrar datos
|
||||
#BORRAR_DATOS:
|
||||
REGION #BORRAR_DATOS
|
||||
|
||||
// Reseteamos los valores del aviso actual
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.Registrar := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.Categoria := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_1 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_2 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_3 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_4 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodInt_5 := 0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodReal_1 :=
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.CodReal_2 := 0.0;
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.User := '';
|
||||
"DB7_TRZ".Gestion.Aviso.Datos.TimeStamp := DTL#1970-01-01-00:00:00;
|
||||
|
||||
"DB7_TRZ".Gestion.Etapa := #REPOSO;
|
||||
|
||||
END_REGION
|
||||
|
||||
END_CASE;
|
||||
|
||||
END_REGION SECUENCIA_TRAZA
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION ACTIVACION_ALARMAS
|
||||
|
||||
// Activamos los avisos en WORD segun la categoria y su habilitacion
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X0 := "DB7_TRZ".Gestion.HabilitarCategoria[0] AND "DB7_TRZ".Gestion.Aviso.Aviso[0];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X1 := "DB7_TRZ".Gestion.HabilitarCategoria[1] AND "DB7_TRZ".Gestion.Aviso.Aviso[1];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X2 := "DB7_TRZ".Gestion.HabilitarCategoria[2] AND "DB7_TRZ".Gestion.Aviso.Aviso[2];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X3 := "DB7_TRZ".Gestion.HabilitarCategoria[3] AND "DB7_TRZ".Gestion.Aviso.Aviso[3];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X4 := "DB7_TRZ".Gestion.HabilitarCategoria[4] AND "DB7_TRZ".Gestion.Aviso.Aviso[4];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X5 := "DB7_TRZ".Gestion.HabilitarCategoria[5] AND "DB7_TRZ".Gestion.Aviso.Aviso[5];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X6 := "DB7_TRZ".Gestion.HabilitarCategoria[6] AND "DB7_TRZ".Gestion.Aviso.Aviso[6];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X7 := "DB7_TRZ".Gestion.HabilitarCategoria[7] AND "DB7_TRZ".Gestion.Aviso.Aviso[7];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X8 := "DB7_TRZ".Gestion.HabilitarCategoria[8] AND "DB7_TRZ".Gestion.Aviso.Aviso[8];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X9 := "DB7_TRZ".Gestion.HabilitarCategoria[9] AND "DB7_TRZ".Gestion.Aviso.Aviso[9];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X10 := "DB7_TRZ".Gestion.HabilitarCategoria[10] AND "DB7_TRZ".Gestion.Aviso.Aviso[10];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X11 := "DB7_TRZ".Gestion.HabilitarCategoria[11] AND "DB7_TRZ".Gestion.Aviso.Aviso[11];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X12 := "DB7_TRZ".Gestion.HabilitarCategoria[12] AND "DB7_TRZ".Gestion.Aviso.Aviso[12];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X13 := "DB7_TRZ".Gestion.HabilitarCategoria[13] AND "DB7_TRZ".Gestion.Aviso.Aviso[13];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X14 := "DB7_TRZ".Gestion.HabilitarCategoria[14] AND "DB7_TRZ".Gestion.Aviso.Aviso[14];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[0].%X15 := "DB7_TRZ".Gestion.HabilitarCategoria[15] AND "DB7_TRZ".Gestion.Aviso.Aviso[15];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X0 := "DB7_TRZ".Gestion.HabilitarCategoria[16] AND "DB7_TRZ".Gestion.Aviso.Aviso[16];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X1 := "DB7_TRZ".Gestion.HabilitarCategoria[17] AND "DB7_TRZ".Gestion.Aviso.Aviso[17];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X2 := "DB7_TRZ".Gestion.HabilitarCategoria[18] AND "DB7_TRZ".Gestion.Aviso.Aviso[18];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X3 := "DB7_TRZ".Gestion.HabilitarCategoria[19] AND "DB7_TRZ".Gestion.Aviso.Aviso[19];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X4 := "DB7_TRZ".Gestion.HabilitarCategoria[20] AND "DB7_TRZ".Gestion.Aviso.Aviso[20];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X5 := "DB7_TRZ".Gestion.HabilitarCategoria[21] AND "DB7_TRZ".Gestion.Aviso.Aviso[21];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X6 := "DB7_TRZ".Gestion.HabilitarCategoria[22] AND "DB7_TRZ".Gestion.Aviso.Aviso[22];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X7 := "DB7_TRZ".Gestion.HabilitarCategoria[23] AND "DB7_TRZ".Gestion.Aviso.Aviso[23];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X8 := "DB7_TRZ".Gestion.HabilitarCategoria[24] AND "DB7_TRZ".Gestion.Aviso.Aviso[24];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X9 := "DB7_TRZ".Gestion.HabilitarCategoria[25] AND "DB7_TRZ".Gestion.Aviso.Aviso[25];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X10 := "DB7_TRZ".Gestion.HabilitarCategoria[26] AND "DB7_TRZ".Gestion.Aviso.Aviso[26];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X11 := "DB7_TRZ".Gestion.HabilitarCategoria[27] AND "DB7_TRZ".Gestion.Aviso.Aviso[27];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X12 := "DB7_TRZ".Gestion.HabilitarCategoria[28] AND "DB7_TRZ".Gestion.Aviso.Aviso[28];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X13 := "DB7_TRZ".Gestion.HabilitarCategoria[29] AND "DB7_TRZ".Gestion.Aviso.Aviso[29];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X14 := "DB7_TRZ".Gestion.HabilitarCategoria[30] AND "DB7_TRZ".Gestion.Aviso.Aviso[30];
|
||||
"DB7_TRZ".Gestion.Aviso.AvisoWord[1].%X15 := "DB7_TRZ".Gestion.HabilitarCategoria[31] AND "DB7_TRZ".Gestion.Aviso.Aviso[31];
|
||||
|
||||
END_REGION ACTIVACION_ALARMAS
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
FUNCTION "FC8_ZC_TRZ_REGISTRO" : Void
|
||||
TITLE = FC8_TRAZA_REGISTRO
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
AUTHOR : ABH
|
||||
FAMILY : ZeusControl
|
||||
VERSION : 1.0
|
||||
//Funcion para almacenar una traza en el buffer de trazas.
|
||||
VAR_INPUT
|
||||
FechaHora {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // Fecha y hora actual
|
||||
Registrar : USInt; // Registrar trazabilidad
|
||||
Categoria : Int; // Categoria de trazabilidad
|
||||
User : String; // Usuario actual
|
||||
CodInt_1 : Int; // Codigo entero 1
|
||||
CodInt_2 : Int; // Codigo entero 2
|
||||
CodInt_3 : Int; // Codigo entero 3
|
||||
CodInt_4 : Int; // Codigo entero 4
|
||||
CodInt_5 : Int; // Codigo entero 5
|
||||
CodReal_1 : Real; // Codigo real 1
|
||||
CodReal_2 : Real; // Codigo real 2
|
||||
END_VAR
|
||||
|
||||
VAR_TEMP
|
||||
t_dummy : Int; // Variable temporal para su uso en programa
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
REGION DESCRIPCION
|
||||
(*
|
||||
###### (C)Copyright ZeusControl 2022 - 2026
|
||||
|
||||
---
|
||||
### 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 almacenar de forma secuencial un nuevo evento de trazabilidad dentro del buffer de registros.
|
||||
|
||||
Las tareas que realiza son las siguientes:
|
||||
|
||||
- Verifica que la gestión general de trazabilidad se encuentre habilitada en el sistema.
|
||||
- Desplaza el contenido actual del buffer de trazas una posición hacia abajo mediante la instrucción `MOVE_BLK_VARIANT`, liberando el primer índice.
|
||||
- Convierte la marca de tiempo de entrada (formato `DTL`) a una cadena de texto (`String`) haciendo uso de la función `FC15006_ZC_DTL_TO_STRING`.
|
||||
- Almacena los parámetros del nuevo registro (orden de registrar, marca de tiempo, categoría, códigos numéricos enteros y reales) en la posición inicial (índice 0) del buffer.
|
||||
- Valida la cadena de caracteres correspondiente al usuario: si se encuentra vacía, registra una cadena de espacios por defecto; en caso contrario, asigna el nombre de usuario proporcionado en la entrada.
|
||||
|
||||
---
|
||||
### Dependencias Requeridas
|
||||
| Tipo | Elementos |
|
||||
|------|-----------|
|
||||
| FC | `FC15006_ZC_DTL_TO_STRING` |
|
||||
| FB | - |
|
||||
| DB | `DB7_TRAZA` |
|
||||
| UDT | - |
|
||||
|
||||
---
|
||||
### Historial de Cambios
|
||||
| Versión | Fecha | Técnico | Cambios |
|
||||
|----------|------------|---------|---------|
|
||||
| 00.00.01 | 31.08.2022 | (ABH) | Primera version. |
|
||||
| 00.00.02 | 25.03.2026 | (ABH) | Se añade datos nuevos de UDT. |
|
||||
| 01.00.00 | 21.05.2026 | (ABH) | Se cambia la variable fechaactual de string a DTL. Se reduce el usuario actual a 15 caracteres. |
|
||||
*)
|
||||
END_REGION DESCRIPCION
|
||||
|
||||
|
||||
// ==========================================================================================================
|
||||
REGION GESTION_REGISTRO_TRAZA
|
||||
|
||||
// Si la trazabilidad esta habilitada
|
||||
IF "DB7_TRZ".Gestion.HabilitacionGeneral THEN
|
||||
|
||||
// Desplazamos los datos una posicion hacia abajo
|
||||
#t_dummy := MOVE_BLK_VARIANT(SRC := "DB7_TRZ".Buffer, COUNT := INT_TO_UDINT(("N_MAX_TRAZA_BUFFER")), SRC_INDEX := 0, DEST_INDEX := 1, DEST => "DB7_TRZ".Buffer);
|
||||
|
||||
// Guardamos el nuevo registro en la primera posicion
|
||||
"DB7_TRZ".Buffer[0].Registrar := #Registrar;
|
||||
"DB7_TRZ".Buffer[0].TimeStamp := #FechaHora;
|
||||
"DB7_TRZ".Buffer[0].Categoria := #Categoria;
|
||||
"DB7_TRZ".Buffer[0].CodInt_1 := #CodInt_1;
|
||||
"DB7_TRZ".Buffer[0].CodInt_2 := #CodInt_2;
|
||||
"DB7_TRZ".Buffer[0].CodInt_3 := #CodInt_3;
|
||||
"DB7_TRZ".Buffer[0].CodInt_4 := #CodInt_4;
|
||||
"DB7_TRZ".Buffer[0].CodInt_5 := #CodInt_5;
|
||||
"DB7_TRZ".Buffer[0].CodReal_1 := #CodReal_1;
|
||||
"DB7_TRZ".Buffer[0].CodReal_2 := #CodReal_2;
|
||||
IF #User = '' THEN
|
||||
"DB7_TRZ".Buffer[0].User := ' ';
|
||||
ELSE
|
||||
"DB7_TRZ".Buffer[0].User := #User;
|
||||
END_IF;
|
||||
|
||||
END_IF;
|
||||
|
||||
END_REGION GESTION_REGISTRO_TRAZA
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
Reference in New Issue
Block a user