Estos temporizadores no usan el formato de tiempo S5TIME propio de Step7, sino que usan el formato TIME según la norma IEC. Este formato no es más que un entero doble con signo (32 bits) donde se almacena el tiempo en milisegundos. Para saber más sobre su funcionamiento, en la ayuda de Step7 vienen perfectamente documentados.
Pero existe otra opción para realizar temporizaciones. En Step7 tenemos la función del sistema SFC64 TIME_TCK (time tick), con la que se puede leer el cronómetro del sistema de la CPU. Esto nos da la opción de construir nuestro propio temporizador a medida y es lo que voy a hacer a continuación.
La función del sistema SFC64 está disponible en la misma biblioteca que los temporizadores TON y TOF. Al llamarla nos devolverá, en formato TIME, el cronómetro del sistema, que no es más que el número de milisegundos que han transcurrido desde que el PLC ha pasado a modo RUN.
Mi temporizador lo voy a controlar con cuatro parámetros de entrada:
- HABILIT, booleano de habilitación que servirá para activar la temporización.
- PAUSA, booleano que permitirá pausar el tiempo mientras esté activada la temporización (igual a lo que hice en la entrada anterior con un temporizador SIMATIC).
- REINIC, booleano que permitirá reinicializar la temporización.
- TIEMPO, en formato TIME que será el tiempo de temporización.
- TEMPORIZANDO, booleano que nos indicará que la temporización está en marcha.
- FIN, booleano que señalará que la temporización ha finalizado.
- T_RESTANTE, en formato TIME nos irá informando del tiempo que falta para terminar la temporización.
Actualización: también tienes el código del temporizador en este proyecto de Step7.
La programación del temporizador está hecha en un bloque de función (FB) que necesitará un bloque de datos (DB) de instancia asociado. En las siguientes capturas se puede ver la parametrización del interface de entrada (IN), salida (OUT), status (STAT) y temporal (TEMP):
En la siguiente captura está la programación en diagrama de contactos (KOP) del FB de temporización, está comentado y creo que se entiende bastante bien:
Con esto sería suficiente, pero los temporizadores son código que se usa frecuentemente y es preferible que esté lo más optimizado posible, así que lo he traducido a lista de instrucciones (AWL). Aprovechando que el lenguaje AWL es menos restrictivo con los tipos de datos he suprimido algunas variables auxiliares requiriendo, por tanto, menos memoria. El interface de entrada (IN) y salida (OUT) es idéntico a la programación en KOP, no así el de status (STAT) y el temporal (TEMP), que se han simplificado:
El código optimizado en AWL es el siguiente:
CALL "TIME_TCK" // LECTURA DEL CRONÓMETRO DEL SISTEMA
RET_VAL:=#TIME_MS
U #HABILIT // AL INICIAR EL TEMPORIZADOR Y AL RESETEAR
FP #FP1 // SE CALCULA EL TIEMPO DE FINALIZACIÓN
O #REINIC // Y SE CARGA EL TIEMPO TOTAL
SPBN SLT1 // EN EL TIEMPO RESTANTE
L #TIME_MS
L #TIEMPO
+D
T #T_FINAL
L #TIEMPO
T #T_RESTANTE
SLT1: U #HABILIT // SI HAY SEÑAL DE HABILITACIÓN,
UN #PAUSA // NO SE ESTÁ EN PAUSA,
UN #FIN // NO HA FINALIZADO LA TEMPORIZACIÓN Y
UN #REINIC // NO SE ESTÁ REINICIANDO,
= #TEMPORIZANDO // SE ESTÁ TEMPORIZANDO
U #TEMPORIZANDO // SI SE ESTÁ TEMPORIZANDO Y
U( // SE HA COMPLETADO EL TIEMPO
L #T_FINAL // HA FINALIZADO LA TEMPORIZACIÓN
L #TIME_MS
<=D
)
S #FIN
ON #HABILIT // SI NO HAY HABILITACIÓN O
O #REINIC // SI SE ESTÁ REINICIALIZANDO
R #FIN // SE QUITA LA SEÑAL DE FIN DE TEMPORIZACIÓN
U #HABILIT // SI ESTANDO HABILITADO EL TEMPORIZADOR Y
U #PAUSA // AL ENTRAR EN PAUSA
FP #FP2 // Y SI NO HA FINALIZADO LA TEMPORIZACIÓN
UN #FIN // SE GUARDA EL TIEMPO RESTANTE
SPBN SLT2
L #T_FINAL
L #TIME_MS
-D
T #T_RESTANTE
SLT2: U #HABILIT // SI HAY HABILITACIÓN
U #PAUSA // Y PAUSA
UN #FIN // Y NO HA FINALIZADO LA TEMPORIZACIÓN
SPBN SLT3 // SE RECALCULA EL TIEMPO FINAL DE TEMPORIZACIÓN
L #TIME_MS
L #T_RESTANTE
+D
T #T_FINAL
SLT3: UN #HABILIT // SI NO HAY HABILITACIÓN O
O #FIN // SI HA FINALIZADO LA TEMPORIZACIÓN,
SPBN SLT4 // EL TIEMPO RESTANTE DE TEMPORIZACIÓN
L 0 // SE PONE A CERO
T #T_RESTANTE
SLT4: U #TEMPORIZANDO // SI SE ESTÁ TEMPORIZANDO
SPBN SLT5 // SE CALCULA EL TIEMPO QUE FALTA
L #T_FINAL // PARA TERMINAR
L #TIME_MS
-D
T #T_RESTANTE
SLT5: NOP 0
En la siguiente captura de pantalla se ve el temporizador en ejecución:
Para finalizar y como curiosidad, el DB de instancia necesario en mi temporizador ocupa 54 bytes, frente a los 58 de los temporizadores IEC. Simplificando el funcionamiento de mi temporizador podría reducirse el tamaño del BD de instancia, lo cual podría ser interesante en el caso de que necesitemos ahorrar memoria.
A pesar de todo lo visto en esta entrada, pienso que es preferible usar los temporizadores SIMATIC, no consumen memoria con DB de instancia y sospecho que requieren menos recursos del PLC.
Si alguien mejora el código, realiza otro tipo de temporizador a partir de este o encuentra algún fallo, le agradecería que me lo comunicase.
Aparte de esto se podrá realizar una programación por ejemplo: de 3 procesos similares, pero con diferentes variables y tenido considerado un temporizador por proceso, pero con los bloques DB y FB mas el OB lógicamente ocupar solo una dirección, como T0………T255
ResponderEliminarBuen día, tu función está muy bien, salvo que cuando la cpu pasa a stop, la función se vuelve loca, la solución está en comprobar y recargar el tiempo restante cuando la SFC64 devuelve T#0ms o 1ms.
ResponderEliminarPor otra parte el código se puede optimizar mucho más, el tema de crear un timer sin timer y no utilizar el ton o toff es el espacio de memoria que consume, y tu solución está bien, pero le sobra la pausa, el todas las salidas.
Bueno, como supongo que es un ejemplo, está muy bien, pero solo como ejemplo, el la vida real es un poco peligroso este timer.
Saludos. (No aporto solución porque no sé como añadirla en tu blog.)
Hola Amigo anónimo,
Eliminarsi que el PLC pueda pasar a stop resulta problemático siempre tenemos los OB de fallo y arranque para solventar la situación.
Usar Ton y Toff también requiere de DB de instancia con lo que la memoria consumida sería similar.
El temporizador lo he diseñado en función de mis necesidades y la función de pausa es algo que en ocasiones me ha venido muy bien. Si consideras que se puede mejorar el código estaré encantado de echarle un vistazo y publicarlo en el blog (mi correo es: notasdeautomatizacion@gmail.com)
Un saludo y gracias por tu comentario.