この記事ではSchneider TM241とBeckhoff IPC C6920でEthernet/IP Networkを構築します。Beckhoff側はScannerでSchneider TM241がAdapterになり、なおかつTwincat側はIOデータ一致性をCheckするプログラムも作成していきます。
よろしくおねがいします。
Thanks!
この記事が出来上がるのはベッコフ日本法人ベッコフオートメーション株式会社さまとMana Design worksさまから機材を貸してくださったおかけです。誠にありがとうございます。
ベッコフ日本法人ベッコフオートメーション株式会社
IPC6920-005はベッコフ日本法人ベッコフオートメーション株式会社さまが貸してくださったものです。Beckhoff Automationは1980 年会社設立、PCベースの制御技術をベースにしたオープンオートメーションシステム導入の先頭に立つドイツ企業です。
ベッコフ日本法人ベッコフオートメーション株式会社は、2011年に横浜に本社、2017年に名古屋オフィスを設立しました。
こちらはベッコフ日本法人ベッコフオートメーション株式会社様のホームページです。
どうぞよろしくお願いします。
https://www.beckhoff.com/ja-jp/
Mana Design Works
Schneider PLCはMana Design Works 様からのご提供でお送ります。内容は自体はシュナイダーですが、Mana Design Worksは大阪に本社あるSiemensの正式なソリューション パートナーで、Siemens製のCPU・HMI・Drive・Motion Controller・SCADAから国産メーカまで常に最適な提案できます
こちらはMana Design Works 様のホームページです。
どうぞよろしくお願いします。
Implementation
こちらは今回の記事のConfigurationです。
Schneider Side
ではまずTM241 PLCから始めます。こちらのEthernet portを使用します。
New Project
Machine Expert Logic Builderを起動し>File>New Projectで新規プロジェクトを作成します。
Controler TypeにTM241CET/Uを設定>Project名を入力>OKします。
新規プロジェクトが作成されました。
Configure Ethernet Interface
“Ethernet_1*をダブルクリックしCPUのEthernet Interface を設定します。
Configured Parametersで” fixed IP Address”を設定すればIPを入力できるようになります。
192.168.250.33/24に設定します。
Configure an Ethernet/IP Adapter
Ethernet_1右クリック>Add Deviceします。
Fieldbus からEthernet/IP>Ethernet/IP Local Adapter>EthernetIPを選び>Add Devicesします。
Assembly Parameters
次はSchneiderのInput/Output AssemblyやData Sizeの設定を行います。
EthernetIP をダブルクリックします。
EtherNEIP Tabが開きました。
Instance Numbers
DefaultではInstance150はOut Assembly、Instance100はInput Assemblyになっています。
Size(Word)
そしてデータ交換のDefault Sizeは20 Wordsです。
ここで32 Wordsを変更します。
I/O Mapping
EthernetIp Slave IO MappingからInput/Output変数のMappingを一覧できます。
Defaultで20Wordsのデータ交換のせいで、Machine Expert Logic Builderが自動的に iwEthernetIP_IWxのGlobal変数と紐つけます。
Outputs画面も同じです。
Export EDS
EthernetIP icon右クリック>Export as EDS からEDS FileをExportします。このFileはTwinCATぐぁで使用します。
保存先を設定します。
Done!
Program
Application tree tabを開きます。
GVL
Program editor は表示され、GVLの中にEthernet/IP Adapter用の変数をいくつか定義します。”GVL” Iconをダブルクリックします。
GVL tabが開かれました。
2つの長さ32 Wordsの配列を定義します。こちらの変数はEthernet/IP AdapterのMappingで使用します。
Main
SR_Mainプログラムの中のInputデータをそのままOutputにLoopbackすればよいです。
検証プログラムがTwinCAT側で実装されます。
Mapping Again
次はEthernet/IP Adapterの変数を再Mappingします。
Input
こちらはInputs 変数で、GVLで定義された変数に再Mappingします。
Output
こちらはOutputs 変数で、GVLで定義された変数に再Mappingします。
Login
Schneider側はここで終わります。次はProjectをCPUにDownloadしましょう。
Controller iconをクリックし>Download先を選び>Loginします。
YesでProjectをDownloadすれば完成です。
TwinCAT Side
いまからTwinCAT側を実装しますが、最初にIO Dataの一致性CheckはTwinCAT側に任せ、InputとOutput Dataが一致しているかをCheckします。こちらはプログラムのFlowになります。TwinCATはまずScanner Statusを確認>次はAdpaterの状態を確認>乱数データを出力>入力データが一致してるか確認>Loop Backのイメージです。
Configure An Ethernet/IP Scanner
まずEthernet/IP Sacnnerを追加します。I/O>Devices>右クリック>Add New Itemします。
EtherNet/IP>EtherNet/IP Scannerを選び>OKです。
実際にEthernet/IP に接続しているEthernet Interaceを設定してください。
もう一度AdapterのTabを開き>設定されたInterfaceが正しいかを確認しましょう。
Configure the IP
Settings Tabを開き、F800.20,F800.21の項目からIPとNetwork Maskを設定してください。
Task
次はSync TaskのTab開きEthernet/IP Scanner用のTaskを追加します。
Select Special Sync Task option>Create new I/O Taskします。
Task名を入力>OKします。
Ethernet/IP Taskが作成され、アプリケーションによりCycle Timeを調整しましょう。
Configure Target
次はEthernet/IP AdapterをProjectに構築していきます。
Import EDS
Scannerを右クリック>Import EDS Fileします。
EDSを選び>Openします。
EDS FileがImportされました。
Insert Schneider Adapter
Scannerで右クリック>Add New Itemします。
Schneider Electric>TM241_xxxx を選択>Ok。
TM241 Ethernet/IP adapterが追加されました。
Configure IP
TM241 Ethernet/IP Adapterを右クリック>Change IP AddressでIP変更します。
IPを入力しOKします。
IPが設定されたら、ICONも変わります。
Append IO
Box1を右クリック>Append IO Connection> Read From 100/Write to 150を選びます。
Yes.
Connection 1 (Input/Output) はBox1に追加されました。
Mapping-input
EDS FileがImportしたConnectionでは変数が少し変ですよね。それはSchneiderがDefaultのデータ交換Sizeは32Wordsなので、それ以外の変数は“noname0_arrBYTE”の配列になっています。
Mapping-Output
Outputも同じです。
Add PLC
PLC>Add New ItemでSoftware PLCをProjectに追加します。
Standard Project>Addします。
Standard PLCが追加されました。
GVLs(Global Variable List)
こちらはGVLでProcess IO変数が定義され、こちらの変数はEthernet/IP データと紐つけます。
{attribute ‘qualified_only’} VAR_GLOBAL EIP_Scanner1_Box1_Inputs AT %I*:ARRAY[0..31]OF WORD; EIP_Scanner1_Box1_Outputs AT %Q*:ARRAY[0..31]OF WORD; END_VAR |
DUT
DUT_TF6281_DevState
こちらはTF6281 Ethernet/IP Scannerの状態をまとめる構造体です。
TYPE DUT_TF6281_DevState : STRUCT LinkError :BOOL; OutOfSendResources :BOOL; WatchdogTrigger :BOOL; MasterNoValidIPAddr :BOOL; TCPUnable :BOOL; UDPUnable :BOOL; END_STRUCT END_TYPE |
TC3 EIP Scanner ObjectのDeveState変数から詳しい情報を取得できます。
詳しいStatusはComment Fieldから確認できます。
DUT_TF6281_Boxes_State
TC3 EIP Scanner Objectの各Ethernet/IP Adapterの接続状態を示すState変数から詳しい情報を取得できます。
TYPE DUT_TF6281_Boxes_State : STRUCT ConnectionDisconnected :ARRAY[1..8]OF BOOL; TCPClientInitFailed :BOOL; UDPClientInitFailed :BOOL; RemoteNodeNoConnections :BOOL; RemoteNodeNotReachable :BOOL; END_STRUCT END_TYPE |
TC3 EIP Scanner の下の各AdapterのState変数から詳しい情報を取得できます。
詳しいStatusはComment Fieldから確認できます。
Function Block
DUTの定義が終わったら次はFunction Blockを作成し、Ethernet/IP Scannerと各Adapterの状態を取得しましょう。
FB_TF6281_Status
VAR
こちらの変数は直接Process I/OにMappingされています。
FUNCTION_BLOCK FB_TF6281_Status VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR EIP_Scanner_Boxes_State AT %I* :ARRAY[1..4]OF UINT; EIP_Scanner_DevState AT %I* :UINT; END_VAR |
PROPERTY DevNormal : Bool
Get
このPropertyはScannerが正常状態かを取得できます。
DevNormal:=EIP_Scanner_DevState =0; |
PROPERTY PUBLIC DevState : DUT_TF6281_DevState
Get
このPropertyはDeveState変数の現在値をEncodeし、該当するエラーを返します。
DevState.LinkError:=(EIP_Scanner_DevState AND 16#0001)>0; DevState.OutOfSendResources:=(EIP_Scanner_DevState AND 16#0010)>0; DevState.WatchdogTrigger:=(EIP_Scanner_DevState AND 16#0020)>0; DevState.MasterNoValidIPAddr:=(EIP_Scanner_DevState AND 16#4000)>0; DevState.TCPUnable:=(EIP_Scanner_DevState AND 16#2000)>0; DevState.UDPUnable:=(EIP_Scanner_DevState AND 16#1000)>0; |
GetBoxStates : DUT_TF6281_Boxes_State
このMethodはEthernet/IP Adapter状態をReturnします。BoxNumberのパラメータから取得したいConnection番号を選べます。
VAR
METHOD GetBoxStates : DUT_TF6281_Boxes_State VAR_INPUT BoxNumber:UINT; END_VAR VAR _State:UINT; END_VAR |
PROGRAM
IF BoxNumber>=1 AND BoxNumber<=4 THEN _State:=EIP_Scanner_Boxes_State[BoxNumber]; ELSE _State:=EIP_Scanner_Boxes_State[1]; END_IF GetBoxStates.ConnectionDisconnected[1]:=(_State AND 16#0001)>0; GetBoxStates.ConnectionDisconnected[2]:=(_State AND 16#0002)>0; GetBoxStates.ConnectionDisconnected[3]:=(_State AND 16#0004)>0; GetBoxStates.ConnectionDisconnected[4]:=(_State AND 16#0008)>0; GetBoxStates.ConnectionDisconnected[5]:=(_State AND 16#0010)>0; GetBoxStates.ConnectionDisconnected[6]:=(_State AND 16#0020)>0; GetBoxStates.ConnectionDisconnected[7]:=(_State AND 16#0040)>0; GetBoxStates.ConnectionDisconnected[8]:=(_State AND 16#0080)>0; GetBoxStates.UDPClientInitFailed:=(_State AND 16#1000)>0; GetBoxStates.TCPClientInitFailed:=(_State AND 16#2000)>0; GetBoxStates.RemoteNodeNotReachable:=(_State AND 16#4000)>0; GetBoxStates.RemoteNodeNoConnections:=(_State AND 16#8000)>0; |
POUs EIP_IOs
最後はPOUsを作成しIO Dataの一致性をCheckします。
Add Referenced Task
Projectで右クリック>Add>Referenced Taskします。
先程のStepで作成したTaskを選び>Openします。
Reference Taskが作成されました。
VAR
こちらはPOUsで使用する変数です。
PROGRAM EIP_IOs VAR Scanner1 :FB_TF6281_Status; iCounter:INT; OutputRefleshed:BOOL; IODataChecked:BOOL; Seed:INT; Random :DRAND; DataNoSame :BOOL; TimerIOVerify:TON; TimerOutputReflesh:TON; ScannerReady:BOOL; Box1:DUT_TF6281_Boxes_State; Start2Verify :BOOL; pStart2Verify :R_TRIG; tIOVerifyTime :TIME:=T#64MS; tOutputFlash :TIME:=T#96MS; END_VAR |
PROGRAM
プログラムの流れは最初に言った通り、まずScanner状態をCheck>Adapter接続状態Check>乱数データを生成>データ出力>データ入力と一致してるか>もし一致しないならリセット不可のBitをTrueします。
//Get Scanner and box status ScannerReady:=Scanner1.DevNormal; Box1:=Scanner1.GetBoxStates(1); IF ScannerReady AND NOT Box1.ConnectionDisconnected[1] AND NOT Box1.RemoteNodeNotReachable AND NOT Box1.RemoteNodeNoConnections AND NOT Box1.TCPClientInitFailed AND NOT Box1.UDPClientInitFailed THEN //This Bit will never reset – for the first time CPU Start up Start2Verify:=TRUE; END_IF; //Verification will start while Scanner and Box is ready. pStart2Verify(CLK:=Start2Verify); //IO Verification //Read IF TimerIOVerify.Q THEN FOR iCounter:=0 TO 31 DO IF GVL.EIP_Scanner1_Box1_Outputs[iCounter] <> GVL.EIP_Scanner1_Box1_Inputs[iCounter] THEN DataNoSame:=TRUE; END_IF END_FOR OutputRefleshed:=FALSE; IODataChecked:=TRUE; END_IF; //Write IF TimerOutputReflesh.Q OR pStart2Verify.Q THEN FOR iCounter:=0 TO 31 DO Random.Seed:=Seed; Random(); GVL.EIP_Scanner1_Box1_Outputs[iCounter]:=LREAL_TO_WORD((Random.Num*100)); END_FOR OutputRefleshed:=TRUE; IODataChecked:=False; END_IF //Time Reflesh //IOVerification TimerIOVerify( IN:=OutputRefleshed AND NOT IODataChecked ,PT:=tIOVerifyTime ); //Output Flesh TimerOutputReflesh( IN:=IODataChecked AND NOT OutputRefleshed ,PT:=tOutputFlash ); |
Build
Build>Build Solution でプロジェクトをコンパイルします。
Link the variables
Inputs
EDS Fileに沿ってImportされた変数を一回全部削除します。
Inputs右クリック>Add New Itemします。
変数名入力し、Data TypeをWordに選択>”Create Array Type” Buttonで配列変数を宣言します。
array[0…31]of WORDを定義します。
Done!そしてUser Programの変数と紐つけましょう。
Outputs
EDS Fileに沿ってImportされた変数を一回全部削除します。
Outputs右クリック>Add New Itemします。
Array[0..31] OF WORDを選び>OKします。
そしてUser Programの変数と紐つけましょう。
DevState
次はScannerのDevState変数と紐つけます。DevState>右クリック>Change Linkします。
変数を選び>OKします。
State
最後はAdapterの接続状態を示す変数StateをUser Programと紐つけます。右クリック>Change Linkします。
変数を選び>OKします。
Result
TM241 Schneider PLCはエラーなしで起動できました。
WiresharkからもCIP I/O Packagesが流れていると見えました。
乱数データもTwincatから受信します。
TwinCAT側でも乱数データをSchneider TM241 PLCに送信しています。
下記のLinkからSchneider TM241のLED Statusが確認できます。
Source Code Download
こちらのLinkからProjectをDownlaodできます。
https://github.com/soup01Threes/TwinCAT3/blob/main/TwinCAT3_Schneider_TM241_EIP_Project.7z