Introducción a Instruction List (IL)
IL (Instruction List) es uno de los lenguajes textuales estandarizados por la norma IEC 61131-3. Su estructura secuencial y el uso de un acumulador implícito lo asemejan al lenguaje ensamblador de los microprocesadores. Aunque en la actualidad lenguajes gráficos como diagrama de contactos (KOP) o FBD son más intuitivos, IL sigue siendo indispensable en tareas de optimización de código, librerías de bajo nivel y migración de sistemas legacy. Su capacidad para expresar operaciones lógicas y aritméticas de forma compacta lo mantiene vigente en entornos CODESYS, Siemens Step 5/7 y PLCopen.
Cada instrucción ocupa normalmente una línea y consta de un código de operación (opcode) y, opcionalmente, uno o varios operandos (variables, constantes o etiquetas). El resultado de las operaciones se almacena en un registro interno llamado acumulador (ACU). Este enfoque de máquina de pila simplificada permite ejecutar complejas redes de contactos con muy pocas instrucciones.
Instrucciones básicas y flujo de datos
Las instrucciones fundamentales manipulan el acumulador y las variables de entrada/salida. A continuación se detallan las más usadas, con ejemplos paso a paso.
Carga y almacenamiento: LD / ST
LD (Load) copia el valor del operando al acumulador. ST (Store) guarda el valor del acumulador en la variable destino. Por ejemplo:
LD X1 (* carga el estado de la entrada X1 *) ST Y1 (* el acumulador se transfiere a la salida Y1 *)
| | Simbología normalizada IEC 60617: contacto NA (X1) y bobina (Y1). En IL, una red de contactos serie se traduce en LD X1 seguido de AND X2.
Operaciones lógicas: AND, OR, NOT
Estas instrucciones combinan el acumulador con el operando y dejan el resultado en el acumulador. Ejemplo de enclavamiento:
LD X0 (* arranque *) OR Y0 (* autoretención *) ANDN X1 (* X1 normalmente cerrado – paro *) ST Y0
Esta secuencia implementa un arranque/paro con prioridad al paro. Nótese el uso de ANDN (AND NOT) para contactos NC.
LD, AND, ST, ADD, JMP…).
Nota: IL fue eliminado en la edición 4 de IEC 61131-3 (2025),
aunque sigue siendo válido en CODESYS V3 y STEP 7.
Fuente: Elaboración propia.
Licencia:
CC BY-NC 4.0
Aritméticas básicas: ADD, SUB, MUL, DIV
IL también soporta operaciones aritméticas. El acumulador actúa como primer operando; el segundo se toma de la variable o constante. Ejemplo de cálculo de presión diferencial:
LD P_ALTA SUB P_BAJA ST DIFERENCIAL
Estas operaciones trabajan con enteros o flotantes según el tipo de dato declarado.
Saltos condicionales y control de flujo
La potencia de IL reside en las instrucciones de salto que permiten modificar la secuencia de ejecución en función del acumulador.
JMP, JMPC, JMPNC
JMP ETIQUETA– salto incondicional.JMPC ETIQUETA– salto si el acumulador es verdadero (1 lógico).JMPNC ETIQUETA– salto si el acumulador es falso (0 lógico).
Ejemplo de temporización simulada con saltos (espera activa, solo ilustrativo):
inicio: LD T1.Q JMPC fin_temporizador LD X1 AND T1.QN JMPC inicio . fin_temporizador: ST Y2
Las etiquetas (inicio:, fin_temporizador:) deben terminar en dos puntos. Así se construyen bucles y bifurcaciones complejas.
# sim_il.py - Ejemplo didáctico para Thonny/Raspberry Pi
# Implementa un bucle de ejecución de instrucciones IL con etiquetas y saltos
programa = [
("LD", "X1"),
("JMPC", "SALTO"),
("LD", "X2"),
("ST", "Y1"),
("SALTO", None), # etiqueta
("LD", "X3"),
("ST", "Y2")
]
# Estado de entradas/salidas (simula %I y %Q)
entradas = {"X1": True, "X2": False, "X3": True}
salidas = {"Y1": False, "Y2": False}
acumulador = False
# Construir mapa de etiquetas (direcciones)
etiquetas = {}
for i, (op, arg) in enumerate(programa):
if op.endswith(":") or (arg is None and op != "SALTO"): # detecta etiquetas tipo "SALTO:"
etiquetas[op.rstrip(":")] = i
pc = 0 # program counter
while pc < len(programa):
op, arg = programa[pc]
# Saltar etiquetas (no son instrucciones ejecutables)
if op.endswith(":") or (arg is None and op != "SALTO"):
pc += 1
continue
if op == "LD":
acumulador = entradas.get(arg, False)
elif op == "ST":
salidas[arg] = acumulador
elif op == "AND":
acumulador = acumulador and entradas.get(arg, False)
elif op == "JMPC":
if acumulador:
pc = etiquetas[arg]
continue # saltar incremento normal
# . se pueden añadir más instrucciones
pc += 1
print("Salidas:", salidas) # Esperado: Y1=False (porque X1=True saltó), Y2=True
Este ejemplo ejecuta una lista de instrucciones IL sencilla. Se puede probar en Thonny, modificar entradas y observar el flujo con saltos. Base para entender el ciclo de ejecución de un PLC.
Aunque IL ha perdido protagonismo frente a ST (Structured Text) y gráficos, la nueva versión de la IEC 61131-3 edición 4 (prevista para 2026) refuerza el soporte de IL para programación segura (Safety) y librerías criptográficas en PLC. También se observa un resurgimiento en entornos de PLC blandos (SoftPLC) sobre Raspberry Pi gracias a su baja huella de memoria y ejecución determinista.
Podemos ejecutar un intérprete IL escrito en Python sobre Raspberry Pi OS y leer GPIOs usando RPi.GPIO. Las entradas (X) se asignan a pines y las salidas (Y) a actuadores. El mismo código del ejemplo anterior puede adaptarse para controlar un semáforo o una cinta transportadora a pequeña escala.
Mediante Arduino PLC IDE (que cumple IEC 61131-3) es posible programar en IL directamente sobre hardware Arduino Opta o Portenta. Para Arduinos convencionales, existen librerías como PLCino que traducen un subconjunto de IL a C++.
- ✅ 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, el ciclo comienza cuando los dos pulsadores de marcha (X0 y X1) están activados simultáneamente. Además, un final de carrera de protección (X2) debe estar NO accionado (NC). La salida Y10 activa la prensa.
Problema: Se escribe el siguiente programa IL:
LD X0 AND X1 ANDN X2 ST Y10
Pregunta: Si X0=1, X1=1 y X2=1 (actuado), ¿cuál es el valor final de Y10?
🍓 Raspberry Pi + Python
Contexto: Se conecta un pulsador al GPIO17 (entrada X1) y un LED al GPIO27 (salida Y1). Se ejecuta este código Python que emula IL:
acumulador = False
X1 = GPIO.input(17)
if X1:
acumulador = True
acumulador = acumulador and GPIO.input(18) # AND X2 (GPIO18)
GPIO.output(27, acumulador)
Pregunta: Si GPIO17 = True y GPIO18 = False, ¿qué estado tendrá el LED?
🐍 Python puro
Contexto: Dada la siguiente función Python que simula tres instrucciones IL:
def il_bloque(ent1, ent2):
acc = ent1
acc = acc and ent2
return acc
Pregunta: ¿Qué operación lógica implementa?
| Función | IL (Instrucción) | Ladder (símbolo) |
|---|---|---|
| Contacto NA | LD X1 | —| |— |
| Contacto NC | LDN X1 / ANDN X1 | —|/|— |
| Bobina | ST Y1 | —( )— |
| Serie (AND) | AND X2 | contactos en serie |
| Paralelo (OR) | OR X3 | contactos en paralelo |
📚 Recursos Técnicos y Normativos 2026
Normativas y Estándares
- IEC 61131-3:2013 (base) + enmiendas 2025 - Programmable controllers — Part 3: Programming languages
- PLCopen - Asociación para la estandarización en automatización