IoT industrial

Beckhoff TwinCAT MQTT: publicar datos estructurados del PLC en un broker

Usa las funciones IoT de TwinCAT 3 para publicar datos estructurados del PLC en JSON, verificarlos en un broker público y conectarte después a un broker privado con TLS, credenciales y un Last Will.

PC industrial Beckhoff con TwinCAT 3 publicando datos de máquina en un broker en la nube, ilustrando Beckhoff TwinCAT MQTT
Pruébalo en tu propio broker MQTTConsigue un broker MQTT privado y gestionado con el plan Free y empieza con ejemplos de código listos para usar.
Pruébalo gratis Ejemplos de código Sin tarjeta

El soporte de Beckhoff TwinCAT MQTT permite que un PC industrial Beckhoff publique datos de máquina directamente desde el runtime del PLC, sin un gateway aparte en el armario. En este tutorial usarás las funciones IoT de TwinCAT 3 para conectarte a un broker MQTT, serializar un tipo de dato estructurado a JSON, publicarlo al cambiar y con un temporizador y, por último, proteger la conexión con TLS y credenciales. El mismo patrón escala desde un único banco de pruebas hasta una flota de máquinas.

Comparativa de opciones MQTT en TwinCAT

Beckhoff ofrece más de una vía hacia MQTT, y elegir la adecuada desde el principio ahorra trabajo.

Opción Qué es Quién la configura Ideal para
TF6701 IoT Communication Librería de PLC (Tc3_IotBase) con un bloque de función de cliente MQTT El programador del PLC, en texto estructurado Control total de topics, payloads y temporización
TF6720 IoT Data Agent Gateway basado en configuración que asigna símbolos ADS a MQTT Interfaz gráfica de configuración, sin código de PLC Publicar símbolos existentes sin cambiar el programa del PLC
Gateway ADS externo Tu propio servicio que lee símbolos por ADS y publica MQTT El equipo de software Canalizaciones a medida, muchos controladores, formatos no estándar

Este tutorial usa TF6701 porque es la opción más habitual entre los fabricantes de máquinas que quieren que el comportamiento MQTT forme parte del proyecto de PLC versionado. Tanto TF6701 como TF6720 son funciones de TwinCAT con licencia; una licencia de prueba de 7 días basta para seguir el tutorial.

Requisitos previos

  • TwinCAT 3.1 XAE (Visual Studio o TwinCAT XAE Shell) y un destino: un IPC de Beckhoff, o tu PC de ingeniería en modo run para pruebas.
  • La función TF6701 instalada en el destino y una licencia de prueba o completa activada.
  • Acceso de red saliente desde el destino hasta el broker por TCP 1883 para pruebas y 8883 para TLS.
  • Las librerías de PLC Tc3_IotBase y Tc3_JsonXml añadidas a las referencias del proyecto.
  • Clientes de mosquitto en un PC para la verificación.

Paso 1: definir un tipo de dato estructurado

Publicar una estructura en lugar de variables sueltas mantiene juntos los valores relacionados y coherentes las marcas de tiempo. Añade un DUT:

TYPE ST_PressData :
STRUCT
    rForce_kN       : REAL;
    rTemperature_C  : REAL;
    nCycleCount     : UDINT;
    bRunning        : BOOL;
    sState          : STRING(20);
END_STRUCT
END_TYPE

Paso 2: conectar con FB_IotMqttClient

FB_IotMqttClient, de Tc3_IotBase, se configura mediante propiedades y se controla llamando a su método Execute en cada ciclo. Llámalo desde una tarea con un ciclo de 10 ms o más rápido; el cliente gestiona su propia comunicación en segundo plano, pero solo avanza cuando se llama a Execute.

PROGRAM MAIN
VAR
    fbMqttClient   : FB_IotMqttClient;
    bSetParameter  : BOOL := TRUE;
    bConnect       : BOOL := TRUE;

    fbJson         : FB_JsonSaxWriter;
    stPress        : ST_PressData;
    stLastPress    : ST_PressData;

    sTopicData     : STRING(255) := 'connectmq/demo/t3w9p1/plant1/stamping/cell4/press1/telemetry';
    sPayload       : STRING(1023);
    fbHeartbeat    : TON;
    bPublish       : BOOL;
END_VAR

// --- One-time client configuration ---
IF bSetParameter THEN
    bSetParameter := FALSE;
    fbMqttClient.sHostName  := 'broker.connectmq.com';
    fbMqttClient.nHostPort  := 1883;
    fbMqttClient.sClientId  := 'twincat-demo-t3w9p1';   // non-empty and unique
    fbMqttClient.nKeepAlive := 30;
END_IF

// --- Keep the connection alive every cycle ---
fbMqttClient.Execute(bConnect);

// --- Decide when to publish: on change or every 10 s ---
fbHeartbeat(IN := NOT fbHeartbeat.Q, PT := T#10S);
bPublish := fbHeartbeat.Q
            OR ABS(stPress.rForce_kN - stLastPress.rForce_kN) > 1.0
            OR stPress.bRunning <> stLastPress.bRunning
            OR stPress.sState <> stLastPress.sState;

// --- Serialize and publish ---
IF bPublish AND fbMqttClient.bConnected THEN
    fbJson.ResetDocument();
    fbJson.StartObject();
    fbJson.AddKey('force_kN');       fbJson.AddReal(stPress.rForce_kN);
    fbJson.AddKey('temperature_C');  fbJson.AddReal(stPress.rTemperature_C);
    fbJson.AddKey('cycle_count');    fbJson.AddUdint(stPress.nCycleCount);
    fbJson.AddKey('running');        fbJson.AddBool(stPress.bRunning);
    fbJson.AddKey('state');          fbJson.AddString(stPress.sState);
    fbJson.EndObject();
    fbJson.CopyDocument(sPayload, SIZEOF(sPayload));

    fbMqttClient.Publish(
        sTopic       := sTopicData,
        pPayload     := ADR(sPayload),
        nPayloadSize := LEN(sPayload),
        eQoS         := TcIotMqttQos.AtLeastOnceDelivery,
        bRetain      := FALSE,
        bQueue       := FALSE);

    stLastPress := stPress;
END_IF

Algunas notas sobre las decisiones anteriores:

  • CopyDocument en lugar de GetDocument. GetDocument devuelve un string estándar de 255 caracteres, que trunca en silencio los payloads más grandes. Copiar en un buffer dimensionado lo evita.
  • Report by exception. La banda muerta de fuerza y las comparaciones de estado publican los cambios reales de inmediato, mientras que el latido de 10 segundos demuestra que la máquina sigue viva aunque nada cambie.
  • Gestión de errores. Vigila fbMqttClient.hrErrorCode y fbMqttClient.eConnectionState en la vista online durante la puesta en marcha. La mayoría de los fallos aparecen ahí primero.

Para estructuras más grandes, Tc3_JsonXml también ofrece una función auxiliar que serializa un tipo de dato completo, incluidos atributos como las unidades, en una sola llamada. La salida SAX escrita a mano como la anterior te da un control exacto sobre los nombres de las claves, algo importante cuando otros equipos consumen los datos.

Paso 3: verificar en el broker público

Activa la configuración, arranca el PLC y suscríbete desde un PC:

mosquitto_sub -h broker.connectmq.com -p 1883 -i twincat-watch-t3w9p1 \
  -t 'connectmq/demo/t3w9p1/#' -v

Salida esperada:

connectmq/demo/t3w9p1/plant1/stamping/cell4/press1/telemetry {"force_kN":412.5,"temperature_C":38.2,"cycle_count":10233,"running":true,"state":"AUTO"}

Fuerza un valor en la vista online y el cambio aparecerá al instante. El servidor MQTT público gratuito broker.connectmq.com, anónimo, es perfecto para este tipo de puesta en marcha, pero es público y está pensado para pruebas y prototipos, no para datos de producción, así que usa un prefijo de topic aleatorio y nada confidencial.

Paso 4: proteger la conexión Beckhoff TwinCAT MQTT

Las máquinas de producción nunca deben publicar por TCP sin cifrar hacia internet. Crea un broker privado en el portal de ConnectMQ, anota el usuario, la contraseña y el client ID generados y después:

  1. Descarga el certificado ISRG Root X1 (la raíz de Let's Encrypt, que usa el broker de ConnectMQ) y cópialo al destino, por ejemplo en una carpeta Certificates dentro del directorio de arranque o de configuración de TwinCAT.
  2. Amplía la configuración inicial:
fbMqttClient.sHostName     := 'YOUR_BROKER_HOST';
fbMqttClient.nHostPort     := 8883;
fbMqttClient.sClientId     := 'YOUR_CLIENT_ID';
fbMqttClient.sUserName     := 'YOUR_USERNAME';
fbMqttClient.sUserPassword := 'YOUR_PASSWORD';
fbMqttClient.stTLS.sCA     := 'C:\TwinCAT\3.1\Config\Certificates\isrgrootx1.pem';
  1. Configura un Last Will mediante la estructura de will del cliente, por ejemplo un mensaje retained offline en plant1/stamping/cell4/press1/status, y publica un online retained en el mismo topic tras conectar. Así los consumidores podrán distinguir una máquina parada de una conexión perdida.
  2. Elimina el prefijo de demostración y usa la jerarquía de topics ISA-95 de tu planta.

Mantén las credenciales fuera del control de versiones: cárgalas desde un archivo en el destino o desde una variable persistente fijada durante la puesta en marcha, en lugar de escribirlas directamente en un proyecto que se comparte.

Diseñar topics para una flota de máquinas

Los fabricantes de máquinas suelen entregar el mismo proyecto TwinCAT a decenas de clientes, por ejemplo a plantas automotrices en el Bajío mexicano o en el País Vasco, así que los topics escritos a fuego se convierten enseguida en un problema de mantenimiento. Algunos hábitos ayudan:

  • Convierte el prefijo del topic en un parámetro. Guarda los nombres de empresa, planta, área, línea y máquina en variables persistentes fijadas en la puesta en marcha y construye el string del topic al arrancar.
  • Separa datos, estado y eventos. Usa .../telemetry para valores periódicos, .../status para la información retained de conexión y estado, y .../events para alarmas o finalizaciones de lote. Los consumidores se suscriben solo a lo que necesitan.
  • Versiona tu payload. Una clave "schema": 1 cuesta unos pocos bytes y permite que el código posterior gestione una actualización de firmware que añada o renombre campos.
  • Mantén los payloads pequeños. Publica los valores que realmente se usan. Los volcados de diagnóstico pueden ir en un topic aparte, bajo demanda.

Estas convenciones también facilitan explorar los datos: un broker que reconoce rutas de estilo ISA-95 puede presentar todas las máquinas en un árbol de plantas y líneas sin configuración adicional, y un gemelo digital 3D de la línea puede suscribirse a la misma jerarquía para mostrar cada prensa en su posición real.

Lista de comprobación para la puesta en marcha

Comprobación Por qué importa
Reloj del destino sincronizado por NTP TLS rechaza los certificados cuando el reloj está muy desfasado
DNS configurado en el IPC El hostname del broker debe resolverse
Client ID único por máquina Los duplicados se desconectan entre sí una y otra vez
Buffer del payload dimensionado para el JSON más grande Evita el truncado silencioso
Latido más report by exception Poco tráfico con prueba de vida
Topic de estado retained con Last Will Detección fiable de conexión y desconexión
Licencia de TF6701 activada La licencia de prueba caduca a los 7 días

Solución de problemas

  • hrErrorCode muestra un rechazo de conexión. Credenciales o client ID incorrectos; en brokers que vinculan los client ID a las credenciales, ambos deben coincidir con lo emitido.
  • Errores TLS tras un reinicio. La ruta del certificado en el destino es incorrecta, o el archivo de la CA no se copió con el proyecto de arranque.
  • No se publica nada a pesar de bConnected. bPublish nunca es verdadero, o se llama a Publish antes de construir el payload.
  • Los mensajes llegan a ráfagas. bQueue := TRUE con una frecuencia de llamada a Execute lenta; llama a Execute en cada ciclo desde una tarea rápida.

Dónde encaja esto

Publicar desde el IPC es una de varias arquitecturas para sacar datos de máquina; compárala con los diseños basados en gateway y en SCADA de conectividad de PLC a la nube. Si trabajas con controladores de distintas marcas, el tutorial CODESYS MQTT usa un patrón execute-and-publish muy parecido. Y cuando muchas máquinas publican en una misma jerarquía, la guía de IoT industrial con MQTT explica cómo modelarla como un Unified Namespace que cualquier aplicación puede consumir a través del broker MQTT.

Conecta tus máquinas Beckhoff a ConnectMQ

Ejecutar tu propio broker junto a cada máquina implica certificados, actualizaciones y monitorización en cada planta. Un broker MQTT gestionado elimina ese trabajo. Crea un broker Serverless gratuito en app.connectmq.com, sin tarjeta de crédito, y observa cómo llegan tus datos de TwinCAT al explorador de topics en vivo en cuestión de minutos.

Preguntas frecuentes

¿Qué licencia de TwinCAT necesito para MQTT?

El enfoque con librería de PLC requiere TF6701 TwinCAT 3 IoT Communication. La alternativa basada en configuración es TF6720 IoT Data Agent. Ambas ofrecen una licencia de prueba de 7 días.

¿Admite TwinCAT MQTT el uso de TLS?

Sí. Indica la ruta del certificado de la CA en la estructura TLS del cliente, conéctate al puerto 8883 y añade las credenciales. También se admiten certificados de cliente si tu broker los exige.

¿Puede TwinCAT suscribirse a topics MQTT?

Sí. FB_IotMqttClient admite suscripciones con una cola de mensajes que lees en el PLC. Valida cada valor recibido antes de que afecte a la lógica de control.

¿Por qué mi payload JSON se corta a los 255 caracteres?

GetDocument devuelve un string de longitud estándar. Usa CopyDocument hacia un buffer más grande, como se muestra arriba.

Artículos relacionados

Todos los artículos →

Tu broker MQTT privado, a unos pocos clics

Crea una cuenta, obtén las credenciales de tu broker y conecta tu primer dispositivo, sin servidores que instalar, parchear ni escalar.