Introducción

Los autómatas programables han evolucionado para adaptarse a las necesidades de automatización en diversos sectores industriales. Su clasificación según la arquitectura permite seleccionar el equipo más adecuado en función de la complejidad del proceso y el entorno donde se instalará. A continuación se describen los principales tipos de PLCs, así como sus aplicaciones típicas y ventajas.

PLCs compactos

Este tipo de autómata integra en una sola unidad el procesador, las entradas y salidas (E/S) y la fuente de alimentación. Suelen tener un número fijo de E/S, aunque algunos modelos permiten una ligera expansión mediante módulos adicionales. Los PLCs compactos son especialmente adecuados para tareas de automatización sencillas y procesos de pequeña envergadura, como el control de máquinas independientes, cintas transportadoras simples, sistemas de bombeo y pequeñas líneas de ensamblaje. Su instalación resulta fácil y rápida por su diseño todo en uno, lo que reduce el espacio en el armario de control y simplifica el cableado. Sin embargo, presentan limitaciones en cuanto a capacidad de expansión y flexibilidad, por lo que no son recomendables para sistemas que puedan requerir ampliaciones significativas en el futuro.

PLCs modulares

Estos dispositivos permiten configurar el sistema a partir de una base en la que se insertan distintos módulos: procesador, módulos de E/S digitales y analógicas, módulos de comunicación, fuentes de alimentación, entre otros. Esta arquitectura ofrece una mayor flexibilidad, permitiendo adaptar el PLC a las necesidades específicas del proceso y facilitando la ampliación del sistema a medida que crecen los requerimientos. Los PLCs modulares se emplean en líneas de producción más complejas, sistemas de envasado, procesos de tratamiento de aguas y aplicaciones donde se requiere una integración con otros equipos o sistemas de supervisión. Su coste inicial es superior al de los compactos, pero se compensa por su capacidad de escalabilidad y mantenimiento más sencillo, ya que los módulos defectuosos pueden sustituirse de forma independiente.

Comparativa entre un PLC compacto (todo en uno) y un PLC modular con varios módulos apilados.
Figura 1: Comparativa entre PLC compacto (izquierda, estilo Siemens SIMATIC S7-1200) con CPU, fuente de alimentación, entradas/salidas y comunicación integradas en un único módulo, frente a un PLC modular (derecha, estilo Siemens SIMATIC S7-1500) donde cada función ocupa un módulo independiente intercambiable sobre carril DIN. Fuente: Elaboración propia / Licencia: CC BY-NC 4.0

PLCs distribuidos

En aplicaciones donde el proceso se extiende a lo largo de grandes distancias físicas, los sistemas distribuidos permiten descentralizar el control mediante varias unidades de PLC interconectadas a través de redes industriales. Cada subproceso cuenta con su propio PLC, que interactúa con los demás para coordinar el funcionamiento global. Este enfoque reduce el cableado, mejora la respuesta ante fallos localizados y facilita la gestión de procesos complejos, como plantas químicas, sistemas de transporte automatizados o grandes instalaciones logísticas. La arquitectura distribuida favorece la escalabilidad y la redundancia, aunque implica una mayor complejidad en la programación y la configuración de redes de comunicación.

PLCs de seguridad

Estos autómatas están diseñados para supervisar y controlar funciones críticas relacionadas con la seguridad de personas y equipos. Incorporan hardware y software certificados para cumplir normativas de seguridad funcional (IEC 61508, ISO 13849), y suelen incluir características como doble procesador, autodiagnóstico y capacidad de detección de fallos internos. Se emplean en aplicaciones donde los riesgos son elevados, como prensas industriales, robots colaborativos, sistemas de parada de emergencia y procesos con sustancias peligrosas. Su uso permite implementar funciones de seguridad integradas en el mismo sistema de automatización, evitando la necesidad de sistemas cableados independientes.

PLCs de altas prestaciones

Estos PLCs están orientados a procesos de gran complejidad, que exigen alta velocidad de procesamiento, gran capacidad de memoria, amplia conectividad y funciones avanzadas (control de movimiento, procesamiento de señales, integración con sistemas MES/ERP). Suelen encontrarse en industrias automotrices, farmacéuticas, alimentarias y en grandes infraestructuras, donde la fiabilidad y el tiempo de respuesta son críticos. Permiten manejar miles de E/S, procesar datos en tiempo real y gestionar redes de comunicación industrial de alto nivel. Su coste y complejidad de programación son superiores, pero aportan una capacidad de control inigualable en entornos exigentes.

La elección entre estos tipos de autómatas dependerá siempre de la complejidad del proceso, el entorno físico, los requisitos de seguridad, la necesidad de escalabilidad y el presupuesto disponible. Un análisis detallado de estos factores garantiza la selección del PLC más adecuado para cada aplicación.

🐍 Ejemplo de código Python: Simulación de configuración de un PLC modular
# ============================================================
# SIMULACIÓN DE CONFIGURACIÓN DE UN PLC MODULAR EN PYTHON
# ============================================================
# Este programa simula cómo se construye un PLC modular
# añadiendo diferentes módulos (CPU, E/S digitales, E/S analógicas,
# comunicación) a un chasis o rack.
#
# Se definen clases para cada tipo de módulo y se ensambla
# una configuración. Luego se muestra un resumen de los recursos
# totales (E/S, memoria, etc.) y se simula un ciclo de escaneo
# que utiliza algunos de esos módulos.
#
# Ejecútalo en Thonny para ver cómo se construye la configuración.
# ============================================================

class Modulo:
    """Clase base para cualquier módulo del PLC."""
    def __init__(self, nombre, tipo, consumo_watts):
        self.nombre = nombre
        self.tipo = tipo          # 'CPU', 'DI', 'DO', 'AI', 'AO', 'COM'
        self.consumo_watts = consumo_watts
        self.activo = True

    def __str__(self):
        return f"{self.nombre} ({self.tipo}) - {self.consumo_watts}W"

class ModuloCPU(Modulo):
    """Módulo procesador con memoria y velocidad."""
    def __init__(self, nombre, velocidad_mhz, memoria_kb, consumo_watts):
        super().__init__(nombre, 'CPU', consumo_watts)
        self.velocidad_mhz = velocidad_mhz
        self.memoria_kb = memoria_kb
        self.programa_cargado = False

    def cargar_programa(self):
        self.programa_cargado = True
        print(f"   ✅ Programa cargado en CPU {self.nombre}")

class ModuloEntradaDigital(Modulo):
    """Módulo de entradas digitales (por ejemplo, 16 entradas 24V)."""
    def __init__(self, nombre, num_entradas, tension_v, consumo_watts):
        super().__init__(nombre, 'DI', consumo_watts)
        self.num_entradas = num_entradas
        self.tension_v = tension_v
        # Simula los valores de las entradas (0/1)
        self.valores = [0] * num_entradas

    def leer_entrada(self, numero):
        """Devuelve el valor simulado de una entrada (podría leer de hardware)."""
        # En simulación, generamos un valor aleatorio o podemos modificarlo externamente
        import random
        self.valores[numero] = random.choice([0, 1])
        return self.valores[numero]

class ModuloSalidaDigital(Modulo):
    """Módulo de salidas digitales (por ejemplo, 8 salidas a relé)."""
    def __init__(self, nombre, num_salidas, corriente_max_a, consumo_watts):
        super().__init__(nombre, 'DO', consumo_watts)
        self.num_salidas = num_salidas
        self.corriente_max_a = corriente_max_a
        self.valores = [0] * num_salidas

    def escribir_salida(self, numero, valor):
        """Simula la activación de una salida."""
        if valor not in (0,1):
            raise ValueError("Valor debe ser 0 o 1")
        self.valores[numero] = valor
        print(f"      ⚙️ Salida {numero} del módulo {self.nombre} = {valor}")

class ModuloComunicacion(Modulo):
    """Módulo de comunicación (Ethernet/IP, Profibus, etc.)."""
    def __init__(self, nombre, protocolo, velocidad_mbps, consumo_watts):
        super().__init__(nombre, 'COM', consumo_watts)
        self.protocolo = protocolo
        self.velocidad_mbps = velocidad_mbps
        self.paquetes_enviados = 0

    def enviar_datos(self, destino, datos):
        """Simula el envío de datos por la red."""
        self.paquetes_enviados += 1
        print(f"      📡 Enviando {len(datos)} bytes a {destino} vía {self.protocolo}")

class PLCModular:
    """Representa un PLC modular con un chasis y varios módulos."""
    def __init__(self, nombre):
        self.nombre = nombre
        self.modulos = []          # Lista de módulos instalados
        self.fuente_alimentacion_watts = 0
        self.cpu = None

    def agregar_modulo(self, modulo):
        """Añade un módulo al PLC (si cabe en el chasis y hay potencia)."""
        self.modulos.append(modulo)
        if modulo.tipo == 'CPU':
            self.cpu = modulo
        print(f"   + Módulo añadido: {modulo}")

    def calcular_consumo_total(self):
        """Calcula el consumo total de todos los módulos."""
        total = sum(m.consumo_watts for m in self.modulos)
        return total

    def configurar_fuente(self, potencia_watts):
        """Configura la fuente de alimentación."""
        self.fuente_alimentacion_watts = potencia_watts
        consumo = self.calcular_consumo_total()
        if consumo > potencia_watts:
            print(f"⚠️ ADVERTENCIA: Consumo total ({consumo}W) excede la potencia de la fuente ({potencia_watts}W)")
        else:
            print(f"✅ Fuente configurada: {potencia_watts}W suficiente para {consumo}W")

    def resumen_configuracion(self):
        """Muestra un resumen de los módulos instalados."""
        print(f"\n{'='*50}")
        print(f"RESUMEN DEL PLC MODULAR: {self.nombre}")
        print(f"{'='*50}")
        print(f"Número de módulos: {len(self.modulos)}")
        print(f"Consumo total: {self.calcular_consumo_total()}W")
        print("Módulos instalados:")
        for i, mod in enumerate(self.modulos):
            print(f"  [{i}] {mod}")
        if self.cpu:
            print(f"   CPU: {self.cpu.nombre} a {self.cpu.velocidad_mhz} MHz, {self.cpu.memoria_kb} KB")
        print(f"{'='*50}\n")

    def ciclo_escaneo(self):
        """Simula un ciclo de escaneo: lee entradas, ejecuta lógica, actualiza salidas."""
        if not self.cpu:
            print("❌ No hay CPU instalada. No se puede ejecutar el ciclo.")
            return
        print(f"\n🔄 Ciclo de escaneo del PLC {self.nombre}")
        # Leer entradas digitales (simulado)
        for mod in self.modulos:
            if mod.tipo == 'DI':
                for i in range(mod.num_entradas):
                    valor = mod.leer_entrada(i)
                    print(f"      📥 Entrada DI {i} = {valor}")
        # Simular lógica simple: si alguna entrada está activa, activar salida 0 del primer módulo DO
        for mod in self.modulos:
            if mod.tipo == 'DO':
                # Lógica de ejemplo: si la primera entrada del primer DI está a 1, activar salida 0
                for mod_ent in self.modulos:
                    if mod_ent.tipo == 'DI' and mod_ent.valores[0] == 1:
                        mod.escribir_salida(0, 1)
                    else:
                        mod.escribir_salida(0, 0)
                break  # Solo actuamos sobre el primer DO encontrado
        print("✅ Ciclo completado.\n")

# ------------------------------------------------------------
# EJEMPLO DE CONFIGURACIÓN
# ------------------------------------------------------------
if __name__ == "__main__":
    print("🎛️ CONSTRUCCIÓN DE UN PLC MODULAR")
    print("="*60)

    # 1. Crear el PLC
    mi_plc = PLCModular("PLC_Principal")

    # 2. Crear módulos
    cpu = ModuloCPU("CPU 314", velocidad_mhz=100, memoria_kb=256, consumo_watts=8)
    di_16 = ModuloEntradaDigital("DI 16x24V", num_entradas=16, tension_v=24, consumo_watts=2)
    do_8 = ModuloSalidaDigital("DO 8xRelé", num_salidas=8, corriente_max_a=2, consumo_watts=3)
    ai_4 = Modulo("AI 4x20mA", "AI", 2)  # Usamos clase base para simplicidad
    com_eth = ModuloComunicacion("COM Ethernet/IP", protocolo="Ethernet/IP", velocidad_mbps=100, consumo_watts=4)

    # 3. Añadir módulos al PLC
    mi_plc.agregar_modulo(cpu)
    mi_plc.agregar_modulo(di_16)
    mi_plc.agregar_modulo(do_8)
    mi_plc.agregar_modulo(ai_4)
    mi_plc.agregar_modulo(com_eth)

    # 4. Configurar fuente de alimentación
    mi_plc.configurar_fuente(potencia_watts=30)

    # 5. Mostrar resumen
    mi_plc.resumen_configuracion()

    # 6. Cargar programa en la CPU
    cpu.cargar_programa()

    # 7. Simular varios ciclos de escaneo
    for ciclo in range(3):
        mi_plc.ciclo_escaneo()

    print("\n✅ Simulación finalizada. Observa cómo se añaden módulos y se ejecuta el ciclo.")

Este código simula la construcción de un PLC modular. Se definen clases para los diferentes tipos de módulos (CPU, entradas digitales, salidas digitales, comunicación). Luego se instancian y se añaden a un PLC. Finalmente se muestra un resumen y se ejecutan varios ciclos de escaneo simulados. Es una excelente forma de entender la arquitectura modular y cómo se integran los componentes.

Recuerda

La correcta clasificación y selección del tipo de autómata programable no sólo optimiza el rendimiento y la flexibilidad del proceso automatizado, sino que también facilita el mantenimiento, la ampliación futura del sistema y el cumplimiento de normativas de seguridad. Antes de elegir un PLC, es fundamental evaluar tanto las necesidades presentes como las posibles evoluciones del proceso, teniendo en cuenta tanto las limitaciones físicas como las exigencias funcionales del entorno industrial.

💼 Caso Práctico Industrial

Contexto: Una empresa química necesita controlar una planta de proceso que se extiende a lo largo de 1 km, con varias estaciones independientes (reactores, tanques de mezcla, filtros). Se requiere que cada estación tenga su propio control local, pero que todas estén coordinadas desde una sala de control central. Además, se necesita alta fiabilidad y redundancia.

Problema: ¿Qué tipo de PLC es el más adecuado para esta aplicación?

Pregunta: Selecciona la opción correcta:

🍓 Caso Práctico Raspberry Pi

Contexto: Quieres usar una Raspberry Pi como un PLC compacto para controlar un pequeño sistema de riego automático. Tienes 4 entradas digitales (sensores de humedad) y 2 salidas digitales (electroválvulas). La Raspberry Pi tiene GPIO, pero no entradas analógicas.

Problema: ¿Cómo podrías adaptar la Raspberry Pi para que funcione como un PLC compacto con las E/S necesarias?

Pregunta: Elige la opción más adecuada:

🐍 Caso Práctico Python

Contexto: En el código de simulación del PLC modular, la clase `PLCModular` tiene un método `ciclo_escaneo()` que implementa una lógica muy simple. Supongamos que queremos añadir un nuevo módulo de salidas analógicas (`ModuloSalidaAnalógica`) que herede de `Modulo`. Este nuevo módulo tendría un método `escribir_analogico(canal, valor)`.

Problema: ¿Qué modificación habría que hacer en el método `ciclo_escaneo()` para que también actualice las salidas analógicas?

Pregunta: Selecciona la opción correcta:

📚 Recursos Técnicos y Normativos 2026