今回の記事ではBeckhoff TwinCAT 3 TF6701 IoT Communication を使用して、TwinCAT PLCからMQTTブローカへ接続し、PackML MQTT Simulator と通信する構成です。PackML MQTT Simulator、BrokerもContainer内で稼働しています。まず全体構成を確認し、その後TwinCAT TF6701を使ったMQTT接続、Subscribe、Publishの基本処理を見ていきましょう。
さ、FAを楽しもう!

前書き
いつも私の技術ブログとYouTubeチャンネルをご覧いただき、心より感謝申し上げます。また、いまFullさん(full@桜 八重 (@fulhause) / X)と共に毎週水曜日の夜にお届けしている「高橋クリス」ラジオ番組を運営しています。
技術は独り占めせず、届けるもの
私たちは工場の生産技術や制御に関する技術情報を、ブログや動画などで無料公開しています。「知識は誰でもアクセスできるべき」という信念のもと、現場で役立つ具体的なノウハウやトラブル事例などを発信してきました。すべて無料で続けているのは、「知らなかったせいで困る人」を少しでも減らしたいからです。
また、もしあなたの現場で…
- 「このPLCとデバイスの組み合わせ、ちゃんと動くのかな?」
- 「EtherCAT通信でうまくいかない部分を検証してほしい」
- 「新しいリモートI/Oを試したいけど社内に検証環境がない」
など、困っている構成や試してみたいアイデアがあれば、ぜひお知らせください。機器の貸出や構成の共有が可能であれば、検証し、記事や動画で発信します(ご希望に応じて匿名対応も可能です)。
支援のかたち
現在、私達の活動はほぼ無償で続けており、記事や動画の制作には、時間と検証環境の整備が必要です。この活動を継続的にコンテンツを提供するためには、皆様の温かいご支援が大変重要です。
メンバーシップ(ラジオの応援)
Fullさんとのラジオをより充実させるための支援プランです。
https://note.com/fulhause/membership/join
Amazonギフトリスト
コンテンツ制作に必要な機材・書籍をリストにしています。
https://www.amazon.co.jp/hz/wishlist/ls/H7W3RRD7C5QG?ref_=wl_share
Patreon(ブログ・動画活動への応援)
月額での小さなご支援が、記事の執筆・検証環境の充実につながります。
https://www.patreon.com/user?u=84249391
Paypal
小さな支援が大きな力になります。
https://paypal.me/soup01threes?country.x=JP&locale.x=ja_JP
知ってたら助かること、届けたいだけです
あなたの応援が、知識の共有をもっと自由で持続可能なものにしてくれます。これからもどうぞよろしくお願いします。
soup01threes*gmail.com
技術はひとりじゃもったいない。
PackML-MQTT-Simulator?
PackML MQTT Simulatorは、MQTT上に実装されたPackMLを使用してインターネット接続を行う仮想ラインである。Industry 4.0ソフトウェアソリューションの開発に使用することを目的としている。
このシミュレータは、以下に示すPackMLステートモデルを実装しており、環境変数によって定義されたMQTTトピックを介して通信する。
シミュレータは、基本的なMQTTトピック構造、またはSparkplug Bのいずれでも実行できる。

Getting Started
PackMLシミュレーションを開始して実行するには、稼働中でアクセス可能なMQTTサーバーが必要です。準備が整ったら、Dockerを使用してシミュレーションを実行し、環境変数でMQTT接続、サイト、エリア、およびラインを制御するのが最も簡単な方法です。
Docker
今回の記事はPackML-MQTT-SimulatorをDocker上で稼働させます。
Simulation
シミュレーションは、以下の内容で構成されています。
- 起動時、機械は自動的に「Clearing」状態に入り、その後「Stopped」状態へ移行します。
- PackMLのUnitModeコマンドおよびステータス
- PackMLステートモデルにおけるコマンドおよびステータス
-
機械速度
- 加速/減速
- 速度の揺らぎ
- 設定値の監視
- 現在速度のステータス
- 機械の設計速度制限の遵守
-
カウンタ
- Consumed:1点
- Produced:1点
- Defective:1点
- Execute状態からの自動的な機械の一時停止/一時停止解除
- Parameters、RemoteInterface、Productsの各コマンドを、対応するステータスタグへエコーバックします。
- このシミュレーションでは、確率に基づいたサイコロの目によって行動が決定されます。
PackML?
製造現場で設備に関わっていると、こんな場面によく出会います。
- 「この装置、いま本当に運転中なの?」
- 「停止中って言っているけど、異常停止なのか、通常停止なのか分からない」
- 「メーカーごとに状態表示の名前が違っていて、ライン全体で見たときに統一感がない」
- 「HMIではRUNなのに、PLC内部ではAUTO、上位システムではEXECUTEと呼んでいる」
でも、ライン全体や上位システムとつなげようとした瞬間に、言葉の粒度がバラバラで、その混乱を整理するための考え方が、PackMLです。
PackMLは Packaging Machine Language の略で、もともとは包装機械向けに整理された標準モデルです。ただし現在では、包装機械に限らず、一般的な製造装置や生産ラインの制御にも応用できます。
ひとことで言えば、PackMLは、装置の状態・操作コマンド・運転モードを共通化するための制御モデルです。

PackMLの背景にあるOMAC Packaging Working Group
PackMLを理解するうえで、まず押さえておきたいのが OMAC Packaging Working Group の存在です。
OMACは The Organization for Machine Automation and Control の略で、製造業における機械自動化や運用を支援するための組織です。
製造現場で使われる機械や制御システムについて、より扱いやすく、より統一された形にしていくことを目的としています。
その中で、包装機械分野を中心に活動しているのが OMAC Packaging Working Group です。
このワーキンググループは、大手の国際的なエンドユーザー企業の要望をきっかけに設立されました。
参加しているのは、主に以下のような立場の企業・技術者です。
- エンドユーザー
- 機械メーカー、OEM
- コントローラメーカー
つまり、設備を使う側、設備を作る側、制御機器を提供する側が同じテーブルにつき、製造機械の自動化に関する標準化を進めているわけです。
なぜ標準化が必要だったのか
製造装置の世界では、メーカーごと、設備ごと、用途ごとに制御構造や状態表現が異なることがよくあります。
ある装置では「RUN」、別の装置では「EXECUTE」、また別の装置では「AUTO」と呼ばれる。
停止や異常、復帰、段取り替えの考え方も、設備ごとに少しずつ違う。
この違いは、単体設備だけを見ていると大きな問題に見えないかもしれません。
しかし、複数の設備をラインとしてつなげたり、上位システムと連携したり、グローバルで同じ設備仕様を展開したりする場合には、大きな負担になります。
そこでOMAC Packaging Working Groupでは、製品・技術・アプリケーションごとに増え続けるバリエーションを減らし、製造機械の自動化をより標準的な形に整理することを目指しました。
OMACが目指した改善ポイント
OMAC Packaging Working Groupの目的は、単に「名前をそろえる」ことではありません。
標準化によって、次のような実務上の改善を狙っています。
改善項目 | 内容 |
|---|---|
納期短縮 | 標準構造を使うことで設計・製作の手戻りを減らす |
立上げ時間短縮 | 状態遷移や操作体系が共通化され、試運転しやすくなる |
機械サイズの最適化 | 装置構成やモジュール化を進めやすくする |
機械性能の向上 | 標準化された構造により制御品質を高めやすくする |
統合性の向上 | ライン・HMI・上位システムとの接続を容易にする |
段取り替え時間短縮 | フォーマット変更や品種切替を整理しやすくする |
柔軟性向上 | 異なる製品や工程に対応しやすくする |
モジュール性向上 | 装置や機能を部品のように組み合わせやすくする |
ダウンタイム削減 | 異常・停止・復帰の扱いを明確にし、停止時間を減らす |
OMAC PackML Guidelinesで定義されているもの
ガイドラインの主要部分では、OMACのモード管理、すなわちユニットモードマネージャおよびステートマシンについて説明している。
これについては、ISA技術報告書 TR88.00.02「Machine and Unit States」を参照のこと。
さらに、PackMLのパックタグも一覧化されている。
これらは、機械コントローラ間の機械横断的な結合、および上位のHMI、MES、またはエンタープライズシステムとの接続に使用される、標準化された変数構造、すなわちパックタグである。
パックタグには、以下の変数構造が存在する。
- コマンドタグ:機械を制御し、パラメータ設定するためのタグ
- ステータスタグ:機械の状態に関する情報を提供するためのタグ
- 管理タグ:機械効率、つまりOEEデータ、および機械診断に関する情報を提供するためのタグ
Production modeのステートマシンの例

Maintenance modeのステートマシンの例

ユニットモード
番号 | ユニットモード | 説明 |
|---|---|---|
0 | Invalid | 有効なユニットモードではない。 |
1 | Production | これは、通常の生産に使用されるモードを表す。機械は、オペレータによって直接入力される、または別の監視システムから発行されるコマンドに応じて、関連するロジックを実行する。 |
2 | Maintenance | このモードでは、適切に権限を与えられた担当者が、生産ライン内の他の機械から独立して、個別の機械を運転できる場合がある。このモードは通常、故障調査、機械試運転、または運転改善のテストに使用される。また、この機能が利用可能な場合には、機械速度の調整も可能にする。 |
3 | Manual | このモードでは、個別の機械モジュールを直接制御できる。この機能は、操作対象となる機構の機械的制約に応じて利用可能となる。この機能は、個別ドライブの試運転、同期ドライブの動作確認、パラメータ変更後のドライブ試験などに使用される場合がある。 |
04..31 | UserMode01…UserMode28 | ユーザー定義のユニットモードに対する要件は、機械およびアプリケーションによって異なる。代表的なユーザー定義ユニットモードの例として、洗浄モードがある。 |
状態
番号 | 状態 | 説明 |
|---|---|---|
0 | Undefined | 有効な状態ではない。 |
1 | Clearing | 状態タイプ:Acting Aborting中に発生し、Aborted状態になる前に存在している可能性のある異常をクリアするために、Clearコマンドによって開始される。 |
2 | Stopped | 状態タイプ:Wait Stopping状態が完了した後、機械は電源投入状態のまま静止している。すべての通信は、動作している場合には有効状態である。ResetコマンドによってStopped状態を抜け、Resetting状態へ移行する。 |
3 | Starting | 状態タイプ:Acting この機械は停止され、静止している。この状態は、Startコマンド、ローカルまたはリモート、の結果として入る。このコマンドの後、機械はExecute状態へ移行する。 |
4 | Idle | 状態タイプ:Wait この状態は、Resettingが完了したことを示す。機械は、その機械がIdle状態にある間に必要な操作を実行するコマンドを待つ。 |
5 | Suspended | 状態タイプ:Wait Suspendingによってこの状態に入ったとき、機械は製品を生産しない。この状態では、機械は実行中のままであるか、または生産手順を継続する。ただし通常の状態とは異なり、Suspended状態では、Unsuspending状態へ遷移する条件を通常はオペレータの介入なしに得ることができる。 |
6 | Execute | 状態タイプ:Acting 機械がExecute状態で材料を処理している状態。Execute状態内では、異なる機械モードごとに特定の活動が発生する。機械が「生産中」モードの場合、Executeは製品が生産されていることを示す。「クリーンアウト」モードの場合、Executeは機械の清掃動作を示す。 |
7 | Stopping | 状態タイプ:Acting この状態は、Stopコマンドに応答して入る。この状態にある間、機械は制御された停止に移行する制御停止シーケンスロジックを実行する。機械のStartingは、Resettingが行われるまで開始できない。 |
8 | Aborting | 状態タイプ:Acting Aborting状態は、Abortコマンド、または機械の異常発生に応答して、いつでも入ることができる。Abortingロジックにより、機械は迅速に停止する。 |
9 | Aborted | 状態タイプ:Wait 機械は、Abort条件に関連する状態情報を保持する。機械は、Clearコマンドを受け取るまでAborted状態を抜けることができず、その後、検出された異常を修正しリセットするために手動介入が必要となる。 |
10 | Holding | 状態タイプ:Acting この状態は、機械内部の条件によって発生し、通常は機械の停止または中断のためではない場合に使用する。機械が継続して生産できない内部条件により、Execute状態から離れる。通常、この状態は、機械の復旧条件が既知で、オペレータによって開始されるか自動的に開始され、容易に復旧できる場合に使用する。例としては、機械が定期的にグルーディスペンサやカートンマガジンを補充するためにオペレータを必要とする場合がある。機械設計により、機械が動作している間にそれが可能でない場合などである。これらの作業は通常の生産作業であるため、Stoppingシーケンスへ移行することは望ましくない。また、この機能は機械内部のものであり、「外部」ではないため、Suspending状態へ進むこともできない。Holding状態にある間、機械は制御された停止に移行し、その後Held状態へ遷移して完了する。制御された停止を再開するためには、関連するすべてのプロセス設定値と、Holdコマンド受信時の手順状態を保存する必要がある。また、Holding手順の実行中に機械を制御する処理を継続してはならない。 |
11 | Held | 状態タイプ:Wait Holdingでこの状態に入ったときに使用する。この状態では、機械は製品を生産しない。オペレータまたは外部コマンドによってUnholdコマンドが発行され、内部機械条件が満たされたときに、Unholding状態へ遷移する。 |
12 | Unholding | 状態タイプ:Acting Holdingからこの状態に入ったときに使用する。機械は通常、Unholdingへ入ると、材料を正常な状態へ戻すためのシーケンスを開始する。たとえば、許容可能なレベルへ戻すなどである。工程設定値や手順を安全な状態に戻すために、軽微な修理作業をオペレータが行う必要がある場合には、Unholdコマンドをオペレータが開始する。 |
13 | Suspending | 状態タイプ:Acting この状態は、機械が生産を継続できない外部条件、通常はユニット外部だが多くの場合は上流または下流工程の条件、によって発生する場合に使用する。機械は、外部プロセス条件によりExecute状態を離れる。通常、この状態は、ライン上の上流または下流条件によって発生する。また、ブロックまたはスターブなど、ライン条件を検出するセンサ、あるいは監視システムの外部コマンドに基づいて入ることもある。Suspending状態の間、機械は制御停止へ進み、その後Suspended状態へ遷移して完了する。Suspended状態後に正しく生産を再開するため、関連するすべてのプロセス設定値と、Suspendコマンド受信時の手順状態を保存する必要がある。また、Suspending手順の実行中に機械を制御する処理を継続してはならない。 |
14 | Unsuspending | 状態タイプ:Acting Suspendingからこの状態に入ったときに使用する。この状態は、プロセス条件が正常に戻った結果である。Unsuspendingでは、機械がExecute状態へ遷移できるようにするために必要な、あらゆる作業またはシーケンスを開始する。Suspended状態から機械を再始動するには、関連するすべてのプロセス設定値と、Suspendコマンド受信時の手順状態が保存されている必要がある。 |
15 | Resetting | 状態タイプ:Acting この状態は、Stopped状態またはComplete状態からResetコマンドを受けた結果として入る。異常および停止原因はリセットされる。Resettingでは通常、安全装置を通電し、機械のヘッド部分を既知の設定位置へ移動する。Aborted状態から来た場合は、Clearコマンドが使用されている必要がある。 |
16 | Completing | 状態タイプ:Acting この状態は、Execute状態からの自動応答である。通常運転は完了に至り、最終製品の処理が終了する。 |
17 | Complete | 状態タイプ:Wait 機械はCompleting状態を完了しており、Resetコマンドを待ってからResetting状態へ遷移する。 |
制御コマンド
番号 | 制御コマンド |
|---|---|
0 | Undefined |
1 | Reset |
2 | Start |
3 | Stop |
4 | Hold |
5 | Unhold |
6 | Suspend |
7 | Unsuspend |
8 | Abort |
9 | Clear |
10 | Complete |
TF6701
TwinCAT 3 IoT Communicationは、いわゆるMQ Telemetry Transport、すなわちMQTTプロトコルを介してデータを送受信するための基本機能を、PLCライブラリの形式で提供する。
コントローラから直接、パブリッシャ/サブスクライバ方式のMQTTメッセージを送受信できるようにすることで、この機能は多様なデバイス間の容易なデータ通信を可能にする。
通信経路を保護するためにTLSを使用でき、これによりデータパケットの暗号化と、メッセージブローカにおける認証が可能になる。
MQTTは、オープンで標準化された通信プロトコルであり、通信オーバーヘッドが小さいため、高速かつ効率的なデータ伝送用途において、ますます広く利用されるようになっている。
多くのITプロバイダ、とりわけクラウドコンピューティング分野のプロバイダは、このプロトコルを介して自社サービスへのアクセスを提供している。

今回記事で使用したの4026なので、TwinCAT Package ManagerからTF6701をDownloadしインストールしましょう。

Implementation
それでは実際にPackML-MQTT-Simulatorをインストールし、TF6701から接続してみましょう。
PackML-MQTT-Simulatorインストール
PackML-MQTT-Simulatorをインストールするには4つの手順に分かれています。
- Folder作成
- docker-compose.yml 作成
- mosquitto.conf 作成
- docker compose up で起動

Folder作成
作業場所とMosquitto設定置き場を作ります。
mkdir -p ~/packml-mqtt-local/mosquitto/config
|
|---|
これはフォルダを作るコマンドで、作っている構造はこれです。
/home/ユーザー名/
|
|---|
docker-compose.yml作成
Broker、PackML Simulator、確認用MQTT Clientのパッケージを作成します。
cat > docker-compose.yml <<‘YAML’
|
|---|
mosquitto.conf作成
次はBrokerの待ち受けポートや匿名接続設定を作ります。
cat > mosquitto/config/mosquitto.conf <<‘CONF’
|
|---|
docker compose up
最後は3つのコンテナを起動します。
docker compose up -d
|
|---|
実際はこの3つのコンテナが同時に起動されます。
packml-mqtt-broker |
|---|
MQTT Explorer検証
Beckhoff TwinCAT3 TF6701を使ってPackML-MQTT-Simulatorと接続テストする前に、まずMQTT Explorerから接続テストしましょう。

Beckhoff
最後はBechoff TwinCAT3側を構築します。

プログラム
このコードでは、TwinCAT 3 TF6701を使って、PLCからMQTTブローカへ接続し、MQTTメッセージのSubscribeとPublishを行っている。
1. MQTTクライアントの接続先を設定する
2. MQTTブローカへ接続する
3. 接続後、指定TopicをSubscribeする
4. 一定周期でテスト用メッセージをPublishする
5. 受信メッセージがあればキューから取り出す
6. 受信TopicとPayloadをPLC変数へ格納する
PROGRAM MAIN
|
|---|
//Init all Parameters
|
|---|
MQTTクライアントの初期設定
プログラムの最初では、bSetParameter を使ってMQTTクライアントの初期設定を一度だけ実行している。ここでは、MQTTブローカの接続先として 192.168.5.245 を指定している。
ポート番号は、一般的なMQTT通信で使用される 1883 を設定している。
IF bSetParameter THEN
|
|---|
MQTTブローカへの接続
bConnect が TRUE の間、MQTTクライアントはブローカへの接続を維持しようとする。
接続状態は fbMqttClient.bConnected で確認できる。
このプログラムでは、ブローカに接続できた後にSubscribe処理やPublish処理を実行するようになっている。
fbMqttClient.Execute(bConnect); |
|---|
TopicのSubscribe処理
MQTTブローカとの接続が確立すると、指定したTopicをSubscribeする。
IF fbMqttClient.bConnected THEN
|
|---|
Subscribe対象のTopicは、以下の変数で定義している。
sTopicSub : STRING(255) := ‘Factory/Packaging/Line1/Status/UnitModeCurrentStr’; |
|---|
MQTTメッセージのPublish処理
このプログラムでは、MQTT通信の動作確認用として、一定周期でメッセージをPublishしている。
IF fbTimer.Q THEN
|
|---|
送信先Topicは以下で定義している。
sTopicPub : STRING(255) := ‘Test1’; |
|---|
受信メッセージの取り出し
SubscribeしたTopicにメッセージが届くと、fbMessageQueue にメッセージが蓄積される。
IF fbMessageQueue.nQueuedMessages > 0 THEN
|
|---|
受信TopicとPayloadの取得
キューから取り出したメッセージに対して、まずTopic名を取得する。
fbMessage.GetTopic(
|
|---|
取得したTopic名は sTopicRcv に格納される。
次に、Payloadを取得する。
sPayloadRcv := ”;
|
|---|
結果
Done!下図のようにTwinCAT3からPackML-MQTT-Simulatorのメッセージを受け取りました。

また、TwinCAT3からもDataを送信できました。次回の記事では実際PackML-MQTT-Simulatorを使ってTwinCAT3とState Machineの動きを見ていきますので、お楽しみに!
