この記事ではWago750-362 Modus TCP Coupler使用しModbus TCP Slaveを立ち上げ、Beckhoff TwinCAT3 TF6250 のFunction BlockとBosch Rexrosh CtrlX VirtualCore x Modbus TCP Appsを使用し接続検証します。
よろしくおねがいします。
Thanks!
この記事が出来上がるのはベッコフ日本法人ベッコフオートメーション株式会社さまとワゴジャパン株式会社さまから機材を貸してくださったおかけです。誠にありがとうございます。
ベッコフ日本法人ベッコフオートメーション株式会社
IPC6920-005はベッコフ日本法人ベッコフオートメーション株式会社さまが貸してくださったものです。Beckhoff Automationは1980 年会社設立、PCベースの制御技術をベースにしたオープンオートメーションシステム導入の先頭に立つドイツ企業です。実際Beckhoffが関わる分野はIPCだけではなく、Motion・Vision・Iot・ロボットなど様々な分野に常に新たなイノベーションを生み出してます。
ベッコフ日本法人ベッコフオートメーション株式会社は、2011年に横浜に本社、2017年に名古屋オフィスを設立しました。
こちらはベッコフ日本法人ベッコフオートメーション株式会社様のホームページです。
どうぞよろしくお願いします。
https://www.beckhoff.com/ja-jp/
ワゴジャパン株式会社
Modbus TCP Coupler750-362はワゴジャパン株式会社さまが貸してくださったものです。WAGO は 1951 年に設立され、いままで端子台の技術で世界中の産業にずっと貢献してるドイツ企業、PUSH WIREやCAGE CLAMPの技術などで現場を支えてきました。他にWAGOさまにもPLC LINEUPがあり、オープン性と柔軟性に重点を置いた自動化ソリューションを提供しています。
ワゴジャパン株式会社は 東京都江東区に本社があります。
Wago Side
こちらは今回の記事で使用するWago社のModbus TCP Coupler 750-362で、隣にインストールされているのは750-1417(8チャンネルデジタル入力)・750-1516(8チャンネルデジタル出力)・750-597(8チャンネルアナログ出力)・750-471(4チャンネルアナログ入力)になります。
LED
750-362に表面にはLED表示があり現在Couplerの状態を示しています。Manualを参照し、更に詳しい情報があります。
Power Supply
こちらはCouplerの電源です。
Example
こちらはModbus Functionを使用する簡単なシステム例です。
Operation System
750-362が電源を入れ・リセットするとシステムが稼働しはじめます。
750-362は起動はじめ各SlotにインストールされているModuleやCoupler自体の設定が問題あるかをCheckします(この間はI/O LEDが赤点滅)。
もしCouplerは”Fieldbus Start”モードに遷移すればI/O LEDが緑になります。
もしCouplerになにかエラーが発生した場合、I/O LEDが赤になります。
Process Data
Fieldbus Couplerは基本的には一緒にインストールされているモジュールのデータをMasterと受送信します。
デジタルIOモジュールはBitベースで、アナログモジュールはByteベースになり、データは場合により複数のByteにグループされ送る場合もあります。(Counterモジュール、計測モジュールなど…)
それらのProcess DataはPII(Process Input Data)とPIO(Process Output Data)2種類あり、実際Moduleにインストールされている場所によって変わります。
(もしデジタルIOデータが8Bit 以上のものであれば、Couplerは自動で新しいByteでデータを操作します。)
Data Exchange
750-362 Modbus Fieldbus Couplerを使用することにより、Modbus TCPやModubus UDP経由で Master/Slave間の通信が実現できます。Slaveはもちろん750-362 Couplerですが、MasterはPLCやPCでも可能です。(今回使用するのはTwinCAT TF6250とCtrlX Modbus TCP App)。
こちらは750-362の同時接続規格です。(Socket)
- 3 connections for HTTP(s), The HTML pages from the coupler.
- 15 connections via Modbus TCP
- 10 Connections for FTP.
Memory Space
すべてのWago Fieldbus CouplerもProecss Imagesに物理のデータが格納されています。
その範囲は0..255と512..1275です。
- CPU/Fieldbus 側がInput Moduleのデータを読み取ります。
- CPU/Fieldbus 側がOutput Moduleのデータを書き込みます。
Controllerの視点からみると、4つのProcess Dataがあります。
- Input words
- Output words
- Input bits
- Output bits
IP addressing
Modbus TCP Coupler 750-362にIPを割り付ける方法が4つあります。
- DIP Switch(Manually)
- DHCP
- “WAGO Ethernet Setting”, シリアルケーブルやLAN Portからの転送
- using BootP
DIP
DIP Switchを使用すればIPアドレスの最後のByteを変更すること(1-254まで)が可能です。例えば、DIPスイッチにbinary code 00110010(50)を設定すれば、CouplerのIp Addressは192.168.1.50になります。
DIP Switch Setting Range:
- 1..254、 IP アドレス 192.168.1.1 から 192.168.1.254まで
- 0,DHCP,BooP,Staticを使用する
- 255,DHCP のみ使用する
Commissioning
DIP Switch
今回の記事では自分はDIPスイッチをすべて1をSetし750-362 CouplerをDHCP経由でIP設定を行います。ネットワークのトラブルを防止するため、Network上で一つだけのDHCP Serverがあることを確認してください。
そしてDHCP Serverはあくまでも一時的にIPを振り分けるだけなので、実際のアプリケーションでは最終的にはStaticの方法でIPを設定してあげてください。
Web server
Access the server
ChromeなどのBrowerから750-362のIPを入力しCouplerのWBMにアクセスします。
TCP/IP
TCP/IP Settingsを開きます。
Loginが必要ですが、Default上で、
- user=admin,password=wago
- user=user,password=user
Loginが成功すれば、CouplerのIpをStaticの方法で設定することも可能です。
Mapping
Fieldbus>Modbus Mappingを開くと、I/O Mapping画面が表示されます。
この画面から各SlotのModbus アドレスを確認できます。
Modbus
ここで一旦とまり、Modbus Communicationに使用してるFunction Codeを説明します。
Function Code
FC2(Read Discrete Inputs)
こちらのFuncitonはModbus SlaveデバイスからBitsデータを読みます。Master側が送信するリクエストは読み取るデバイスの先頭アドレスとデバイス数を設定します。
FC3(Read Multiple Registers)
こちらのFuncitonはModbus SlaveデバイスからHolding Registerを読みます。Master側が送信するリクエストは読み取るデバイスの先頭アドレスとデバイス数(Word)を設定します。
FC4(Read Input Registers)
こちらのFuncitonはModbus Slaveデバイスからinput registersを読みます。Master側が送信するリクエストは読み取るデバイスの先頭アドレスとデバイス数(Word)を設定します。
FC5(Write Coil)
こちらのFuncitonはModbus SlaveデバイスからBitsデータを書き込みます。Master側が送信するリクエストは書き込むデバイスの先頭アドレスとデバイス数を設定します。
FC6(Write Single Register)
こちらのFuncitonはModbus Slaveデバイスから1つだけのを書き込みます。Master側が送信するリクエストは書き込むデバイスの先頭アドレスを設定します。
FC11(Get Comm Event Counter)
こちらのFunctionはModbus SlaveからStatus WordとEvent Counterを取得できます。
FC15(Write Multiple Coils)
こちらのFuncitonはModbus SlaveデバイスからOutput Coilsを書き込みます。Master側が送信するリクエストは順番の1,0で書き込み、そして該当するデバイスの先頭アドレスとデバイス数を設定します。
FC16(Write Multiple Registers)
こちらのFuncitonはModbus Slaveデバイスから複数を書き込みます。Master側が送信するリクエストは順番のデータで書き込み、そして該当する先頭アドレスとデバイス数を設定します。
FC22(Mask Write Register)
こちらのFunctionはAND MaskやOR Maskを使用しRegisterのデータを処理します。
FC23(Read/Write Multiple Registers)
こちらのFunctionは読み書きを1つのリクエストとしてまとめます。
Mapping
FC3/FC4
こちらはFC3/FC4のModbus アドレスです。
FC6/FC16
こちらはFC6/FC16のModbus アドレスです。
FC1/FC2
こちらはFC1/FC2のModbus アドレスです。
FC5/FC15
こちらはFC5/FC15のModbus アドレスです。
Implementation-1 with TwinCAT
こちらのImplementationではBeckhoff TwinCAT3 TF6250 Modbus TCP Function Blockを使用しWago750-362 Modbus TCP Couplerのデータにアクセスします。
Reference Link
Config
Slot1 750-1417
Slot1では、FB_MBReadCoils Function BlockにnQuantity=8,nMBAddr=0に設定します。
Slot2 750-1516
Slot2ではFB_MBReadRegs Function BlockにnQuantity=1,nMBAddr=520に設定します。
Slot3 750-597
Slot3ではFB_MBWriteRegs Function BlockにnQuantity=8,nMBAddr=512に設定します。
Slot4 750-471
Slot4でFB_MBReadRegs Function BlockにnQuantity=4,nMBAddr=0に設定します。
PLC Side
こちらはPLCプログラムです。
VAR
PROGRAM MAIN VAR iStep :INT; bStart :BOOL; bReset :BOOL; bSlotAutoReflash :BOOL; END_VAR VAR FB_MBReadCoilsSlot1:FB_MBReadCoils; FB_MBWriteRegsSlot2:FB_MBWriteRegs; FB_MBWriteRegsSlot3:FB_MBWriteRegs; FB_MBReadRegsSlot4 :FB_MBReadRegs; WagoSlot1 :BYTE; WagoSlot2 :INT; WagoSlot3 :ARRAY[0..7]OF INT; WagoSlot4 :ARRAY[0..3]OF INT; F_TRIG_Slots :ARRAY[1..4]OF F_TRIG; TONs :ARRAY[0..3] OF ton; END_VAR VAR CONSTANT sIPAddr :STRING:=’192.168.3.144′; nTCPPort :UINT:=502; END_VAR |
PROGRAM
プログラムではSlot1デジタル入力(750-1417)のデータを読み>Slot2デジタル出力データを書き込み>Slot3アナログ出力データ(750-597)を書き込み>最後はSlot4アナログ入力データ(750-471)を読み>Lopp Backのイメージです。
IF bSlotAutoReflash THEN TONs[0](IN:=WagoSlot2=0,PT:=T#1S); TONs[1](IN:=WagoSlot2=16#FF,PT:=T#1S); IF TONs[0].Q THEN WagoSlot2:=16#FF; WagoSlot3[4]:=WagoSlot3[4]+16#100; END_IF IF TONs[1].Q THEN WagoSlot2:=16#00; END_IF IF WagoSlot3[4] >=16#7500 THEN WagoSlot3[4]:=16#00; END_IF END_IF; CASE iStep OF 0: IF bStart THEN iStep:=10; bStart:=FALSE; bReset:=FALSE; END_IF 10: FB_MBReadCoilsSlot1.nTCPPort:=nTCPPort; FB_MBReadCoilsSlot1.nUnitID:=1; FB_MBReadCoilsSlot1.nQuantity:=8; FB_MBReadCoilsSlot1.sIPAddr:=sIPAddr; FB_MBReadCoilsSlot1(bExecute:=FALSE); FB_MBReadCoilsSlot1.cbLength:=SIZEOF(WagoSlot1); FB_MBReadCoilsSlot1.pDestAddr:=ADR(WagoSlot1); FB_MBReadCoilsSlot1.nMBAddr:=0; FB_MBWriteRegsSlot2.nTCPPort:=nTCPPort; FB_MBWriteRegsSlot2.nUnitID:=1; FB_MBWriteRegsSlot2.nQuantity:=1; FB_MBWriteRegsSlot2.sIPAddr:=sIPAddr; FB_MBWriteRegsSlot2(bExecute:=FALSE); FB_MBWriteRegsSlot2.cbLength:=SIZEOF(WagoSlot2); FB_MBWriteRegsSlot2.pSrcAddr:=ADR(WagoSlot2); FB_MBWriteRegsSlot2.nMBAddr:=520; FB_MBWriteRegsSlot3.nTCPPort:=nTCPPort; FB_MBWriteRegsSlot3.nUnitID:=1; FB_MBWriteRegsSlot3.nQuantity:=8; FB_MBWriteRegsSlot3.sIPAddr:=sIPAddr; FB_MBWriteRegsSlot3(bExecute:=FALSE); FB_MBWriteRegsSlot3.cbLength:=SIZEOF(WagoSlot3); FB_MBWriteRegsSlot3.pSrcAddr:=ADR(WagoSlot3); FB_MBWriteRegsSlot3.nMBAddr:=512; FB_MBReadRegsSlot4.nTCPPort:=nTCPPort; FB_MBReadRegsSlot4.nUnitID:=1; FB_MBReadRegsSlot4.nQuantity:=4; FB_MBReadRegsSlot4.sIPAddr:=sIPAddr; FB_MBReadRegsSlot4(bExecute:=FALSE); FB_MBReadRegsSlot4.cbLength:=SIZEOF(WagoSlot4); FB_MBReadRegsSlot4.pDestAddr:=ADR(WagoSlot4); FB_MBReadRegsSlot4.nMBAddr:=0; IF NOT FB_MBReadCoilsSlot1.bBusy AND NOT FB_MBWriteRegsSlot2.bBusy AND NOT FB_MBWriteRegsSlot3.bBusy AND NOT FB_MBReadRegsSlot4.bBusy THEN iStep:=20; END_IF 20: FB_MBReadCoilsSlot1(bExecute:=TRUE); F_TRIG_Slots[1](CLK:=FB_MBReadCoilsSlot1.bBusy); IF F_TRIG_Slots[1].Q AND NOT FB_MBReadCoilsSlot1.bError THEN iStep:=30; END_IF IF FB_MBReadCoilsSlot1.bError THEN iStep:=999; END_IF 30: FB_MBWriteRegsSlot2(bExecute:=TRUE); F_TRIG_Slots[2](CLK:=FB_MBWriteRegsSlot2.bBusy); IF F_TRIG_Slots[2].Q AND NOT FB_MBWriteRegsSlot2.bError THEN iStep:=40; END_IF IF FB_MBWriteRegsSlot2.bError THEN iStep:=999; END_IF 40: FB_MBWriteRegsSlot3(bExecute:=TRUE); F_TRIG_Slots[3](CLK:=FB_MBWriteRegsSlot3.bBusy); IF F_TRIG_Slots[3].Q AND NOT FB_MBWriteRegsSlot3.bError THEN iStep:=50; END_IF IF FB_MBWriteRegsSlot3.bError THEN iStep:=999; END_IF 50: FB_MBReadRegsSlot4(bExecute:=TRUE); F_TRIG_Slots[4](CLK:=FB_MBReadRegsSlot4.bBusy); IF F_TRIG_Slots[4].Q AND NOT FB_MBReadRegsSlot4.bError THEN iStep:=10; END_IF IF FB_MBReadRegsSlot4.bError THEN iStep:=999; END_IF 999: IF bReset THEN iStep:=10; bReset:=FALSE; END_IF END_CASE |
Visualization
プロジェクトにも簡単なHMI Displayを作成し各Slotの現在値を一覧できます。そして出力モジュールの与えを変更することも可能です。
Result
下記のYoutube Linkから結果を確認できます。
Source Code
このLinkからSource CodeをDownloadしてください。
https://github.com/soup01Threes/TwinCAT3/blob/main/Wago750_362_TwinCAT%20Project_ModbusTCP.tnzip
Implementation-2 with Ctrlx
Implementation2ではCtrlx Virtual CoreとModbus TCP/IP Appsを使用し、Wago Modbus TCP Coupler 750-362の通信を確立させます。
Reference Link
MODBUS TCP APP?
ModbusはFactory Automationではものすごく一般的な通信ProtocolでMaster/Slaveのモデルでデータ交換し、そのデータはTCP/IP Packagesで流れています。
その中に、Modbus TCP AppはCtrlx Coreと他のModbus-TCP Slaveデバイス(今回の記事ではWago 750-362)をアクセスだけではなく、Real-time layer経由でPLC Runtimeとデータ交換できます。
Modbus TCP App Installation
こちらのLinkから最新VersionのModbus TCP AppをDownloadできます。
RuntimeのWBMにアクセスし、Service Modeに切り替えます。
Press Continueで進みます。
Settings>Appsで開きます。
Install from fileでModbus TCP Appをインストールします。
Installで始めます。
暫く待ちます…
Done!
左のMenuにModbus TCP が追加されました。
Port Configuration
Virtual Coreは仮想環境で稼働していますのでPort Forwarding の設定が必要になります。Extended tab>Port forwardingを選択します。
こちらは自分のPort Forward設定です。
8022:22,8443:443,8740:11740,4840:4840,2069:2069,2070:2070
Virtual CoreのWBMを開き、Setting>Network Interfaceを開きます。
Eth0を選び、Enable IP forwardingをONにします。
Connection Test
実際CtrlXとWago750-362 Couplerと接続する前に、前PFC200 ControllerでセットアップしたModbus TCP ServerとConnection Testを行います。
Reference Link
Configure the Modbus TCP Devices
”Add Modbus TCP Device”で新しいModbus TCP Slave デバイスを追加します。
Add Deviceの画面が表示されました。
Name
Name FieldはModbus Slave名で、今回はPF200を入力します。
IP Address
IP AddressはModbus SlaveのIPになります。今回は192.168.3.17です。
Port
Port Numberは接続先のModbus Slaveデバイス Port番号でDefaultは502です。
Unit Id
Unit IDはDefaultのままでよいと思います。
セットアップが終わりSaveしたら、新しいModbus TCP Slaveが追加されました。
Add Modbus TCP Register
次はアクセスするRegisterを+Buttonから追加します。
Subscription Screenが表示されました。
Name
NameはそのSubscription名になり、Devices1を入力します。
Function Code
Function CodeはModbus のアクセス方法で、FC/FC4/FC16/FC23は使用可能です。
Register Configuration
FC16を選択します。
Data Type
Data TypeはアクセスするRegisterのData Typeになり、今回はUint16です。
uint16/uint32/int16/float/stringは使用できます。
Register address
アクセスするRegisterの先頭番号になります。
いまはFC16,Register 32008からUnit16のデータにアクセスすると設定されました。
Quantity
次はアクセスするRegisterの数を設定します。今回はQuantity=1になります。
いまはFC16,Register 32008で1つのUnit16データにアクセスすると設定されました。
Poll interal(ms)
Polling Timeは通信のCycle Timeになります。
いまはFC16,Register 32008で1つのUnit16データに100msの周期でアクセスすると設定されました。
Save Buttonをクリックし設定を適用します。Connectionが確立されたらStatus=Activeに変わります。
同じ操作でFC4のアクセス操作を追加します。
Result
FC16から直接Register値を変更でき、FC4から同じRegisterを読み込んでるので直ちに反映されます。接続問題なさそうですね。
Connect to 750-362 Wago Coupler
今度はCtrlX Virtual CoreとWago Coupler 750-362に接続設定を行います。
Apps Side
こちらは最終のConfigurationですが、ここで一つずつ説明いたします。
Slot1 750-1417
Slot1 750-1417 8チャネルデジタル入力ではFC1を使用し、Register Address0、Quantity=8でAddress0から8つのCoilにアクセスします。
Slot2 750-1516
Slot2 750-1516 8チャネルデジタル出力ではFC16を使用し、Register Address520、Quantity=1でAddress520から8つのRegisterlにアクセスします。
Slot3 750-597
Slot3 750-597 8チャネルアナログ出力ではFC16を使用し、Register Address512、Quantity=8でAddress512から8つのRegisterlにアクセスします。
Slot4 750-471
Slot4 750-471 4チャネルアナログ入力ではFC23を使用し、Register Address0、Quantity=4でAddress0から4つのRegisterlにアクセスします。
ctrlX PLC Side
Ctrlx VBMから直接Modbus Registerのデータ読み書きできますが、これは私たちのMain Taskではありません。次はData Layer経由でModbus TCP AppsをCtrlx PLC Run Timeに取り込む方法を紹介します。
DataLayer_Realtime configuration
Ctrlx PLC Engineeringを開き、DataLayer_RealTime Objectを開きます。
Refresh Buttonで情報を更新します。
Available read-time data of the Data Layer fieldでは、アクセスできるNodesが一覧できます。
Insert all data again
DataLayer_Realtime右クリック>Install all data from ctrlX CORE againでDataLayerからすべてのNodeをPLC Runtimeに取り込みます。
Modbus TCP Client AppsのNodeがRuntimeにインストールされました。
Online from ctrlX CORE
もちろん、Node Listから直接アプリケーションに必要なNodeだけをImportすることもできます。DataLayer_Realtime>右クリック>Online from ctrlX COREします。
Edit Screenが表示されました。
インストールしたいTopicsを選択します。
今回の記事ではModbus TCP AppsにあるNodeを全部インストールします。
このButtonをクリックし設定を転送します。
Done!
DUT
DUT_8BitChannel
こちらは8 Bitチャンネルのために定義したDUTです。
TYPE DUT_8BitChannel : STRUCT Ch0,Ch1,Ch2,Ch3,Ch4,Ch5,Ch6,Ch7:BIT; END_STRUCT END_TYPE |
GVL
GVLを作成します。
{attribute ‘qualified_only’} VAR_GLOBAL Slot1:DUT_8BitChannel; Slot2:WORD; Slot3:ARRAY[0..7]OF WORD; Slot4:ARRAY[0..3]OF WORD; END_VAR |
Mapping
Codesysの操作と同じくGVLの変数とDataLayerの変数を繋がりましょう。
例えば、Slot1のInput0にある…Buttonをクリックします。
Text SearchのTabを開いて紐つけたい変数名を検索しましょう。
Done!
MAIN
最後は簡単なプログラムを作成します。
PROGRAM PLC_PRG VAR Slot1:DUT_8BitChannel; Slot2:WORD; Slot3:ARRAY[0..7]OF WORD; Slot4:ARRAY[0..3]OF WORD; END_VAR Slot1:=GVL_ModbusData.Slot1; GVL_ModbusData.Slot2:=Slot2; GVL_ModbusData.Slot3:=Slot3; Slot4:=GVL_ModbusData.Slot4; |
Result
プロジェクトをRuntimeにLoginしたら、Data LayerにあるItemはすべて緑になります。
CtrlxからWago Modbus TCP Coupler 750-362の各Slotのデータ制御もできました。