Saltar al contenido
Todo Automatizado
Automatización Industrial

Conectar PLC con Base de Datos: Guía Práctica con SQL, MQTT y OPC UA

Aprende a conectar un PLC con base de datos SQL paso a paso. Métodos reales con OPC UA, MQTT y middleware para registrar datos de producción sin perder el sueño.

Carlos 18 min de lectura

Conectar PLC con Base de Datos: Guía Práctica con SQL, MQTT y OPC UA

Tienes un PLC controlando una línea de producción. Funciona perfecto: mueve motores, lee sensores, gestiona alarmas. Pero todos esos datos — temperaturas, contadores de piezas, estados de máquina — se pierden en el vacío cada vez que apagas el sistema. O peor: los recoges en un Excel que alguien rellena a mano al final del turno.

Conectar tu PLC con una base de datos no es un capricho de informático. Es la diferencia entre operar a ciegas y tener un historial completo de lo que hace tu planta. Trazabilidad, mantenimiento predictivo, informes automáticos, KPIs de producción en tiempo real — todo empieza por meter esos datos en una base de datos.

El problema es que un PLC no habla SQL. Está diseñado para ejecutar lógica de control en ciclos de milisegundos, no para conectarse a un PostgreSQL y lanzar INSERTs. Así que necesitas un puente entre ambos mundos, y elegir el puente equivocado te puede costar meses de trabajo y un montón de frustraciones.

En esta guía te explico los métodos reales que funcionan en planta, con sus ventajas e inconvenientes. Sin teoría abstracta ni diagramas bonitos que no te dicen cómo cablear nada.

Por qué necesitas conectar tu PLC a una base de datos

Antes de meternos en el cómo, conviene tener claro el para qué. Porque la respuesta condiciona el método, la base de datos y la arquitectura que elijas.

Trazabilidad y cumplimiento normativo

En sectores como alimentación, farmacéutica o automoción, no almacenar datos de proceso no es una opción: es un incumplimiento. La normativa FDA 21 CFR Part 11, las trazabilidades de lotes según IFS o BRC, los registros APPCC — todo exige que puedas demostrar qué parámetros tenía tu proceso cuando fabricaste un producto concreto.

Con los datos en una base de datos, generas el informe de un lote con una consulta SQL en lugar de rebuscar en carpetas de papel durante horas.

Mantenimiento predictivo real

Un PLC sabe que un motor lleva 4.327 horas de funcionamiento. Pero esa información no sirve de nada si se queda encerrada en un registro del PLC que nadie consulta. Cuando esas horas se almacenan en una base de datos junto con la temperatura de los rodamientos, el consumo eléctrico y las vibraciones, puedes construir modelos que te avisan antes de que la máquina se rompa.

El mantenimiento correctivo cuesta entre 5 y 10 veces más que el predictivo. Pero el predictivo necesita datos históricos. Y los datos históricos necesitan una base de datos.

Informes y dashboards de producción

El turno de noche produjo 12.400 piezas con un 2,3% de rechazo. El turno de mañana, 11.800 con un 3,1%. ¿Por qué la diferencia? Sin datos almacenados, solo tienes opiniones. Con una base de datos y un Grafana encima, tienes hechos.

Los dashboards de producción en tiempo real — OEE, tiempos de parada, velocidades de línea, consumo energético — se alimentan de datos que salen de los PLCs y se guardan en bases de datos. No hay otra forma escalable de hacerlo.

Integración con ERP y MES

Tu SAP, tu Navision o tu sistema MES necesitan saber qué está pasando en planta. Cuántas piezas se han fabricado, cuánta materia prima se ha consumido, qué máquinas están paradas. La base de datos actúa como punto de encuentro entre el mundo OT (tu PLC) y el mundo IT (tu ERP).

Sin esa conexión, alguien tiene que teclear datos a mano. Y los datos tecleados a mano llegan tarde, con errores y sin el detalle que necesitas.

Los tres caminos para conectar un PLC con una base de datos

No existe una forma única de hacerlo. Hay tres enfoques principales, cada uno con su nivel de complejidad, coste y casos de uso. Vamos de menos a más sofisticado.

Método 1: Middleware con OPC UA (el más robusto)

OPC UA es el estándar industrial para comunicación entre dispositivos. Si tu PLC tiene un servidor OPC UA integrado (la mayoría de los modernos lo tienen: Siemens S7-1500, Rockwell CompactLogix, Beckhoff TwinCAT, Omron NX/NJ), este es el camino más limpio.

Cómo funciona:

PLC (servidor OPC UA) → Cliente OPC UA (middleware) → Base de datos SQL

El middleware lee las variables del PLC vía OPC UA y las escribe en la base de datos. Los más usados en planta son:

  • Kepware KEPServerEX: el estándar de facto. Soporta prácticamente todos los PLCs del mercado. Su módulo IoT Gateway puede escribir directamente a bases de datos SQL o publicar en MQTT. Licencia comercial (desde ~2.000 €).
  • Ignition de Inductive Automation: no es solo un gateway OPC UA, es una plataforma SCADA completa. Su módulo Tag Historian escribe directamente a SQL Server, MySQL o PostgreSQL. Licencia modular (desde ~3.500 €).
  • Node-RED con node-opcua: opción open source. Lees variables OPC UA y las insertas en la base de datos con nodos SQL. Gratis, pero requiere que sepas lo que haces.

Ejemplo real con Kepware:

  1. Configuras un canal en Kepware apuntando al PLC (por ejemplo, un Siemens S7-1500 por su IP).
  2. Añades los tags que quieres registrar: Temperatura_Horno, Contador_Piezas, Estado_Linea.
  3. Activas el módulo IoT Gateway con salida ODBC hacia tu base de datos.
  4. Defines la tabla destino y el intervalo de escritura (por ejemplo, cada 5 segundos).
  5. Arrancas y los datos empiezan a fluir.

Ventajas de OPC UA:

  • Estándar industrial, no dependes de un fabricante.
  • Seguridad integrada: autenticación, cifrado y certificados X.509.
  • Lee cualquier tipo de dato del PLC: enteros, reales, strings, arrays, estructuras.
  • Descubrimiento automático de variables (el cliente puede explorar qué ofrece el servidor).

Inconvenientes:

  • Configurar un servidor OPC UA en PLCs antiguos puede ser un dolor. Los S7-300 no lo soportan nativamente; necesitas un gateway externo.
  • Kepware e Ignition no son baratos. Para una instalación pequeña puede ser sobredimensionado.

Método 2: MQTT + broker + script de inserción (el más flexible)

MQTT se ha comido el mundo del IoT industrial en los últimos años, y por buenas razones. Es ligero, eficiente y funciona en conexiones inestables. Muchos PLCs modernos ya traen cliente MQTT integrado.

Cómo funciona:

PLC (cliente MQTT) → Broker MQTT (Mosquitto) → Suscriptor (Python/Node-RED) → Base de datos SQL

El PLC publica datos en un topic MQTT. Un script suscriptor recoge esos mensajes y los inserta en la base de datos.

Ejemplo práctico con un Siemens S7-1500 y Python:

En el PLC (TIA Portal), activas el bloque de función MQTT_CLIENT. Configuras la IP del broker, el topic (por ejemplo, planta/linea1/produccion) y los datos a publicar en formato JSON:

{
  "timestamp": "2026-06-06T14:30:00",
  "temperatura": 182.5,
  "piezas_ok": 1247,
  "piezas_nok": 29,
  "estado": "produccion"
}

En el servidor, un script Python con paho-mqtt se suscribe al topic y escribe en PostgreSQL:

import paho.mqtt.client as mqtt
import psycopg2
import json
from datetime import datetime

conn = psycopg2.connect(
    host="localhost",
    database="produccion",
    user="scada_writer",
    password="tu_password_segura"
)

def on_message(client, userdata, msg):
    data = json.loads(msg.payload)
    cur = conn.cursor()
    cur.execute("""
        INSERT INTO datos_linea1 
        (timestamp, temperatura, piezas_ok, piezas_nok, estado)
        VALUES (%s, %s, %s, %s, %s)
    """, (
        data['timestamp'],
        data['temperatura'],
        data['piezas_ok'],
        data['piezas_nok'],
        data['estado']
    ))
    conn.commit()
    cur.close()

client = mqtt.Client()
client.connect("localhost", 1883, 60)
client.subscribe("planta/linea1/produccion")
client.on_message = on_message
client.loop_forever()

Ventajas de MQTT:

  • Ligero: funciona con ancho de banda mínimo (ideal para plantas remotas o con conectividad 4G).
  • Desacoplado: el PLC publica y se olvida. Si el suscriptor se cae, los mensajes se retienen en el broker (con QoS 1 o 2).
  • Escalable: añadir más PLCs es añadir más topics. El suscriptor los recoge todos.
  • Coste cero en software: Mosquitto, Python y PostgreSQL son open source.

Inconvenientes:

  • No todos los PLCs soportan MQTT nativo. Los Siemens S7-1200/1500 sí (desde firmware V4.4), los Allen-Bradley necesitan un gateway.
  • Pierdes la riqueza de tipos de datos de OPC UA. MQTT transmite bytes o strings; la estructura de datos la defines tú en el payload.
  • Si tu script Python se cae y no tienes supervisión (systemd, Docker), pierdes datos.

Método 3: Escritura directa desde el PLC (el más simple, pero el más limitado)

Algunos PLCs permiten ejecutar consultas SQL directamente desde el programa. Es la opción más directa, pero tiene trampas serias.

PLCs que lo soportan:

  • Siemens S7-1500 con el bloque de comunicación abierta (TCON/TSEND). Técnicamente posible pero engorroso.
  • Beckhoff TwinCAT: tiene el módulo TF6420 Database Server que ejecuta queries SQL desde código ST (Structured Text). Es el que mejor lo implementa.
  • Codesys: con la librería SQL Client, si tu PLC corre sobre Codesys.

Ejemplo con Beckhoff TwinCAT 3:

// Structured Text - Insertar datos en SQL Server
FB_SQLCommand.sCommand := 'INSERT INTO produccion (timestamp, piezas, temperatura) VALUES (GETDATE(), $piezas$, $temp$)';
FB_SQLCommand.Execute();

Ventajas:

  • Sin middleware. Sin brokers. Sin scripts. El PLC habla directamente con la base de datos.
  • Latencia mínima entre evento y registro.
  • Menos componentes que mantener.

Inconvenientes (y son serios):

  • Acoplas el PLC a la base de datos. Si la base de datos se cae o tarda en responder, el ciclo del PLC se resiente. Dependiendo de la implementación, puede incluso bloquear la ejecución del programa.
  • Gestión de errores limitada. Un middleware reintenta, cachea y gestiona desconexiones. Un PLC no está diseñado para eso.
  • Mantenimiento complicado. Cada cambio en la estructura de la tabla requiere modificar el programa del PLC y descargarlo. Eso es parada de producción.
  • Seguridad. Estás metiendo credenciales de base de datos en un PLC. Piensa en eso un momento.

Mi recomendación: solo para instalaciones muy pequeñas (un PLC, una tabla, datos no críticos) o prototipos rápidos. Para producción real, usa middleware.

Qué base de datos elegir

No todas las bases de datos son iguales para datos industriales. Tus requisitos son específicos: inserciones masivas y constantes, pocas actualizaciones, consultas por rango de tiempo y retención de datos durante años.

Bases de datos relacionales (SQL)

  • PostgreSQL: mi primera opción. Open source, robusto, con extensiones para series temporales (TimescaleDB). Soporta particionado de tablas por fecha, índices BRIN para consultas temporales eficientes y tiene una comunidad enorme. Si no sabes por dónde empezar, empieza aquí.
  • MySQL / MariaDB: funciona perfectamente para instalaciones pequeñas y medianas. Menos funcionalidades avanzadas que PostgreSQL, pero más fácil de administrar si ya lo conoces.
  • SQL Server: si tu entorno es Microsoft (Windows Server, .NET, Power BI), SQL Server se integra bien y Kepware lo soporta nativamente.

Bases de datos de series temporales (Time-Series)

  • TimescaleDB: extensión de PostgreSQL optimizada para datos temporales. Obtienes lo mejor de SQL con rendimiento específico para time-series. Inserción de millones de filas por segundo en hardware modesto. Es mi recomendación para nuevos proyectos.
  • InfluxDB: diseñada específicamente para métricas y datos IoT. Consultas con su lenguaje Flux (o InfluxQL). Excelente rendimiento, pero te ata a un ecosistema propio.
  • QuestDB: la alternativa nueva que está ganando tracción. Rendimiento brutal para inserciones y compatible con protocolo PostgreSQL. Vale la pena evaluarla.

¿Cuál elegir?

CriterioPostgreSQL / TimescaleDBInfluxDBSQL Server
CosteGratis (open source)Gratis (OSS) / pago (Cloud)Licencia (~1.000-5.000 €)
FacilidadMediaFácil para métricasFácil en entorno Windows
Rendimiento time-seriesExcelente (con TimescaleDB)ExcelenteBueno
Integración IT/ERPMáxima (SQL estándar)LimitadaMáxima (ecosistema MS)
Retención largo plazoExcelenteBuena (políticas de retención)Buena

Para la mayoría de plantas industriales, PostgreSQL con TimescaleDB es la opción más equilibrada. Gratis, potente, estándar SQL y con la optimización temporal que necesitas. Si ya tienes SQL Server en tu infraestructura IT, no tiene sentido añadir otra base de datos.

Diseño de la base de datos: errores comunes y cómo evitarlos

Meter datos en una tabla es fácil. Diseñar una estructura que funcione bien cuando tengas 500 millones de filas al cabo de un año es otra historia.

Error 1: Una tabla por tag

He visto instalaciones con una tabla para Temperatura_Horno_1, otra para Temperatura_Horno_2, otra para Velocidad_Motor_1… y así 300 tablas. Es un pesadilla de mantenimiento y las consultas cruzadas son imposibles de escribir sin JOIN monstruosos.

Mejor enfoque: tabla única con columna de identificador.

CREATE TABLE datos_proceso (
    time        TIMESTAMPTZ NOT NULL,
    tag_name    TEXT NOT NULL,
    value       DOUBLE PRECISION,
    quality     SMALLINT DEFAULT 192
);

-- Con TimescaleDB:
SELECT create_hypertable('datos_proceso', 'time');

-- Índice para consultas por tag:
CREATE INDEX idx_tag_time ON datos_proceso (tag_name, time DESC);

Con esta estructura, añadir un tag nuevo es añadir una fila, no crear una tabla. Y consultar el histórico de cualquier variable es una query sencilla:

SELECT time, value 
FROM datos_proceso 
WHERE tag_name = 'Temperatura_Horno_1' 
  AND time > NOW() - INTERVAL '24 hours'
ORDER BY time;

Error 2: No particionar por tiempo

Cuando tu tabla tiene 100 millones de filas, cada consulta recorre todo el disco. Si particionas por mes (o por semana, según tu volumen), PostgreSQL solo lee la partición relevante.

-- Particionado nativo en PostgreSQL 12+:
CREATE TABLE datos_proceso (
    time        TIMESTAMPTZ NOT NULL,
    tag_name    TEXT NOT NULL,
    value       DOUBLE PRECISION
) PARTITION BY RANGE (time);

CREATE TABLE datos_2026_06 PARTITION OF datos_proceso
    FOR VALUES FROM ('2026-06-01') TO ('2026-07-01');

O usa TimescaleDB y olvídate: lo hace automáticamente con chunks de 7 días.

Error 3: Guardar todo a máxima resolución para siempre

Tu PLC actualiza datos cada 100 ms. Almacenar todo eso durante cinco años genera 1,5 billones de filas por tag. ¿Necesitas el dato de cada 100 ms de hace tres años? Probablemente no.

Estrategia de retención escalonada:

  • Últimos 30 días: resolución completa (cada segundo o menos).
  • Últimos 12 meses: datos agregados cada minuto (media, máximo, mínimo).
  • Más de 1 año: datos agregados cada hora.

TimescaleDB tiene funciones de agregación continua que automatizan esto. En PostgreSQL puro, un cron job con un script de compactación cumple la misma función.

Error 4: No pensar en la seguridad

Nunca, repito, nunca conectes tu PLC directamente al servidor de base de datos por la red de producción sin un firewall en medio. Crea un usuario de base de datos específico para escritura con permisos mínimos (INSERT en las tablas necesarias y nada más). Y no guardes credenciales en texto plano en el middleware — usa variables de entorno o un gestor de secretos.

-- Usuario con permisos mínimos:
CREATE USER scada_writer WITH PASSWORD 'contraseña_fuerte';
GRANT INSERT ON datos_proceso TO scada_writer;
-- Sin SELECT, sin DELETE, sin acceso a otras tablas.

Arquitectura completa: del PLC al dashboard

Vamos a juntar todas las piezas en una arquitectura que funciona en producción. Este es el stack que uso y recomiendo para plantas medianas:

Red OT (planta)              DMZ / Edge                    Red IT / Cloud
────────────────         ──────────────────           ─────────────────────
PLC Siemens S7-1500      Node-RED / Kepware            PostgreSQL + TimescaleDB
PLC Allen-Bradley           (OPC UA client)                    ↓
Sensores IoT                     ↓                      Grafana (dashboards)
      ↓                   Mosquitto MQTT                       ↓
   Red PROFINET               ↓                      Alertas (Telegram/email)
                        Script Python                          ↓
                        (suscriptor MQTT)              API REST (para ERP)

                        PostgreSQL ←─────────────────── 

Flujo de datos:

  1. Los PLCs exponen variables vía OPC UA.
  2. Node-RED (o Kepware) lee esas variables y las publica en MQTT con un topic estructurado: planta/linea1/horno/temperatura.
  3. Un suscriptor Python (o el propio Node-RED) recoge los mensajes MQTT y los inserta en PostgreSQL/TimescaleDB.
  4. Grafana lee la base de datos y muestra dashboards en tiempo real.
  5. Alertas configuradas en Grafana envían notificaciones por Telegram o email cuando un valor se sale de rango.

¿Por qué Node-RED + MQTT en lugar de escribir directamente desde Kepware a SQL?

Porque el broker MQTT actúa como buffer. Si la base de datos se cae durante 10 minutos, los mensajes se acumulan en el broker y se procesan cuando vuelve. Si Kepware escribe directamente a SQL y la base de datos no responde, pierdes datos. El desacoplamiento que da MQTT vale su peso en oro en entornos industriales donde la fiabilidad es innegociable.

Caso práctico: registrar producción de una línea de envasado

Para aterrizar toda la teoría, vamos con un caso real simplificado.

Escenario: una línea de envasado con un PLC Siemens S7-1500 que controla el proceso. Necesitas registrar cada 5 segundos: unidades producidas, velocidad de línea (envases/minuto), temperatura de sellado, presión de aire y estado de la máquina (producción, parada, limpieza, avería).

Paso 1 — Crear la tabla en PostgreSQL:

CREATE TABLE linea_envasado (
    time            TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    unidades        INTEGER,
    velocidad       REAL,
    temp_sellado    REAL,
    presion_aire    REAL,
    estado          TEXT
);

-- Optimización temporal con TimescaleDB:
SELECT create_hypertable('linea_envasado', 'time');

Paso 2 — Configurar Node-RED:

Un flow sencillo con tres nodos:

  • OPC UA Client: conecta al S7-1500 y lee los tags cada 5 segundos.
  • Function: formatea los datos como objeto JSON.
  • PostgreSQL node: ejecuta el INSERT.

El nodo Function:

msg.payload = [
    new Date().toISOString(),
    msg.payload.unidades,
    msg.payload.velocidad,
    msg.payload.temp_sellado,
    msg.payload.presion_aire,
    msg.payload.estado
];
msg.query = `INSERT INTO linea_envasado 
    (time, unidades, velocidad, temp_sellado, presion_aire, estado) 
    VALUES ($1, $2, $3, $4, $5, $6)`;
return msg;

Paso 3 — Dashboard en Grafana:

Una consulta para mostrar la producción del turno actual:

SELECT 
    time_bucket('1 hour', time) AS hora,
    MAX(unidades) - MIN(unidades) AS produccion_hora,
    AVG(velocidad) AS velocidad_media,
    AVG(temp_sellado) AS temp_media
FROM linea_envasado
WHERE time > NOW() - INTERVAL '8 hours'
GROUP BY hora
ORDER BY hora;

Con cuatro paneles en Grafana — producción acumulada, velocidad en tiempo real, temperatura de sellado y estado de máquina — tienes un dashboard de producción completo montado en una tarde.

Rendimiento: cuántos datos puedes manejar

Una pregunta legítima: ¿aguanta esta arquitectura el volumen de datos de mi planta?

Números reales con hardware modesto (servidor con 4 cores, 16 GB RAM, SSD):

  • PostgreSQL con TimescaleDB: 100.000+ inserciones por segundo. Para 500 tags a 1 segundo de resolución, estás usando el 0,5% de la capacidad.
  • Mosquitto MQTT: 50.000+ mensajes por segundo en un Raspberry Pi. En un servidor, ni te preocupes.
  • Node-RED: el cuello de botella suele ser la conexión OPC UA, no Node-RED. Con 1.000 tags a 1 segundo, consume menos de 200 MB de RAM.

Para plantas grandes (5.000+ tags a alta frecuencia), considera usar el driver nativo de TimescaleDB con inserciones batch en lugar de filas individuales. La diferencia es de 10x en rendimiento.

Errores que te van a hacer perder tiempo (y cómo evitarlos)

Después de implementar estas conexiones en múltiples plantas, estos son los errores que veo repetirse:

1. No gestionar la zona horaria. Tu PLC trabaja en hora local. Tu servidor de base de datos puede estar en UTC. Tu dashboard muestra la hora del navegador del usuario. Si no normalizas a UTC desde el principio y conviertes solo al visualizar, vas a tener turnos que “se solapan” y datos que “desaparecen” en los cambios de hora.

2. No monitorizar el pipeline. El PLC funciona, el broker funciona, la base de datos funciona… pero el script Python se cayó hace tres horas y nadie se ha enterado. Mete el suscriptor en un servicio systemd con reinicio automático y configura una alerta si deja de insertar datos durante más de 60 segundos.

3. No hacer copias de seguridad automatizadas. Tienes dos años de datos de producción en una base de datos sin backup. Un disco se corrompe y pierdes todo. pg_dump con un cron diario a un almacenamiento externo. No es negociable.

4. Intentar leer datos del PLC demasiado rápido. OPC UA en un S7-1500 puede manejar lecturas cada 100 ms sin problema. Pero si tienes 500 tags y los lees todos a 100 ms, estás generando 5.000 lecturas por segundo, y el PLC va a empezar a quejarse. Agrupa las lecturas y ajusta la frecuencia según la necesidad real. ¿Necesitas la temperatura del horno cada 100 ms? Probablemente cada 5 segundos baste.

5. No separar red OT y red IT. Tu PLC no debe estar en la misma red que el servidor de correo. Punto. Un firewall entre la red de planta y la red IT con reglas que solo permitan el tráfico necesario (OPC UA en el puerto 4840, MQTT en el 8883 con TLS). Consulta la norma IEC 62443 si quieres hacer las cosas bien.

Conclusión

Conectar un PLC con una base de datos es un proyecto que parece simple en la teoría y que tiene matices importantes en la práctica. La buena noticia es que con herramientas open source — Node-RED, Mosquitto, PostgreSQL y Grafana — puedes montar una solución de nivel profesional sin gastar un euro en licencias.

Mi recomendación para empezar: elige un PLC de prueba, monta el stack MQTT + PostgreSQL + Grafana en un servidor o incluso en una Raspberry Pi, y conecta cinco o diez tags. Cuando veas los datos fluyendo en un dashboard, vas a querer conectar toda la planta. Y entonces agradecerás haber diseñado bien la base de datos desde el principio.

Los datos de tu planta son un activo. Cada día que pasan sin almacenarse es información que pierdes para siempre. Y en un mercado donde la eficiencia se mide en décimas de porcentaje, esa información marca la diferencia entre una planta que sobrevive y una que compite.


¿Quieres conectar los PLCs de tu planta a una base de datos y no sabes por dónde empezar? En automatizatodo.com diseñamos e implementamos soluciones de captura de datos industriales adaptadas a tu instalación — desde un piloto con un solo PLC hasta despliegues en múltiples plantas. Contacta con nosotros y te ayudamos a sacarle valor a los datos que tu planta ya genera.

#PLC #base de datos #SQL #OPC UA #MQTT #automatización industrial #historian #Node-RED #Kepware

Sigue leyendo