今回の記事ではOmronのSysmac Libraryを使用しMQTT通信を行います。Broker側ではPLCNEXTとPodmanのContainer技術の組み合わせですが、普通のRapsberry Piでも問題ありません。よろしくお願いします。

Reference Link
Build a Broker
MQTT Program With Other CPU
TLS
MQTT Library?
MQTT Communications Libraryは、MQTT BrokerにPub/Subタイプのメッセージ交換に使用されるソフトウェア機能を使用できるライブラリです。
このライブラリは、バージョン3.1.1のMQTTプロトコルをサポートしています。
MQTT Communications Library使用すると、このような機能を実装できます:
- MQTT Brokerと接続
- Subscriberとして、ネットワークにあるPublisherから情報を受信する。
- Publisherとして、ネットワークにあるSubscriberに情報を送信する。
- MQTT Brokerとの通信と応答時間の確認

Install
Omron HPからMQTT Communication libraryをDownloadし、EXEを起動します。
https://www.fa.omron.co.jp/product/tool/sysmac-library/

言語を選び>OKで続きます。

Next>で進みます。

ライセンス同意し、Next>で進みます。

Next>で進みます。

Install!

しばらく待ちます…

Done!

Method
次は今回記事では使用されるFunction BlockとDUTとを紹介します。
DUT
sConnectionSettings
Name | Data Type | Description |
IpAdr | STRING[201] | BrokerのIPアドレス |
PortNo | UINT | BorkerのPort番号 |
TLSUse | BOOL | 1=TLS使用 |
TLSessionName | STRING[17] | TLS session 名 |
UserName | STRING[256] | LoginするときのUsername設定 |
Password | STRING[256] | LoginするときのPassword設定 |
WillCfg | sWillCfg | Will パラメータ設定 |
CleanSession | BOOL | 1=Sessionクリア |
sWillCfg
Name | Data Type | Description |
WillTopic | STRING[512] | Will Topic名 |
WillMsg | STRING[256] | Will Message |
WillRetain | BOOL | 1=MessageがRetainする |
WillQoS | BYTE | QoS レベル(0,1,2) |
WillFlag | BOOL | 1=Will機能有効 |
MQTTClient
こちらのFunction BlockはNX CPUとMQTT BrokerをConnectionを作成します。MQTTClientが実行成功し、INOUT パラメータであるClientReferenceを MQTTPubAryByte, MQTTSubAryByte, MQTTSubString, MQTTPing のFunction Blockを渡していくのイメージです。

Input Variables
Variable | Data type | Description |
Enable | BOOL | True=接続開始 |
ClientID | STRING[256] | MQTT Brokerに識別させるうための識別子 |
ConnectionSettings | sConnectionSettings | MQTT Brokerに接続するパラメータ |
KeepAlive | UINT | KeepAlive 時間設定0-65535 |
Timeout | UINT | Timeout設定(0-20s) |
DiscardMsgTime | UINT | 受信したメッセージが破棄されるまでの待ち時間の最大値を指定します。 |
Output Variables
Variable | Data type | Description |
Connected | BOOL | True=Brokerと接続中 |
Busy | BOOL | True=Function Block 実行中 |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
DiscardMsgNum | UDINT | This is the number of discarded message receptions |
SessionPresent | BOOL | True=Sessionがある |
VAR_IN_OUT
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
MQTTPubAryByte
このFunction BlockはBYTE 配列で指定されたメッセージの PUBLISH メッセージをMQTT ブローカ、に送信する。

VAR_IN
Name | Type | Description |
Execute | BOOL | 立ち上げでFunction Block実行 |
MsgSize | UINT | パラメータPubMsgのPublishメッセージのサイズ(Byte) |
PubSettings | sPubFlags | PublishするときのRetainやQoS設定 |
Topic | STRING[512] | PublishするTopic名 |
TimeOut | UINT | Timeout設定 |
VAR_OUT
Name | Type | Description |
Done | BOOL | True=実行成功 |
Busy | BOOL | True=Function Block 実行中 |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
VAR_IN_OUT
Name | Type | Description |
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
PubMsg | ARRAY[*] OF BYTE | Brokerに送信するMessage |
MsgSize | UINT | パラメータPubMsgのPublishメッセージのサイズ(Byte) |
PacketID | UINT | 実行開始時にのときに0以外の数値が指定された場合、指定されたパケットIDの再送メッセージとして送信されます。 |
MsgType | USINT | QoSレベルが1または2で、なおかつPacketIDが0でない場合にそのパラメータにアクセスされます。0=PUBLISH、1= PUBREL |
MQTTPubString
このFunction Blockは文字列で指定されたメッセージの PUBLISH メッセージをMQTT ブローカ、に送信する。

VAR_IN
Name | Type | Description |
Execute | BOOL | 立ち上げでFunction Block実行 |
PubSettings | sPubFlags | PublishするときのRetainやQoS設定 |
Topic | STRING[512] | PublishするTopic名 |
TimeOut | UINT | Timeout設定 |
VAR_OUT
Name | Type | Description |
Done | BOOL | True=実行成功 |
Busy | BOOL | True=Function Block 実行中 |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
VAR_IN_OUT
Name | Type | Description |
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
PubMsg | ARRAY[*] OF BYTE | Brokerに送信するMessage |
MsgSize | UINT | パラメータPubMsgのPublishメッセージのサイズ(Byte) |
PacketID | UINT | 実行開始時にのときに0以外の数値が指定された場合、指定されたパケットIDの再送メッセージとして送信されます。 |
MsgType | USINT | QoSレベルが1または2で、なおかつPacketIDが0でない場合にそのパラメータにアクセスされます。0=PUBLISH、1= PUBREL |
MQTTSubAryByte
こちらのFunction Blockは入力パラメータEnable=TrueでBrokerにTopicをByte配列としてSubscribeを開始します。

VAR_IN
Name | Type | Description |
Enable | BOOL | 1=TopicにSubscribeする |
Topic | STRING[512] | SubscribeするTopic名 |
SubQoS | BYTE | QoSを設定します。(0,1,2) |
TimeOut | UINT | Timeout設定 |
VAR_OUT
Name | Type | Description |
Subscribed | BOOL | 1=TopicにSubscribeした |
Status | SINT | Scbscribeの状態です。0:実行停止中1:Scbscribeを要求中2:Scbscribe中3:Scbscribeをストップする4:Brokerの再接続待ち |
Received | BOOL | 1=Messageが受信した |
MsgSize | UINT | 受信したデータサイズ(Byte) |
RcvTopic | STRING[512] | 受信したTopic |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
VAR_IN_OUT
Name | Type | Description |
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
RcvMsg | ARRAY[*] OF BYTE | 受信したデータを格納先 |
MQTTSubString
こちらのFunction Blockは入力パラメータEnable=TrueでBrokerにTopicを文字列としてSubscribeを開始します。

VAR_IN
Name | Type | Description |
Enable | BOOL | 1=TopicにSubscribeする |
Topic | STRING[512] | SubscribeするTopic名 |
SubQoS | BYTE | QoSを設定します。(0,1,2) |
TimeOut | UINT | Timeout設定 |
VAR_OUT
Name | Type | Description |
Subscribed | BOOL | 1=TopicにSubscribeした |
Status | SINT | Scbscribeの状態です。0:実行停止中1:Scbscribeを要求中2:Scbscribe中3:Scbscribeをストップする4:Brokerの再接続待ち |
Received | BOOL | 1=Messageが受信した |
RcvTopic | STRING[512] | 受信したTopic |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
VAR_IN_OUT
Name | Type | Description |
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
RcvMsg | ARRAY[*] OF BYTE | 受信したデータを格納先 |
MQTTPing
こちらのFunction BlockはMQTT BrokerにPingメッセージを送信し返答時間を測定することができます。

VAR_IN
Name | Type | Description |
Enable | BOOL | 1=TopicにSubscribeする |
TimeOut | UINT | Timeout設定 |
VAR_OUT
Name | Type | Description |
Done | BOOL | 1=FB実行成功 |
Busy | BOOL | 1=FB実行中 |
ElapseTime | UINT | PINGREQパケットを送信してからPINGRESPパケットを受信するまでの時間 |
Error | BOOL | True=Function Blockエラー発生 |
ErrorID | WORD | 0=Function Block正常終了、ほかはFunction Blockエラーあり |
ErrorIDEx | DWORD | エラーコードの拡張 |
VAR_IN_OUT
Name | Type | Description |
ClientReference | sClientReference | MQTT FB間で共用するデータです。 |
Implementation

Import the library
Sysmac Studioを起動し、ライブラリをプロジェクトにImportします。
Project>Library>Show Referencesをします。

+ボタンをクリックします。

先程Downloadしたライブラリを選び、Openします。

無視でOKです。

Done!MQTT LibraryがImportされました。

Configuration
Controller Setup>Built-in EtherNet/IP Settingsを開き、TCP/IP SettingのTabからMQTT Brokerと接続してるPortのIPを設定しましょう。

Program
DUT
DUT_MQTT_Basic

DUT_MQTT_Client

DUT_MQTT_Sub

DUT_MQTT_Ping

DUT_MQTT_Pub

VAR
Variables Name | Type | Descritpion |
bDummy | BOOL | |
bAlwaysON | BOOL | |
pubFlags | sPubFlags | BrokerにMessageをPublishする設定 |
rcvMsg | ARRAY [0..999] OF BYTE | Brokerに受信したByte配列の格納先 |
RcvTopic | STRING[512] | Brokerに受信したのTopic名格納先 |
SubMessage | STRING[1986] | Brokerに受信した文字列データ格納先 |
MyString | STRING[255] | |
pubMsg | ARRAY[0..999] OF BYTE | BrokerにPublishするByte配列データ |
StringToAry_DataConverted | UINTを | データ変換Buffer |
MQTTPubString | MQTTPubString | Brokerに文字列データをPublishするのFB Instance |
PubMessage | STRING[1986] | BrokerにPublishする文字列データの格納先 |
MQTTClient | MQTTClient | Brokerと接続するFB Instance |
bMQTTConnect | BOOL | 1=MQTT Brokerと接続 |
Client | DUT_MQTT_Client | FBのパラメータ変数 |
MQTTSubAryByte | MQTTSubAryByte | BrokerにMessageをSubscribe FB Instance |
SubAryByte | DUT_MQTT_Sub | FBのパラメータ変数 |
MQTTPing | MQTTPing | BrokerにPingする FB Instance |
MQTTSubString | MQTTSubString | BrokerにMessageをSubscribe FB Instance |
Ping | DUT_MQTT_Ping | FBのパラメータ変数 |
SubString | DUT_MQTT_Sub | FBのパラメータ変数 |
PubAryByte | DUT_MQTT_Pub | FBのパラメータ変数 |
MQTTPubAryByte | MQTTPubAryByte | BrokerにPublishするByte配列データの格納先 |
pubString | DUT_MQTT_Pub | FBのパラメータ変数 |
Result_SubAryByte | DINT | |
Result_SubString | DINT |
Rung0
Rung Commentをまとめます。

Rung1
MQTT Brokerと接続するパラメータを設定します。

Rung2
MQTT Brokerと接続するTLS パラメータを設定します。

Rung3
WillCfg設定を行います。

Rung4
CleanSessionオプションを有効します。

Rung5
Omron NX CPUがメッセージ PublishするときのQosとRetain設定です。

Rung6
OMRON NX CPUのEthernet Portが正常、なおかつMQTT Functionが実行してない・エラーが発生してないときをbMQTTConnectをTrueします。そのbMQTTConnectはMQTTClientのFunctionのパラメータです。

Rung7
Dummy回路でRung Commentをまとめます。

Rung8
MQTTClient Function Blockを呼び出し、MQTT Brokerと接続します。

Rung9
MQTT ClientがBrokerと接続OKなおかつエラーが発生しないなら自動的にBrokerにTopicをSubscribeします。

Rung10
MQTTSubAryByte Function Blockを呼び出しBrokerからTopci PLCNEXT/Node/Data/Node1をSubscribeします。

Rung11
新しいMessageを受信した場合、データをAryToString関数を使ってByte配列を文字列に変換し、そして文字列をDINTに再変換します。

Rung12
MQTTPing Function Blockを使用しNX CPUとBrokerの通信状態を確認します。

Rung13
MQTTSubString Function Blockを呼び出しBrokerからTopci PLCNEXT/Node/Data/Node1をSubscribeします。

Rung14
新しいMessageを受信した場合、データをAryToString関数を使って文字列をDINTに変換します。

Rung15
NX CPUがBrokerと接続してるときPublishするMessage値を書き込みます。

Rung16
MQTTPubAryByte Function Blockを呼び出しMessageをBrokerにPublishします。

Rung17
MessageをPublishしたらトリガーデバイスをリセットします。

Rung18
NX CPUがBrokerと接続してるときPublishするMessage値を書き込みます。

Rung19
MQTTPubString Function Blockを呼び出しMessageをBrokerにPublishします。

Rung20
MessageをPublishしたらトリガーデバイスをリセットします。

Result
Done!Client.ConnectedがTureになり、NX CPUがBrokerと接続しました。

Subscribe
Omron NX CPUはMQTT Brokerに”PLCNEXT/Node/Data/Node1”をSubscribeしました。

ではPLCNEXT側でデータをPublishしてみますね。

SubAryByte.MsgSize=5、つまり5Bytesのデータを受信しました。
そしてRevTopicから受信したTopicを確認できます。

データ12345を受信しました。

MQTTSubString Function BlockでRevTopicから受信したTopicを確認できます。

同じく、データ12345を受信しました。

Publish
今度MQTTPubAryBytePublishのExecute Flagをトリガーし、Omron NX CPUからデータをPLCNEXTのBrokerに送信します。

Done!PLC NEXT Brokerを7891受信しました。

次はMQTTPubStringのExecuteをトリガーし文字列データをPLC NEXT Brokerにデータを送信します。

Done!PLC NEXT Brokerを8922番号受信しました。
