O suporte a Beckhoff TwinCAT MQTT permite que um PC industrial Beckhoff publique dados da máquina diretamente do runtime do CLP, sem um gateway separado no painel. Neste tutorial você vai usar as funções IoT do TwinCAT 3 para se conectar a um broker MQTT, serializar um tipo de dado estruturado em JSON, publicá-lo na mudança e por temporizador e, por fim, proteger a conexão com TLS e credenciais. O mesmo padrão escala de uma única bancada de testes a uma frota de máquinas.
Opções de MQTT no TwinCAT comparadas
A Beckhoff oferece mais de um caminho para o MQTT, e escolher o certo desde o início evita retrabalho.
| Opção | O que é | Quem configura | Ideal para |
|---|---|---|---|
| TF6701 IoT Communication | Biblioteca de CLP (Tc3_IotBase) com um bloco de função cliente MQTT | Programador de CLP, em texto estruturado | Controle total sobre topics, payloads e temporização |
| TF6720 IoT Data Agent | Gateway baseado em configuração que mapeia símbolos ADS para MQTT | Interface gráfica do configurador, sem código no CLP | Publicar símbolos existentes sem alterar o programa do CLP |
| Gateway ADS externo | Seu próprio serviço que lê símbolos via ADS e publica MQTT | Equipe de software | Pipelines personalizados, muitos controladores, formatos não padrão |
Este tutorial usa o TF6701 porque é a escolha mais comum de fabricantes de máquinas que querem que o comportamento MQTT faça parte do projeto de CLP versionado. Tanto o TF6701 quanto o TF6720 são funções TwinCAT licenciadas; uma licença de teste de 7 dias basta para acompanhar.
Pré-requisitos
- TwinCAT 3.1 XAE (Visual Studio ou TwinCAT XAE Shell) e um alvo: um IPC Beckhoff ou o seu PC de engenharia em modo run para testes.
- A função TF6701 instalada no alvo e uma licença de teste ou completa ativada.
- Acesso de rede de saída do alvo ao broker na porta TCP 1883 para testes e 8883 para TLS.
- Bibliotecas de CLP Tc3_IotBase e Tc3_JsonXml adicionadas às referências do projeto.
- Clientes mosquitto em um PC para verificação.
Passo 1: defina um tipo de dado estruturado
Publicar uma estrutura em vez de variáveis soltas mantém os valores relacionados juntos e os timestamps consistentes. Adicione um DUT:
TYPE ST_PressData :
STRUCT
rForce_kN : REAL;
rTemperature_C : REAL;
nCycleCount : UDINT;
bRunning : BOOL;
sState : STRING(20);
END_STRUCT
END_TYPE
Passo 2: conecte com FB_IotMqttClient
O FB_IotMqttClient da Tc3_IotBase é configurado por propriedades e acionado chamando seu método Execute a cada ciclo. Chame-o a partir de uma task com ciclo de 10 ms ou mais rápido; o cliente cuida da própria comunicação em segundo plano, mas só avança quando Execute é chamado.
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
// --- Configuração única do cliente ---
IF bSetParameter THEN
bSetParameter := FALSE;
fbMqttClient.sHostName := 'broker.connectmq.com';
fbMqttClient.nHostPort := 1883;
fbMqttClient.sClientId := 'twincat-demo-t3w9p1'; // não vazio e único
fbMqttClient.nKeepAlive := 30;
END_IF
// --- Mantém a conexão ativa a cada ciclo ---
fbMqttClient.Execute(bConnect);
// --- Decide quando publicar: na mudança ou a cada 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;
// --- Serializa e publica ---
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
Algumas observações sobre as escolhas acima:
CopyDocumentem vez deGetDocument.GetDocumentretorna uma string padrão de 255 caracteres, que trunca silenciosamente payloads maiores. Copiar para um buffer dimensionado evita isso.- Report by exception. A banda morta de força e as comparações de estado publicam mudanças reais imediatamente, enquanto o heartbeat de 10 segundos prova que a máquina está viva mesmo quando nada muda.
- Tratamento de erros. Acompanhe
fbMqttClient.hrErrorCodeefbMqttClient.eConnectionStatena visão online durante o comissionamento. A maioria das falhas aparece primeiro ali.
Para estruturas maiores, a Tc3_JsonXml também oferece uma função auxiliar que serializa um tipo de dado inteiro, incluindo atributos como unidades, em uma única chamada. A saída SAX escrita à mão, como acima, dá controle exato sobre os nomes das chaves, o que importa quando outras equipes consomem os dados.
Passo 3: verifique no servidor MQTT público
Ative a configuração, inicie o CLP e assine a partir de um PC:
mosquitto_sub -h broker.connectmq.com -p 1883 -i twincat-watch-t3w9p1 \
-t 'connectmq/demo/t3w9p1/#' -v
Saída esperada:
connectmq/demo/t3w9p1/plant1/stamping/cell4/press1/telemetry {"force_kN":412.5,"temperature_C":38.2,"cycle_count":10233,"running":true,"state":"AUTO"}
Force um valor na visão online e a mudança aparece instantaneamente. O servidor MQTT público (gratuito) em broker.connectmq.com, anônimo e feito para testes e protótipos, é perfeito para esse tipo de colocação em operação, mas é público, então use um prefixo de topic aleatório e nada confidencial.
Passo 4: proteja a conexão Beckhoff TwinCAT MQTT
Máquinas em produção nunca devem publicar via TCP sem criptografia na internet. Crie um broker privado no portal do ConnectMQ, anote o usuário, a senha e o client ID gerados e então:
- Baixe o certificado ISRG Root X1 (a raiz do Let's Encrypt, usado pelo broker do ConnectMQ) e copie-o para o alvo, por exemplo para uma pasta
Certificatesno diretório de boot ou de configuração do TwinCAT. - Amplie a configuração única:
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';
- Configure um Last Will pela estrutura de will do cliente, por exemplo uma mensagem retida
offlineemplant1/stamping/cell4/press1/status, e publique umonlineretido no mesmo topic depois de conectar. Assim os consumidores conseguem distinguir uma máquina parada de uma conexão perdida. - Remova o prefixo de demonstração e use a hierarquia de topics ISA-95 da sua planta.
Mantenha as credenciais fora do controle de versão: carregue-as de um arquivo no alvo ou de uma variável persistente definida durante o comissionamento, em vez de deixá-las fixas em um projeto que é compartilhado.
Projetando topics para uma frota de máquinas
Fabricantes de máquinas, como um fabricante de prensas em Joinville que atende clientes em todo o Brasil, muitas vezes entregam o mesmo projeto TwinCAT a dezenas de clientes, então topics fixos no código viram rapidamente um problema de manutenção. Alguns hábitos ajudam:
- Transforme o prefixo do topic em parâmetro. Armazene os nomes de empresa, site, área, linha e máquina em variáveis persistentes definidas no comissionamento e monte a string do topic na inicialização.
- Separe dados, status e eventos. Use
.../telemetrypara valores periódicos,.../statuspara informações retidas de online e estado e.../eventspara alarmes ou conclusões de lotes. Os consumidores assinam apenas o que precisam. - Versione o payload. Uma chave
"schema": 1custa poucos bytes e permite que o código consumidor lide com uma atualização de firmware que adiciona ou renomeia campos. - Mantenha os payloads pequenos. Publique os valores que as pessoas realmente usam. Dumps de diagnóstico podem ir para um topic separado, sob demanda.
Essas convenções também tornam os dados fáceis de navegar: um broker que reconhece caminhos no estilo ISA-95 pode apresentar cada máquina em uma árvore de site e linha sem configuração extra, e a mesma árvore serve de base para um gêmeo digital da linha.
Checklist de comissionamento
| Verificação | Por que importa |
|---|---|
| Relógio do alvo sincronizado via NTP | O TLS rejeita certificados quando o relógio está muito errado |
| DNS configurado no IPC | O hostname do broker precisa ser resolvido |
| Client ID único por máquina | Duplicados desconectam um ao outro repetidamente |
| Buffer de payload dimensionado para o maior JSON | Evita truncamento silencioso |
| Heartbeat mais report by exception | Pouco tráfego com prova de vida |
| Topic de status retido com Last Will | Detecção confiável de online e offline |
| Licença do TF6701 ativada | A licença de teste expira após 7 dias |
Solução de problemas
hrErrorCodemostra recusa de conexão. Credenciais ou client ID errados; em brokers que vinculam client IDs a credenciais, ambos precisam corresponder ao que foi emitido.- Erros de TLS após reinicialização. O caminho do certificado está errado no alvo, ou o arquivo da CA não foi copiado junto com o projeto de boot.
- Nada é publicado apesar de
bConnected.bPublishnunca fica verdadeiro, ouPublishé chamado antes de o payload ser montado. - As mensagens chegam em rajadas.
bQueue := TRUEcom uma taxa de chamada deExecutelenta; chameExecutea cada ciclo a partir de uma task rápida.
Onde isso se encaixa
Publicar a partir do IPC é uma das várias arquiteturas para extrair dados de máquinas; compare-a com as arquiteturas baseadas em gateway e em SCADA em conectividade de CLP para a nuvem. Se você trabalha com controladores de marcas variadas, o tutorial CODESYS MQTT usa um padrão de executar e publicar muito parecido. E quando muitas máquinas publicam em uma única hierarquia, o guia de IoT industrial com MQTT explica como modelá-la como um Unified Namespace que qualquer aplicação pode consumir pelo broker MQTT.
Conecte suas máquinas Beckhoff ao ConnectMQ
Rodar seu próprio broker ao lado de cada máquina significa certificados, atualizações e monitoramento em cada site. Um broker MQTT gerenciado elimina esse trabalho. Crie um broker Serverless gratuito em app.connectmq.com, sem cartão de crédito, e veja seus dados TwinCAT chegarem ao explorador de topics ao vivo em minutos.
Perguntas frequentes
Qual licença do TwinCAT preciso para MQTT?
A abordagem com biblioteca de CLP exige o TF6701 TwinCAT 3 IoT Communication. A alternativa baseada em configuração é o TF6720 IoT Data Agent. Ambos oferecem licença de teste de 7 dias.
O TwinCAT MQTT suporta TLS?
Sim. Defina o caminho do certificado da CA na estrutura TLS do cliente, conecte-se à porta 8883 e adicione as credenciais. Certificados de cliente também são suportados, caso o seu broker os exija.
O TwinCAT pode assinar topics MQTT?
Sim. O FB_IotMqttClient suporta assinaturas com uma fila de mensagens que você lê no CLP. Valide cada valor recebido antes que ele chegue à lógica de controle.
Por que meu payload JSON é cortado em 255 caracteres?
GetDocument retorna uma string de comprimento padrão. Use CopyDocument para um buffer maior, como mostrado acima.



