シーメンス#S71500 CPUとPLC-V8R/ETH-MP/BMをProfinet IRTで接続してみよう!

今回の記事ではPhoenix ContactのPLC-V8R/ETH-MP/BMとPhoenix ContactのPLCNEXT AXCF 2152とProfinetで接続する手順を説明します。こちらは今回記事で使用した機器です。

  • SIEMENSt社のS71500 CPU
  • SIEMENS TIA V20
  • Phoenix Contact社のPLC-V8R/ETH-MP/BM
  • Phoenix Contact社のPLC-RPT- 24DC/ 1AU/SEN
  • Phoenix Contact社のPLC-RPT- 24DC/21 – リレーモジュール

さ、FAを楽しもう!

Reference Link

PLCNEXT#AXCF 2152とPLC-V8R/ETH-MP/BMをProfinetで接続してみよう!
今回の記事ではPhoenix ContactのPLC-V8R/ETH-MP/BMとPhoenix ContactのPLCNEXT A...

前書き

いつも私の技術ブログと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

https://x.com/3threes2

技術はひとりじゃもったいない。

Implementation

それではプロジェクトを構築しましょう。

PLC-V8R/ETH-MP/BM側

最初はPhoenix ContactのPLC-V8R/ETH-MP/BM側から設置します。

モジュールのインストール

最初はモジュールのインストール方法を説明します。

モジュールにはPLC-V8R/ETH-MP/BMにインストールできる特定の形状があります。

下図のように簡単に挿入できます。

Done!

GSDMLファイルをダウンロード

下記のLinkからPLC-V8R/ETH-MP/BMのGSDML Fileをダウンロードします。

https://www.phoenixcontact.com/en-de/products/communication-module-plc-v8r-eth-mp-bm-1279135

シーメンス側

次はシーメンス側を構築します。

GSDML ファイルのインストール

TIAからGSDML Fileをインストールします。Options→Manage general station description filesをクリックします。

GSDML Fileのインストール画面が表示されます。

下図の赤枠ボタンをクリックします。

先ほどPhoenix ContactのHome PageからダウンロードしたGSDML Fileの選択します。

Done!次はインストールするGSDML FileにCheckboxを入れ、Installします。

少々お待ち下さい…

Done!

Profinet ネットワーク構築

次はTIAからProfinetネットワークを構築します。

PLC V8PLC-V8R/ETH-MP/BM追加

TIAをNetwork Viewに切り替え、Catalogから今回記事を使用するPLC V8PLC-V8R/ETH-MP/BMをNetwork ViewにDropします。

Done!

Profinet IO コントローラーに割り付け

先ほど追加したPLC V8PLC-V8R/ETH-MP/BMにある”Not Assigned”をクリックし→S71500のProfinetインタフェースに割り付けましょう。

Done!

IP設定

今度は下図に示してるICONをクリックします。

PLC V8PLC-V8R/ETH-MP/BMを実際のネットワークに合わせてIPを設定しましょう。

デバイス名設定

Profinetネットワークを使用するには各Profinetデバイスにもデバイス名を明確に設定する必要があります。PLC V8PLC-V8R/ETH-MP/BMを右クリック→Assign device nameします。

Update listをクリックします。

Done!今回記事で使用するPLC V8PLC-V8R/ETH-MP/BMを検索できました。次は”Assign name”をクリックします。

Done!これでPLC V8PLC-V8R/ETH-MP/BMのデバイス名割り付け完了です。

スロットの設定

PLC V8PLC-V8R/ETH-MP/BMのデバイスViewに切り替え、デバイスのスロット設定を変更します。

PropertiesにPLC V8PLC-V8R/ETH-MP/BMにインストールされている各スロットのタイプを設定できます。

各SLOTにDrop-listがあり、実機に合わせて設定しましょう。

Done!

絶対アドレス変更

次はPLC V8PLC-V8R/ETH-MP/BMデバイスの入出力絶対アドレスを設定します。

IRT

今回の記事ではPLC V8PLC-V8R/ETH-MP/BMとS71500の間はProfinet IRTで接続します。

Topology

TIAのTopology Viewに切り替えます。

PLC V8PLC-V8R/ETH-MP/BMとS71500間の物理接続に合わせて接続設定を行います。

今回の記事ではS71500のPort1 X2とPLC V8PLC-V8R/ETH-MP/BMのX1と接続します。

Done!

Sync

PLC V8PLC-V8R/ETH-MP/BMのProperties開き→Real time settings→Synchronizationを開きます。

RT ClassをIRTに設定します。

UDT

次はPLC V8PLC-V8R/ETH-MP/BMの構造体を作成します。

udt_PLC_V8R_ETH_MP_BM_IN

`udt_PLC_V8R_ETH_MP_BM_IN`は、PLC-V8R/ETH-MP/BMの入力データをまとめたユーザー定義型(UDT)です。

ベースモジュール(BM)のスロット入力データ`BM_Slot_IN`とステータス`BM_State`に加え、拡張モジュール(EM1〜EM3)それぞれのデジタル入力、スロット入力、アナログ入力、ステータスを一つの構造体に集約しています。

udt_PLC_V8R_ETH_MP_BM_OUT

`udt_PLC_V8R_ETH_MP_BM_OUT`は、ベースモジュールおよび拡張モジュールの出力データをまとめたUDTです。

ベースモジュール(BM)と拡張モジュール(EM1〜EM3)それぞれのスロット出力データを`Array[0..7] of DWord`型で保持する4つのメンバーで構成されており、システム全体の出力データを一元管理することができます。

udt_PLC_V8R_ETH_MP_BM_STATE0

`udt_PLC_V8R_ETH_MP_BM_STATE0`は、ベースモジュールの診断ステータスをまとめたUDTです。

電源電圧低下、SPIインタフェースエラー、各スロットの短絡・過負荷エラーなど、ベースモジュールの異常状態を示すBOOL型のフラグを15個持っており、すべてデフォルト値はfalseです。

udt_PLC_V8R_ETH_MP_BM_STATE1

udt_PLC_V8R_ETH_MP_BM_STATE1は、ベースモジュールのアナログ入力診断ステータスをまとめたUDTです。

スロット0〜7のアナログ入力モジュール未接続を示すxDiag_AnalogIN_SlotX_NotConnectedと、スロット0〜7のアナログ/温度モジュールの値異常を示すxDiag_AnalogTemp_SlotX_ValueErrorの計16個のBOOL型フラグで構成されています。

udt_PLC_V8R_ETH_MP_BM_STATE2

`udt_PLC_V8R_ETH_MP_BM_STATE2`は、拡張モジュール(EM1〜EM3)の診断ステータスをまとめたUDTです。

各拡張モジュールの重大エラー、一般エラー、デバイス未検出、通信エラー、ステーション設定エラーを示すフラグに加え、上位コントローラーとのアクティブ接続状態を示す`xDiag_ActiveConnectionToController`の計15個のBOOL型フラグで構成されています。

udt_PLC_V8R_ETH_MP_BM_STATE

`udt_PLC_V8R_ETH_MP_BM_STATE`は、先ほどのSTATE0〜STATE2をまとめた上位のUDTです。

`stSTATE0`、`stSTATE1`、`stSTATE2`の3つのメンバーで構成されており、ベースモジュールの基本診断、アナログ入力診断、拡張モジュール診断をひとつの構造体として管理することができます。

udt_PLC_V8R_ETH_MP_EM_STATE0

udt_PLC_V8R_ETH_MP_EM_STATE0は、拡張モジュールのSPIインターフェース診断と各スロットのエラー状態をまとめたUDTです。

SPIインターフェースの接続エラー、電圧低下、温度超過、スロットグループエラーを示す4つのフラグと、スロット0〜7の短絡・過負荷エラーを示すxDiag_EM_SlotX_Errorの計13個のBOOL型フラグで構成されています。

udt_PLC_V8R_ETH_MP_EM_STATE1

`udt_PLC_V8R_ETH_MP_EM_STATE1`は、拡張モジュールのアナログ入力診断をまとめたUDTです。

IN4〜IN7のアナログ値異常、ベースモジュールとの通信状態(通常・セーフステート・エラー)を示すフラグに加え、スロット0〜7のアナログ入力モジュール未接続と、スロット0〜7のアナログ/温度モジュールの値異常を示すフラグの計23個のBOOL型フラグで構成されています。

udt_PLC_V8R_ETH_MP_EM_STATE

`udt_PLC_V8R_ETH_MP_EM_STATE`は、拡張モジュールのSTATE0とSTATE1をまとめた上位のUDTです。

`stSTATE0`(SPIインターフェース・スロットエラー診断)と`stSTATE1`(アナログ入力診断)の2つのメンバーで構成されており、拡張モジュールの診断情報をひとつの構造体として管理することができます。

udt_PLC_V8R_ETH_MP_Configs

`udt_PLC_V8R_ETH_MP_Configs`は、モジュールの設定情報をまとめたシンプルなUDTです。

デジタルI/Oの使用を示す`DIO`とアナログI/Oの使用を示す`AIO`の2つのBOOL型フラグで構成されており、接続されているモジュールの種類を管理します。

udt_PLC_V8R_ETH_MP_EM

`udt_PLC_V8R_ETH_MP_EM`は、PLC-V8R/ETH-MP/BMシステム全体のデータを集約したメインのUDTです。

設定情報(`BMConfigsIN`/`EMConfigsIN`/`BMConfigsOUT`/`EMConfigsOUT`)、ベースモジュールのデジタル・アナログ入力(`BM_IN_DI`/`BM_IN_AI`)、拡張モジュールのデジタル・アナログ入力(`EM_IN_DIs`/`EM_IN_AIs`)、診断ステータス(`BM_Status`/`BM_IN_STATE`/`EM_IN_STATE`)、そしてベースモジュールと拡張モジュールのデジタル・アナログ出力(`BM_OUT_DO`/`BM_OUT_AO`/`EM_OUT_DOs`/`EM_OUT_AOs`)をひとつの構造体に集約しています。これにより、システム全体のI/OデータとステータスをUDT一つで管理することができます。

Tags

デフォルトタグテーブルで先ほど定義したUDTをPROFINETの入出力アドレスに割り付けます。

`_PLC_V8R_ETH_MP_BM_IN`を`udt_PLC_V8R_ETH_MP_BM_IN`型で`%I0.0`に、`_PLC_V8R_ETH_MP_BM_OUT`を`udt_PLC_V8R_ETH_MP_BM_OUT`型で`%Q0.0`にそれぞれ割り付けることで、PLC-V8R/ETH-MP/BMとのPROFINET通信データをUDT単位で管理することができます。

dbPLC_V8R_ETH_MP

`dbPLC_V8R_ETH_MP`は、先ほど定義した`udt_PLC_V8R_ETH_MP_EM`をベースにしたデータブロック(DB1)です。

設定情報、入力データ、診断ステータス、出力データがすべてこのデータブロックに集約されており、プログラム内から`dbPLC_V8R_ETH_MP.BM_IN_DI`のような形でアクセスすることができます。

FUNCTION

次は今回記事で作成したFUNCTIONを紹介します。

fc_PLC_V8R_ETH_MP_AIChannelConvert

このファンクションfc_PLC_V8R_ETH_MP_AIChannelConvertは、アナログ入力チャンネルのデータ変換を行います。

まずio1(DWord配列)とio2(Word配列)の配列境界が一致しているかを確認します。一致しない場合はエラーコード16#8000を返します。一致している場合はxEnableをTrueにして処理を続行します。

xEnableがTrueかつioConfigsのAIOフラグがTrueの場合、io1の各要素をDWORD_TO_WORDで変換しio2に格納します。処理が正常に完了した場合は16#0を返します。

FUNCTION “fc_PLC_V8R_ETH_MP_AIChannelConvert” : Word

VAR_IN_OUT
io1 : Array[*] OF DWord;
io2 : Array[*] OF Word;
ioConfigs : Array[0..7] OF “udt_PLC_V8R_ETH_MP_Configs”;
END_VAR

VAR_TEMP
i : DInt;
xEnable : Bool;
END_VAR

VAR CONSTANT

END_VAR



#fc_PLC_V8R_ETH_MP_AIChannelConvert := 16#0;
#xEnable := False;

IF LOWER_BOUND(ARR := #io1, DIM := 1) <> LOWER_BOUND(ARR := #io2, DIM := 1)
OR UPPER_BOUND(ARR := #io1, DIM := 1) <> UPPER_BOUND(ARR := #io2, DIM := 1)
THEN
#fc_PLC_V8R_ETH_MP_AIChannelConvert := 16#8000;
ELSE
#xEnable := True;
END_IF;

IF #xEnable THEN
IF #ioConfigs[#i].AIO THEN
FOR #i := LOWER_BOUND(ARR := #io1, DIM := 1) TO UPPER_BOUND(ARR := #io1, DIM := 1) DO
#io2[#i] := DWORD_TO_WORD(IN := #io1[#i]);
END_FOR;
END_IF;
END_IF;

fc_PLC_V8R_ETH_MP_AOChannelConvert

fc_PLC_V8R_ETH_MP_AOChannelConvertは、アナログ出力チャンネルのデータ変換を行うファンクションです。

基本的な構造はfc_PLC_V8R_ETH_MP_AIChannelConvertと同じですが、変換方向が逆になっています。io2(Word配列)の各要素をWORD_TO_DWORDで変換しio1(DWord配列)に格納します。これにより、プログラムで扱うWord型のアナログ出力値をPROFINET通信用のDWord型に変換することができます。

FUNCTION “fc_PLC_V8R_ETH_MP_AOChannelConvert” : Word

VAR_IN_OUT
io1 : Array[*] OF DWord;
io2 : Array[*] OF Word;
ioConfigs : Array[0..7] OF “udt_PLC_V8R_ETH_MP_Configs”;
END_VAR

VAR_TEMP
i : DInt;
xEnable : Bool;
END_VAR

#fc_PLC_V8R_ETH_MP_AOChannelConvert := 16#0;
#xEnable := False;

IF LOWER_BOUND(ARR := #io1, DIM := 1) <> LOWER_BOUND(ARR := #io2, DIM := 1)
OR UPPER_BOUND(ARR := #io1, DIM := 1) <> UPPER_BOUND(ARR := #io2, DIM := 1)
THEN
#fc_PLC_V8R_ETH_MP_AOChannelConvert := 16#8000;
ELSE
#xEnable := True;
END_IF;

IF #xEnable THEN
IF #ioConfigs[#i].AIO THEN
FOR #i := LOWER_BOUND(ARR := #io1, DIM := 1) TO UPPER_BOUND(ARR := #io1, DIM := 1) DO
#io1[#i] := WORD_TO_DWORD(IN := #io2[#i]);
END_FOR;
END_IF;
END_IF;

fc_PLC_V8R_ETH_MP_DI2BoolArray

`fc_PLC_V8R_ETH_MP_DI2BoolArray`は、デジタル入力データをBool配列に変換するファンクションです。

`iodw`(DWord配列)の各要素が0より大きいかどうかを判定し、その結果を`iob`(Bool配列)の対応するインデックスに格納します。これにより、PROFINETから受信したDWord型のデジタル入力データを、プログラムで扱いやすいBool型に変換することができます。

FUNCTION “fc_PLC_V8R_ETH_MP_DI2BoolArray” : Void

VAR_IN_OUT
iodw : Array[0..7] OF DWord;
iob : Array[0..7] OF Bool;
END_VAR

VAR_TEMP

END_VAR

VAR CONSTANT

END_VAR


#iob[0] := #iodw[0] > 0;
#iob[1] := #iodw[1] > 0;
#iob[2] := #iodw[2] > 0;
#iob[3] := #iodw[3] > 0;
#iob[4] := #iodw[4] > 0;
#iob[5] := #iodw[5] > 0;
#iob[6] := #iodw[6] > 0;
#iob[7] := #iodw[7] > 0;

fc_PLC_V8R_ETH_MP_DO2DWordArray

`fc_PLC_V8R_ETH_MP_DO2DWordArray`は、Bool配列をデジタル出力データに変換するファンクションです。

`fc_PLC_V8R_ETH_MP_DI2BoolArray`の逆方向の処理で、`iob`(Bool配列)の各要素を`iodw`(DWord配列)の各要素のビット0(`%X0`)に書き込みます。これにより、プログラムで扱うBool型のデジタル出力値をPROFINET通信用のDWord型に変換することができます。

FUNCTION “fc_PLC_V8R_ETH_MP_DO2DWordArray” : Void

VAR_INPUT

END_VAR

VAR_OUTPUT

END_VAR

VAR_IN_OUT
iodw : Array[0..7] OF DWord;
iob : Array[0..7] OF Bool;
END_VAR

#iodw[0].%X0 :=#iob[0];
#iodw[1].%X0 :=#iob[1];
#iodw[2].%X0 :=#iob[2];
#iodw[3].%X0 :=#iob[3];
#iodw[4].%X0 := #iob[4];
#iodw[5].%X0 := #iob[5];
#iodw[6].%X0 := #iob[6];
#iodw[7].%X0 := #iob[7];

fc_PLC_V8R_ETH_MP_GetBMSTATE0

`fc_PLC_V8R_ETH_MP_GetBMSTATE0`は、ベースモジュールの診断データを解析するファンクションです。

入力として受け取ったDWord型の`dwSTATE`から各ビットを抽出し、`udt_PLC_V8R_ETH_MP_BM_STATE0`の対応するフラグに割り当てます。電源電圧低下(ビット4、7)、SPIインターフェースエラー(ビット8、13、14、15、16)、各スロットのエラー(ビット24〜31)をそれぞれ対応するBOOLフラグにマッピングすることで、DWord型の生データを扱いやすい構造体に変換します。

FUNCTION “fc_PLC_V8R_ETH_MP_GetBMSTATE0” : “udt_PLC_V8R_ETH_MP_BM_STATE0”
VAR_INPUT
dwSTATE : DWord;
END_VAR

#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_UnderVoltageDetected := #dwSTATE.%X4;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_ErrorMemoryUndervoltage := #dwSTATE.%X7;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_SPI_NoConnectionToDrivers := #dwSTATE.%X8;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_SPI_NoConnection := #dwSTATE.%X13;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_SPI_UndervoltageDetected := #dwSTATE.%X14;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_SPI_TemperatureOverrange := #dwSTATE.%X15;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_SPI_SlotsGroupError := #dwSTATE.%X16;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot0_Error := #dwSTATE.%X24;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot1_Error := #dwSTATE.%X25;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot2_Error := #dwSTATE.%X26;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot3_Error := #dwSTATE.%X27;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot4_Error := #dwSTATE.%X28;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot5_Error := #dwSTATE.%X29;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot6_Error := #dwSTATE.%X30;
#fc_PLC_V8R_ETH_MP_GetBMSTATE0.xDiag_BM_Slot7_Error := #dwSTATE.%X31;

fc_PLC_V8R_ETH_MP_GetBMSTATE1

`fc_PLC_V8R_ETH_MP_GetBMSTATE1`は、ベースモジュールのアナログ入力診断データを解析するファンクションです。

入力として受け取ったDWord型の`dwSTATE`から各ビットを抽出し、`udt_PLC_V8R_ETH_MP_BM_STATE1`の対応するフラグに割り当てます。スロット0〜7のアナログ入力モジュール未接続(ビット16〜23)と、スロット0〜7のアナログ/温度モジュールの値異常(ビット24〜31)をそれぞれ対応するBOOLフラグにマッピングすることで、DWord型の生データを扱いやすい構造体に変換します。

FUNCTION “fc_PLC_V8R_ETH_MP_GetBMSTATE1” : “udt_PLC_V8R_ETH_MP_BM_STATE1”

VAR_INPUT
dwSTATE : DWord;
END_VAR

#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot0_NotConnected := #dwSTATE.%X16;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot1_NotConnected := #dwSTATE.%X17;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot2_NotConnected := #dwSTATE.%X18;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot3_NotConnected := #dwSTATE.%X19;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot4_NotConnected := #dwSTATE.%X20;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot5_NotConnected := #dwSTATE.%X21;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot6_NotConnected := #dwSTATE.%X22;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogIN_Slot7_NotConnected := #dwSTATE.%X23;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot0_ValueError := #dwSTATE.%X24;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot1_ValueError := #dwSTATE.%X25;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot2_ValueError := #dwSTATE.%X26;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot3_ValueError := #dwSTATE.%X27;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot4_ValueError := #dwSTATE.%X28;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot5_ValueError := #dwSTATE.%X29;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot6_ValueError := #dwSTATE.%X30;
#fc_PLC_V8R_ETH_MP_GetBMSTATE1.xDiag_AnalogTemp_Slot7_ValueError := #dwSTATE.%X31;

fc_PLC_V8R_ETH_MP_GetBMSTATE2

`fc_PLC_V8R_ETH_MP_GetBMSTATE2`は、拡張モジュールの診断データを解析するファンクションです。

入力として受け取ったDWord型の`dwSTATE`から各ビットを抽出し、`udt_PLC_V8R_ETH_MP_BM_STATE2`の対応するフラグに割り当てます。EM1〜EM3の重大エラー(ビット2〜4)、一般エラー(ビット5〜7)、デバイス未検出(ビット8〜10)、通信エラー(ビット11)、BMおよびEM1〜EM3のステーション設定エラー(ビット16〜19)、上位コントローラーとのアクティブ接続状態(ビット29)をそれぞれ対応するBOOLフラグにマッピングすることで、DWord型の生データを扱いやすい構造体に変換します。

FUNCTION “fc_PLC_V8R_ETH_MP_GetBMSTATE2” : “udt_PLC_V8R_ETH_MP_BM_STATE2”

VAR_INPUT
dwSTATE : DWord;
END_VAR

#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM1_CriticalError := #dwSTATE.%X2;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM2_CriticalError := #dwSTATE.%X3;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM3_CriticalError := #dwSTATE.%X4;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM1_Error := #dwSTATE.%X5;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM2_Error := #dwSTATE.%X6;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM3_Error := #dwSTATE.%X7;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM1_DeviceNotDetected := #dwSTATE.%X8;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM2_DeviceNotDetected := #dwSTATE.%X9;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM3_DeviceNotDetected := #dwSTATE.%X10;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM_CommunicationError := #dwSTATE.%X11;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_BM_StationConfigError := #dwSTATE.%X16;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM1_StationConfigError := #dwSTATE.%X17;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM2_StationConfigError := #dwSTATE.%X18;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_EM3_StationConfigError := #dwSTATE.%X19;
#fc_PLC_V8R_ETH_MP_GetBMSTATE2.xDiag_ActiveConnectionToController := #dwSTATE.%X29;

fc_PLC_V8R_ETH_MP_GetEMSTATE0

`fc_PLC_V8R_ETH_MP_GetEMSTATE0`は、拡張モジュールのSPIインターフェース診断とスロットエラーを解析するファンクションです。

入力として受け取ったDWord型の`dwSTATE`から各ビットを抽出し、`udt_PLC_V8R_ETH_MP_EM_STATE0`の対応するフラグに割り当てます。SPIインターフェースエラー(ビット8、13、14、15、16)と各スロットのエラー(ビット24〜31)をそれぞれ対応するBOOLフラグにマッピングすることで、DWord型の生データを扱いやすい構造体に変換します。

FUNCTION “fc_PLC_V8R_ETH_MP_GetEMSTATE0” : “udt_PLC_V8R_ETH_MP_EM_STATE0”
VAR_INPUT
dwSTATE : DWord;
END_VAR



#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_SPI_NoConnectionToDrivers := #dwSTATE.%X8;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_SPI_NoConnection := #dwSTATE.%X13;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_SPI_UndervoltageDetected := #dwSTATE.%X14;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_SPI_TemperatureOverrange := #dwSTATE.%X15;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_SPI_SlotsGroupError := #dwSTATE.%X16;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot0_Error := #dwSTATE.%X24;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot1_Error := #dwSTATE.%X25;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot2_Error := #dwSTATE.%X26;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot3_Error := #dwSTATE.%X27;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot4_Error := #dwSTATE.%X28;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot5_Error := #dwSTATE.%X29;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot6_Error := #dwSTATE.%X30;
#fc_PLC_V8R_ETH_MP_GetEMSTATE0.xDiag_EM_Slot7_Error := #dwSTATE.%X31;

fc_PLC_V8R_ETH_MP_GetEMSTATE1

`fc_PLC_V8R_ETH_MP_GetEMSTATE1`は、拡張モジュールのアナログ入力診断データを解析するファンクションです。

入力として受け取ったDWord型の`dwSTATE`から各ビットを抽出し、`udt_PLC_V8R_ETH_MP_EM_STATE1`の対応するフラグに割り当てます。IN4〜IN7のアナログ値異常(ビット4〜7)、ベースモジュールとの通信状態(ビット10、13、14)、スロット0〜7のアナログ入力モジュール未接続(ビット16〜23)、スロット0〜7のアナログ/温度モジュールの値異常(ビット24〜31)をそれぞれ対応するBOOLフラグにマッピングすることで、DWord型の生データを扱いやすい構造体に変換します。

FUNCTION “fc_PLC_V8R_ETH_MP_GetEMSTATE1” : “udt_PLC_V8R_ETH_MP_EM_STATE0”
VAR_INPUT
dwSTATE : DWord;
END_VAR

#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_IN4_ValueError := #dwSTATE.%X4;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_IN5_ValueError := #dwSTATE.%X5;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_IN6_ValueError := #dwSTATE.%X6;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_IN7_ValueError := #dwSTATE.%X7;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_BM_CommunicationActive := #dwSTATE.%X10;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_BM_CommunicationError_SafeState := #dwSTATE.%X13;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_BM_CommunicationError := #dwSTATE.%X14;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot0_NotConnected := #dwSTATE.%X16;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot1_NotConnected := #dwSTATE.%X17;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot2_NotConnected := #dwSTATE.%X18;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot3_NotConnected := #dwSTATE.%X19;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot4_NotConnected := #dwSTATE.%X20;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot5_NotConnected := #dwSTATE.%X21;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot6_NotConnected := #dwSTATE.%X22;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogIN_Slot7_NotConnected := #dwSTATE.%X23;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot0_ValueError := #dwSTATE.%X24;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot1_ValueError := #dwSTATE.%X25;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot2_ValueError := #dwSTATE.%X26;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot3_ValueError := #dwSTATE.%X27;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot4_ValueError := #dwSTATE.%X28;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot5_ValueError := #dwSTATE.%X29;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot6_ValueError := #dwSTATE.%X30;
#fc_PLC_V8R_ETH_MP_GetEMSTATE1.xDiag_AnalogTemp_Slot7_ValueError := #dwSTATE.%X31;

FUNCTION BLOCK

次は今回記事で作成したFUNCTION BLOCKを紹介します。

fb_PLC_V8R_ETH_MP

InOutパラメータとして、PROFINETの入力データ`iorawin`(`udt_PLC_V8R_ETH_MP_BM_IN`)、出力データ`iorawout`(`udt_PLC_V8R_ETH_MP_BM_OUT`)、そしてシステム全体のデータを集約した`iodut`(`udt_PLC_V8R_ETH_MP_EM`)の3つを持ちます。これらを通じて、PROFINETの生データの受け取りと、各種変換処理を経たデータの管理を一つのファンクションブロックで完結させることができます。

ネットワーク3-6

Network3〜6では、fc_PLC_V8R_ETH_MP_DI2BoolArrayを使ってPROFINETから受信したスロットデータをBool配列に変換しています。

  • Network3(BM):#iorawin.BM_Slot_INをiodwに、#iodut.BM_IN_DIをiobに接続し、ベースモジュールのデジタル入力を変換します。
  • Network4(EM1):#iorawin.EM1_Slot_INをiodwに、#iodut.EM_IN_DIs[0]をiobに接続し、拡張モジュール1のデジタル入力を変換します。
  • Network5(EM2):#iorawin.EM2_Slot_INをiodwに、#iodut.EM_IN_DIs[1]をiobに接続し、拡張モジュール2のデジタル入力を変換します。
  • Network6(EM3):#iorawin.EM3_Slot_INをiodwに、#iodut.EM_IN_DIs[2]をiobに接続し、拡張モジュール3のデジタル入力を変換します。
ネットワーク8-10

Network8〜10では、fc_PLC_V8R_ETH_MP_AIChannelConvertを使ってアナログ入力データをDWordからWordに変換しています。

  • Network8(BM):#iorawin.BM_Slot_INをio1に、#iodut.BM_IN_AIをio2に、#iodut.BMConfigsINをioConfigsに接続し、ベースモジュールのアナログ入力を変換します。
  • Network9(EM1):#iorawin.EM1_Slot_INをio1に、#iodut.EM_IN_AIs[0]をio2に、#iodut.EMConfigsIN[0]をioConfigsに接続します。変換後、MOVEインストラクションで#iorawin.EM1_ANALOG_IN_exを#iodut.EM_IN_AIs_ex[0]にコピーします。
  • Network10(EM2):#iorawin.EM2_Slot_INをio1に、#iodut.EM_IN_AIs[1]をio2に、#iodut.EMConfigsIN[1]をioConfigsに接続します。変換後、MOVEインストラクションで#iorawin.EM2_ANALOG_IN_exを#iodut.EM_IN_AIs_ex[1]にコピーします。
ネットワーク11

Network11(EM3):#iorawin.EM3_Slot_INをio1に、#iodut.EM_IN_AIs[2]をio2に、#iodut.EMConfigsIN[2]をioConfigsに接続します。変換後、MOVEインストラクションで#iorawin.EM3_ANALOG_IN_exを#iodut.EM_IN_AIs_ex[2]にコピーします。

ネットワーク13-15

Network13〜15では、ベースモジュールの診断データを解析しています。

  • Network13(STATE0):#iorawin.BM_State[0]をdwSTATEに接続し、fc_PLC_V8R_ETH_MP_GetBMSTATE0で解析した結果を#iodut.BM_IN_STATE.stSTATE0に格納します。
  • Network14(STATE1):#iorawin.BM_State[1]をdwSTATEに接続し、fc_PLC_V8R_ETH_MP_GetBMSTATE1で解析した結果を#iodut.BM_IN_STATE.stSTATE1に格納します。
  • Network15(STATE2):#iorawin.BM_State[2]をdwSTATEに接続し、fc_PLC_V8R_ETH_MP_GetBMSTATE2で解析した結果を#iodut.BM_IN_STATE.stSTATE2に格納します。
ネットワーク17-18

Network17〜18では、拡張モジュールの診断データを解析しています。

  • Network17(EM1):#iorawin.EM1_State[0]をfc_PLC_V8R_ETH_MP_GetEMSTATE0で解析し結果を#iodut.EM_IN_STATE[1].stSTATE0に格納します。続けて#iorawin.EM1_State[1]をfc_PLC_V8R_ETH_MP_GetEMSTATE1で解析し結果を#iodut.EM_IN_STATE[1].stSTATE1に格納します。
  • Network18(EM2):#iorawin.EM2_State[0]をfc_PLC_V8R_ETH_MP_GetEMSTATE0で解析し結果を#iodut.EM_IN_STATE[2].stSTATE0に格納します。続けて#iorawin.EM2_State[1]をfc_PLC_V8R_ETH_MP_GetEMSTATE1で解析し結果を#iodut.EM_IN_STATE[2].stSTATE1に格納します。
ネットワーク19

Network19(EM3):#iorawin.EM3_State[0]をfc_PLC_V8R_ETH_MP_GetEMSTATE0で解析し結果を#iodut.EM_IN_STATE[3].stSTATE0に格納します。続けて#iorawin.EM3_State[1]をfc_PLC_V8R_ETH_MP_GetEMSTATE1で解析し結果を#iodut.EM_IN_STATE[3].stSTATE1に格納します。

ネットワーク21-22

Network21〜22では、出力データの変換処理を行っています。

  • Network21(BM):まずfc_PLC_V8R_ETH_MP_DO2DWordArrayで#iodut.BM_OUT_DO(Bool配列)を#iorawout.BM_Slot_OUT(DWord配列)に変換します。続けてfc_PLC_V8R_ETH_MP_AOChannelConvertで#iodut.BM_OUT_AO(Word配列)を#iorawout.BM_Slot_OUT(DWord配列)に変換し、#iodut.BMConfigsOUTをioConfigsに接続します。
  • Network22(EM1):まずfc_PLC_V8R_ETH_MP_DO2DWordArrayで#iodut.EM_OUT_DOs[0](Bool配列)を#iorawout.EM1_Slot_OUT(DWord配列)に変換します。続けてfc_PLC_V8R_ETH_MP_AOChannelConvertで#iodut.EM_OUT_AOs[0](Word配列)を#iorawout.EM1_Slot_OUT(DWord配列)に変換し、#iodut.EMConfigsOUT[0]をioConfigsに接続します。
ネットワーク21-23

Network23(EM2):まずfc_PLC_V8R_ETH_MP_DO2DWordArrayで#iodut.EM_OUT_DOs[1](Bool配列)を#iorawout.EM2_Slot_OUT(DWord配列)に変換します。続けてfc_PLC_V8R_ETH_MP_AOChannelConvertで#iodut.EM_OUT_AOs[1](Word配列)を#iorawout.EM2_Slot_OUT(DWord配列)に変換し、#iodut.EMConfigsOUT[1]をioConfigsに接続します。

ネットワーク24

Network24(EM3):まずfc_PLC_V8R_ETH_MP_DO2DWordArrayで#iodut.EM_OUT_DOs[2](Bool配列)を#iorawout.EM3_Slot_OUT(DWord配列)に変換します。続けてfc_PLC_V8R_ETH_MP_AOChannelConvertで#iodut.EM_OUT_AOs[2](Word配列)を#iorawout.EM3_Slot_OUT(DWord配列)に変換し、#iodut.EMConfigsOUT[2]をioConfigsに接続します。

OB1

最後はOB1から検証プログラムを作成します。

ネットワーク1

Network1(Configs)では、BMの入出力設定フラグを初期化しています。

`dbPLC_V8R_ETH_MP.BMConfigsIN[0].DIO`〜`BMConfigsIN[7].DIO`をセットし、続けて`dbPLC_V8R_ETH_MP.BMConfigsOUT[0].DIO`〜`BMConfigsOUT[7].DIO`をセットすることで、ベースモジュールの全スロット(0〜7)のデジタルI/O設定を有効化しています。

ネットワーク2

Network2では、ベースモジュールのデジタル入力をデジタル出力に折り返すテスト用ラダーです。

  • BM_IN_DI[4] → BM_OUT_DO[0]
  • BM_IN_DI[5] → BM_OUT_DO[1]
  • BM_IN_DI[6] → BM_OUT_DO[2]
  • BM_IN_DI[7] → BM_OUT_DO[3]

入力スロット4〜7の状態をそのまま出力スロット0〜3に反映させることで、デジタルI/Oの動作確認を行っています。

ネットワーク3

Network3では、fb_PLC_V8R_ETH_MP(DB2)を呼び出しています。

PROFINETの入力アドレスP#I0.0にマップされた_PLC_V8R_ETH_MP_BM_INをiorawinに、出力アドレスP#Q0.0にマップされた_PLC_V8R_ETH_MP_BM_OUTをiorawoutに、そしてデータブロックdbPLC_V8R_ETH_MP(DB1)をiodutに接続することで、PROFINETの生データの受け取りからデータ変換・管理までを一括して実行します。

ダウンロード

最後はプロジェクトをS71500にDownloadしましょう。

結果

Done!PLC-V8R/ETH-MP/BMとS7-1500とProfinet IRT通信が成立しました。

こちらの動画から動作確認できます。

ダウンロード

今回記事で作成したプロジェクトを下記のGITHUBからDownloadしてください。

https://github.com/soup01Threes/Siemens/blob/main/TestWithPH-PLC-V8R2.zap20

シェアする

  • このエントリーをはてなブックマークに追加

フォローする