Introducción a los bloques de temporización, contaje y comparación
En la automatización industrial, el control de tiempos, el conteo de eventos y la comparación de magnitudes son esenciales para implementar procesos secuenciales, alarmas, supervisiones y lógica de seguridad. La norma IEC 61131-3 estandariza bloques funcionales (FB) para estas tareas, permitiendo su uso en cualquier PLC compatible (Siemens, Rockwell, CODESYS, etc.).
Estos bloques se representan gráficamente en los lenguajes FBD y Ladder, y también pueden invocarse en ST e IL. Su correcta parametrización y combinación permite construir desde sencillos retardos hasta complejos sistemas de control de producción.
Ejemplo industrial: en una línea de envasado, un sensor detecta el paso de botellas y alimenta un contador CTU. Cuando se alcanzan 24 botellas (PV=24), el bloque activa un temporizador TON que, tras 2 segundos, acciona un empujador para formar un lote. Un comparador verifica que el contador no supere un máximo por seguridad.
Bloque TON: Temporizador a la conexión
El TON (Timer ON Delay) genera un retardo a la activación. Su comportamiento es el siguiente:
- Cuando la entrada IN pasa de FALSE a TRUE (flanco de subida), el temporizador comienza a incrementar el tiempo transcurrido ET (Elapsed Time) desde cero.
- Mientras IN permanezca TRUE y ET sea menor que el tiempo prefijado PT (Preset Time), la salida Q permanece FALSE.
- Cuando ET alcanza o supera PT, la salida Q se pone a TRUE y se mantiene mientras IN sea TRUE.
- Si IN pasa a FALSE antes de alcanzar PT, el temporizador se reinicia (ET vuelve a 0).
Parámetros:
IN(BOOL): entrada de activación.PT(TIME): tiempo de retardo (ej. T#5s, T#100ms).Q(BOOL): salida temporizada.ET(TIME): tiempo transcurrido (solo lectura).
Aplicación típica: retardo para evitar rebotes en un pulsador, o tiempo de seguridad antes de arrancar una máquina.
Ejemplo en Structured Text (ST):
TON_inst(IN := Start, PT := T#3s);
IF TON_inst.Q THEN
Motor := TRUE;
END_IF
Bloque TOF: Temporizador a la desconexión
El TOF (Timer OFF Delay) actúa de manera inversa al TON. Al activarse la entrada IN, la salida Q se pone inmediatamente a TRUE. Cuando IN pasa a FALSE, comienza la temporización: ET se incrementa desde 0 hasta PT, y mientras tanto Q permanece TRUE. Al alcanzar PT, Q pasa a FALSE.
Si IN vuelve a TRUE durante la temporización, el temporizador se detiene y Q se mantiene TRUE (reinicio).
Aplicación típica: mantener una cinta en movimiento unos segundos después de que el último objeto haya pasado, para asegurar que sale del sistema.
Ejemplo en ST:
TOF_inst(IN := Sensor, PT := T#2s); Ventilador := TOF_inst.Q;
Bloque CTU: Contador ascendente
El CTU incrementa su valor interno cada vez que detecta un flanco ascendente (de FALSE a TRUE) en la entrada CU (Count Up). Cuando el valor actual CV alcanza o supera el valor prefijado PV, la salida Q se pone a TRUE. La entrada R (Reset) pone CV a 0 y Q a FALSE.
Parámetros:
CU(BOOL): entrada de conteo (flanco ascendente).R(BOOL): reset prioritario (pone CV a 0).PV(INT / DINT): valor de consigna.CV(INT / DINT): valor actual.Q(BOOL): salida activa cuando CV >= PV.
Aplicación típica: conteo de piezas, ciclos de máquina, lotes de producción.
Ejemplo en ST:
CTU_inst(CU := Sensor_pieza, R := Reset, PV := 100); Lote_completo := CTU_inst.Q;
Bloque CTD: Contador descendente
El CTD decrementa CV desde PV hasta 0 con cada flanco ascendente en CD. Cuando CV llega a 0, la salida Q se activa. La entrada LD (Load) carga el valor de PV en CV (inicialización).
Parámetros:
CD(BOOL): entrada de decremento.LD(BOOL): carga el valor preset (pone CV = PV).PV(INT): valor inicial.CV(INT): valor actual.Q(BOOL): activa cuando CV = 0.
Aplicación típica: control de stock (cantidad restante de material), temporizaciones descendentes, juegos de luces.
Ejemplo en ST:
CTD_inst(CD := Consumo, LD := Cargar_lote, PV := 500); Alarma_stock := CTD_inst.Q; (* cuando llega a 0 *)
Bloque CMP: Comparador de valores
El CMP (Comparador) evalúa dos operandos según la condición seleccionada (igual, mayor que, menor que, etc.) y produce una salida booleana. Aunque no es un bloque estándar único (puede implementarse con operadores en ST o con funciones de comparación), en FBD se representa como un bloque con dos entradas y una salida, donde se selecciona el tipo de comparación.
Las operaciones más comunes:
EQ(equal) – igualdadGT(greater than) – mayor queLT(less than) – menor queGE(greater or equal) – mayor o igualLE(less or equal) – menor o igualNE(not equal) – diferente
Aplicación típica: comparar la temperatura actual con un umbral, activar una alarma si se supera. Comparar el contador de piezas con el lote deseado.
Ejemplo en ST:
Alarma := (Temperatura > 100.0);
IF (Piezas_contadas >= Lote_objetivo) THEN
Lote_completo := TRUE;
END_IF
En FBD, se suele usar el bloque CMP con dos entradas y la salida correspondiente.
# plc_blocks.py - Clases para simular TON, CTU y CMP en Python
# Puede ejecutarse en Thonny y adaptarse a GPIO de Raspberry Pi
import time
class TON:
"""Temporizador a la conexión (IEC 61131-3)"""
def __init__(self, PT):
self.PT = PT # tiempo preset en segundos
self.IN_prev = False
self.start_time = None
self.Q = False
self.ET = 0.0
def evaluate(self, IN):
if IN and not self.IN_prev: # flanco ascendente
self.start_time = time.time()
self.ET = 0.0
if IN:
if self.start_time is not None:
self.ET = time.time() - self.start_time
self.Q = (self.ET >= self.PT)
else:
self.Q = False
self.ET = 0.0
self.start_time = None
self.IN_prev = IN
return self.Q, self.ET
class CTU:
"""Contador ascendente"""
def __init__(self, PV):
self.PV = PV
self.CV = 0
self.Q = False
self.last_CU = False
def evaluate(self, CU, R):
if R:
self.CV = 0
self.Q = False
elif CU and not self.last_CU: # flanco ascendente
self.CV += 1
self.Q = (self.CV >= self.PV)
self.last_CU = CU
return self.Q, self.CV
class CMP_GE:
"""Comparador: mayor o igual (>=)"""
def __init__(self):
pass
def evaluate(self, IN1, IN2):
return (IN1 >= IN2)
# --- Ejemplo de uso combinado ---
if __name__ == "__main__":
import time
# Instanciar bloques
ton = TON(PT=2.0) # temporizador de 2 segundos
ctu = CTU(PV=5) # contar hasta 5
cmp = CMP_GE()
# Simular entradas
sensor = [False, True, True, True, False, True, True, True, True, True]
reset = False
print("Tiempo| Sensor | TON.Q | CTU.CV | CTU.Q | CMP(CTU.CV>=3)")
for i, val in enumerate(sensor):
# Evaluar TON
ton_q, ton_et = ton.evaluate(val)
# Evaluar CTU (con el sensor como pulso)
ctu_q, ctu_cv = ctu.evaluate(val, reset)
# Comparar si CV >= 3
cmp_res = cmp.evaluate(ctu_cv, 3)
print(f" {i} | {int(val)} | {int(ton_q)} | {ctu_cv} | {int(ctu_q)} | {int(cmp_res)}")
time.sleep(1) # simula ciclo de scan
# Resultado: Al llegar a 5, CTU.Q se activa; cuando CV>=3, CMP activo.
Este código implementa versiones simplificadas de TON, CTU y un comparador. Se puede probar en Thonny y después utilizar con GPIO para contar pulsos reales o temporizar eventos en Raspberry Pi.
Los bloques de temporización y contaje evolucionan hacia versiones con soporte para tiempos de alta resolución (microsegundos) y conteo de eventos en frecuencias elevadas (hasta MHz) gracias a la integración de hardware específico (coprocesadores). Además, la norma IEC 61131-3 edición 4 incorpora bloques para temporizadores multipropósito (TP) y contadores bidireccionales con reset selectivo. En el ámbito de la Industria 4.0, estos bloques pueden ser monitorizados y parametrizados remotamente vía OPC UA.
Con Python y librerías como RPi.GPIO, podemos implementar los bloques anteriores para controlar procesos reales. Por ejemplo, leer un sensor infrarrojo (contar piezas), activar un relé después de un tiempo (TON) y comparar el conteo con un valor para encender un LED. El código del recuadro Python es directamente adaptable.
En el entorno Arduino, los temporizadores se implementan con millis() (no bloqueantes) y los contadores con variables. El Arduino PLC IDE proporciona estos bloques como instrucciones gráficas, facilitando la programación según IEC 61131-3.
- ✅ Comprender activamente cada línea de código generada
- ✅ Personalizar la solución según tus necesidades específicas
- ✅ Iterar y refinar el código hasta dominar la lógica
- ✅ Desarrollar habilidades de comunicación técnica con IA
📋 Instrucciones de Uso:
- Copia el prompt completo del recuadro superior.
- Personaliza los campos entre corchetes [CAMPO] con tu información específica.
- Pega el prompt en una nueva conversación con tu IA favorita.
- Itera y refina: Pide aclaraciones, modificaciones o añade requisitos adicionales.
- Prueba el código en Thonny primero, luego en tu Raspberry Pi y ajusta según resultados.
💼 Caso Práctico Industrial
Contexto: En una prensa hidráulica, se requiere que el ciclo de prensado solo comience si el operador ha mantenido pulsado el botón de marcha (X0) durante al menos 3 segundos (para evitar arranques involuntarios). Además, la prensa debe realizar un ciclo completo y luego esperar 2 segundos antes de permitir un nuevo ciclo. Se utiliza un bloque TON para el retardo de arranque y un TOF para el retardo entre ciclos.
Pregunta: ¿Qué combinación de bloques y señales es la correcta?
🍓 Raspberry Pi + Python
Contexto: En una Raspberry Pi, se ha implementado una clase CTU similar a la del ejemplo. Se conecta un sensor de barrera al GPIO17 y se cuenta el número de veces que se interrumpe. El contador tiene PV=10. Al alcanzar 10, se activa un LED en GPIO27.
Pregunta: Si el sensor se interrumpe 12 veces (flanco ascendente) y luego se activa la entrada de reset (R) durante un ciclo, ¿cuál será el valor de CV después del reset?
🐍 Lógica de comparación
Contexto: Se tiene un comparador que debe activar una salida cuando la temperatura actual (real) sea mayor o igual a 100.5 grados. En Python, se escribe:
if temp >= 100.5:
alarma = True
else:
alarma = False
Pregunta: ¿Qué operador de comparación se está usando implícitamente?
| Bloque | Función | Entradas | Salidas | Aplicación típica |
|---|---|---|---|---|
| TON | Retardo a la conexión | IN, PT | Q, ET | Arranque temporizado, filtro de rebotes |
| TOF | Retardo a la desconexión | IN, PT | Q, ET | Apagado progresivo, tiempo de espera |
| CTU | Contador ascendente | CU, R, PV | Q, CV | Conteo de piezas, ciclos |
| CTD | Contador descendente | CD, LD, PV | Q, CV | Control de stock, tiempo restante |
| CMP | Comparador | IN1, IN2, tipo | Q | Supervisión de límites, umbrales |
📚 Recursos Técnicos y Normativos 2026
Normativas y Estándares
- IEC 61131-3:2013 + enmiendas 2025 - Programmable controllers — Part 3: Programming languages (definición de bloques TON, TOF, CTU, etc.)
- PLCopen - Librerías de bloques de temporización y contaje