こちらの記事ではPilz CPUでModbus TCP/IP Serverを立ち上げ、Omron NX CPUからModbus TCP Clientのプログラムを組んでアクセスします。Omron のManualはほぼSTで自分も最初にSTで書こうと思いますが、あえてラダーを書いてみました。よろしくおねがいします。
Thanks!
この記事が出来上がったのはオムロン株式会社さまとPilz Japan.さまから機材を貸してくださったおかけです。誠にありがとうございます。
オムロン株式会社
オムロン株式会社は、オートメーションのリーディングカンパニーとして、工場の自動化を中心とした制御機器、電子部品、駅の自動改札機や太陽光発電用パワーコンディショナーなどの社会システム、ヘルスケアなど多岐にわたる事業を展開し、約120の国と地域で商品・サービスを提供しています。
こちらはオムロン株式会社のホームページです。
どうぞよろしくお願いします。
PILZ
PILZは安全およびオートメーション技術のソリューションでトータルソリューションサプライヤとしてのFA現場を支え、人の安全だけではなく、機械、および環境の安全を保証し、機械や設備をいかに安全に稼働させます。ピルツは全世界に42の現地法人や支社を設置し、包装、自動車産業、ロボットアプリケーション、さらに風力発電、鉄道技術など様々な分野で活躍しています。
Office:
ピルツジャパン株式会社
〒222-0033
横浜市港北区新横浜3-17-5
いちご新横浜ビル 4階
HP
Reference Link
http://soup01.com/ja/category/omron%e3%82%aa%e3%83%a0%e3%83%ad%e3%83%b3/
http://soup01.com/ja/category/pilz/
Pilz
IP Connections?
PSS4000システムでは、IP Connectionsを使用することにより、CPUと3rd Partyデバイス間でModbus TCP/Raw TCP/Raw UDPで通信可能になります。PSS4000システムの視点からみるとそれらのConnectionは全て外部通信です。
Max Number of IP connections?
PSS4000システムの最大IP Connections数はツールから設定できますが、32を超えることができません。ですが、SafetyNet p ConnectionsはIP Connectionsに管理されていませんので、Connections数とて計算されません。
IP Connections Name?
プロジェクト内のIP Connectionsの名前は必ず重複しないようにしてください。
Local Port Number?
プロジェクト内のIP Connectionsで使用するLocal Port(CPU本体)も必ず重複しないようにしてください。CPUでは1つのPortと1つのIP Connectionは1対1の関係で、Raw TCP/UDPを使用するとき該当するPortはすでに別のSerivcesに占有されたかを確認しておきましょう。(そしてRaw TCP/UDP Servicesで使用できるPort番号は1024から5000まで、UDPは49152から65535までになります)
Modbus TCP
Data Area(Server)
こちらはPSS4000 システム Modbus TCP Server SideのData Areaになります。注意するのはPSS4000は0からスタートですが、メーカーにより1からスタートの場合もございますので、注意してください。
Data Area | Modbus Synatax | R/W | Range | Example |
Coils(Bit) | 0x[xxxxx] | Read/Write可能 | 0x00000から0x65535まで | 0x01234 |
Discrete Inputs(Bit) | 1x[xxxxx] | Readのみ | 0x00000から0x65535まで | 1×5123 |
Input Register(Word 16 bit) | 3x[xxxxx] | Readのみ | 0x00000から0x65535まで | 3×0111 |
Holding Register(Word 16 bit) | 4x[xxxxx] | Read/Write可能 | 0x00000から0x65535まで | 4×1234 |
Function Codes
こちらはClient側PSS4000のModbus TCP Serverデータにアクセスする際、使用するFunction Codeです。
Data Area | Data Length | FC(Writing From Client) | FC (Reading From Client) |
0x[xxxxx] Coils | =1Bit | FC=05(Write Single Coil) | FC=01(Read Coil,Range:1-2000) |
0x[xxxxx] Coils | >1Bit | FC=15(Write Multiple Coils,1-1968) | FC=01(Read Coil,Range:1-2000) |
1x[xxxxx]Discrete Input | >=1Bit | – | FC=02(Read Discrete Input,Range:1-2000) |
3x[xxxxx]Read Input Register | >=1Word | – | FC=04(Read Input RegisterRange:1-125) |
4x[xxxxx]Read Holding Register | =1Word | FC=06(Write Single RegisterRange:1-123) | FC=03(Read Holding RegisterRange:1-125) |
4x[xxxxx]Read Holding Register | >1 Word | FC=16(Write Multiple RegisterRange:1-123) | FC=03(Read Holding RegisterRange:1-125) |
Implementation
Pilz Side
PAS4000を起動し、Hardware ConfigurationからIP Connectionsをクリックします。
Connectionsの設定画面が表示されています。
New Modbus/TCP Server
”New Modbus/TCP Server”をクリックしPilz CPUから新しいModbus/TCP Serverを構築します。
Done!Severが作成され、Registerの設定画面が見えました。
Server
Network Settings
Connection name
そのIP Connectionsの名前です。
Local Port Number
Range:1-65535、Defaultは502です。Modbus TCP Clientを構築する際は、このPort番号に合わせてください。
Remote IP address
Defaultは0.0.0.0です。接続可能なModbus TCP Client IPです。0.0.0.0であればすべてのIPも接続可能です。
Remote Port number
Range:0-65535、Defaultは0です。接続可能なModbus TCP Client Port番号です。0であればすべてのPortも接続可能です。
Keep alive settings
Enable keep alive
Check=Keep Aliveします。
Keep alive time[ms]
ServerとClientの間でデータTrafficがないとき、最大のKeep Alive時間です。
Keep alive interval[ms]
ServerとClientの間の最大のKeep Alive メッセージ待ち時間です。
Connecton timeout
PSS4000システムはClientからMonitor時間内で返答がこない場合、Timeoutとして検知できます。計算は:Timeout=(Number of Connection cycles)*(Connection cycle time)
Enable Connection Timeout
CheckするとTimeoutを監視します。
Connection Cycle
Timeout検知するためのConnection cycle数。
Server Allocation Table
PSS4000システムの各Allocatonのサイズ・Start Addressを設定できます。
Program
PROGRAM POU_2 VAR ModbusCoil00_Read AT %i*:ARRAY[0..99]OF BOOL; ModbusCoil00_Write AT %Q*:ARRAY[0..99]OF BOOL; ModbusCoil01_Write AT %Q*:ARRAY[0..99]OF BOOL; ModbusRegister03_Write AT %Q*:ARRAY[0..99]OF WORD; ModbusRegister04_Write AT %Q*:ARRAY[0..99]OF WORD; ModbusRegister04_Read AT %I*:ARRAY[0..99]OF WORD; b1,b2:BOOL; w1,w2:WORD; END_VAR //Read Coils Function Code01 ModbusCoil00_Write[0]:=TRUE; ModbusCoil00_Write[99]:=TRUE; //Read Discrete Inputs Code02 ModbusCoil01_Write[1]:=TRUE; ModbusCoil01_Write[98]:=TRUE; //Write Multiple Coils Code15 b1:=ModbusCoil00_Read[0]; b2:=ModbusCoil00_Read[99]; // w1:=ModbusRegister04_Read[0]; w2:=ModbusRegister04_Read[99]; //Read Input Register Code04 ModbusRegister03_Write[0]:=WORD#99; ModbusRegister03_Write[99]:=WORD#123; //Read Holding Register Code 03 ModbusRegister04_Write[0]:=WORD#56; ModbusRegister04_Write[99]:=WORD#912; END_PROGRAM |
Mapping
プログラム準備が終わったら次はI/O Mappingを行います。
IP ConnectionsでModbus TCP Serverの各Registerが表示されるはずです。
しっかり間違えないようにMappingをしましょう。
Omron Side
こちらは自分が使用するSysmac Studio Versionです。
VAR
次はOmron NX CPUでEthernet通信を使用するとき必要な変数を紹介します。
_EIP_EthXXOnlineSta
Variable Name | Type | Description |
_EIP_EthOnlineSta | BOOL | True=NX CPU 内蔵のEthernet/IP Portが使用可能になります。 |
_EIP1_EthOnlineSta | BOOL | True=NX CPU 内蔵のEthernet/IP Port1使用可能が使用可能になります。 |
_EIP2_EthOnlineSta | BOOL | True=NX CPU 内蔵のEthernet/IP Port2使用可能が使用可能になります。 |
_EIPIn1_EthOnlineSta | BOOL | True=NY CPU 内蔵のEthernet/IP Port1使用可能が使用可能になります。 |
Socket
Variable Name | Type | Description |
Handle | UDINT | 0=すべでのTCP接続をCloseします。 |
SrcAdr | _sSOCKET_ADDRESS | NX CPUのLocal IPとPort番号 |
DstAdr | _sSOCKET_ADDRESS | Remote ServerのIPとPort番号 |
_sSOCKET_ADDRESS
Variable Name | Type | Description |
PortNo | UINT | Port番号 |
IpAdr | String | IPアドレス |
_eMDB_FUN
Enum Name | Range | Data Type |
_MDB_READ_COILS | Read Outputs(Bit,1-2000) | Bool/Bool配列 |
_MDB_READ_DISCRETE_INPUTS | Read Inputs(Bit,1-2000) | Bool/Bool配列 |
_MDB_READ_HOLDING_REGISTERS | Read Holding Register(Word,1-125) | Word/Word配列 |
_MDB__READ_INPUT_REGISTERS | Read Input Register(Word,1-125) | Word/Word配列 |
_MDB_WRITE_SINGLE_COIL | Write Single Coils(Bit,1) | Bool/Bool配列 |
_MDB_WRITE_SINGLE_REGISTER | Write Holding Register(Word,1) | Word/Word配列 |
_MDB_WRITE_MULTIPLE_COILS | Write multiple outputs (Bit,1968) | Bool/Bool配列 |
_MDB_WRITE_MULTIPLE_REGISTERS | Write multiple holding registers (Word,123) | Word/Word配列 |
Function Block
SktTCPConnect
こちらのFunction Blockを使用しOmron CPUからRemote Serverに接続リクエストを送信できます。接続が成功した場合Done=Trueになります。
VAR_INPUT
Variable Name | Type | Description |
SrcTcpPort | Bool | Local(Omron CPU)のPortを指定します。0=1024以上の使用可能なPortを自動的に使います。Default=0です。 |
DstAdr | String | 最大200Bytesの文字列でRemote ServerのIPアドレスを指定できます。 |
DstTcpPort | UINT | Remote Serverの接続Port番号(1-65535まで) |
VAR_OUTPUT
Variable Name | Type | Description |
Done | Bool | FB実行成功 |
Busy | Bool | FB実行中 |
Error | Bool | FBがエラーあり |
ErrorID | WORD | FBのエラー情報 |
Socket | _sSOCKET | Socket変数 |
SktClose
こちらのFunction Blockを使用しNX CPUとRemote ServerのSocket接続を切断できます。実行が成功した場合Done=Trueになります。
VAR_INPUT
Variable Name | Type | Description |
Execute | Bool | 立ち上げて実行する |
Socket | Socket | SktTCPConnectから取得したSocket変数 |
VAR_OUTPUT
Variable Name | Type | Description |
Done | Bool | FB実行成功 |
Busy | Bool | FB実行中 |
Error | Bool | FBがエラーあり |
ErrorID | WORD | FBのエラー情報 |
SktSetOption
こちらのFunction Blockを使用するとSocket通信のOptionsを設定できます。
Done=FB実行成功、Error=FB実行エラーあり。
VAR_INPUT
Variable Name | Type | Description |
Execute | Bool | 立ち上げて実行する |
Socket | Socket | SktTCPConnectから取得したSocket変数 |
OptionType | _sSKT_OPTION_TYPE | SocketのOption Type |
OptionParam | BOOL | True=NO Delayを有効する(Nagle アルゴリズムを無効) |
VAR_OUTPUT
Variable Name | Type | Description |
Done | Bool | FB実行成功 |
Busy | Bool | FB実行中 |
Error | Bool | FBがエラーあり |
ErrorID | WORD | FBのエラー情報 |
ModbusTCPRead
こちらのFunction Blockを使用すると確立されたConnectionから”Read”コマンドをRemote Modbus TCP Serverに送信することができます。読込されたデータサイズは”ReadSize”パラメータに格納され、読込されたデータはReadDatに割り付けられたパラメータに格納されます。(もしエラーが発生したらReadDatとReadSizeはわからないままになるので、該当するFBを実行する前にそれらのパラメータをリセットしたほうよいと思います)
VAR_INPUT
Variable Name | Type | Description |
Execute | Bool | 立ち上げて実行する |
Socket | Socket | SktTCPConnectから取得したSocket変数 |
UnitIdentifier | USINT | Unit ID Default=255 |
ReadCmd | _sMODBUS_READ | Modbus Function Code・サイズ・Start アドレス |
TimeOut | Time | Timeout時間(0.1s単位)を設定する、Defalt=2s(20) |
VAR_OUTPUT
Variable Name | Type | Description |
Done | Bool | FB実行成功 |
Busy | Bool | FB実行中 |
Error | Bool | FBがエラーあり |
ErrorID | WORD | FBのエラー情報 |
ErrorIDEx | DWORD | FBのエラー情報2 |
ReadSize | UINT | 読みされた合計サイズBitの場合は1−2000(Bit単位で計算)Wordの場合は1−125(Word単位で計算) |
VAR_IN_OUT
Variable Name | Type | Description |
ReadDat | ANY | Modbus TCP ServerからRegisterを読み込まれたデータ |
TimeChart-Normal
TimeChart-Error
ModbusTCPWrite
こちらのFunction Blockを使用すると確立されたConnectionから”Write”コマンドをRemote Modbus TCP Serverに送信することができます。書き込むデータサイズは”WriteDat”パラメータに格納され、書き込むデータはWriteDatに割り付けられた変数から転送されます。
VAR_INPUT
Variable Name | Type | Description |
Execute | Bool | 立ち上げて実行する |
Socket | Socket | SktTCPConnectから取得したSocket変数 |
UnitIdentifier | USINT | Unit ID Default=255 |
WriteCmd | _sMODBUS_WRITE | Modbus Function Code・サイズ・Start アドレス |
TimeOut | Time | Timeout時間(0.1s単位)を設定する、Defalt=2s(20) |
VAR_OUTPUT
Variable Name | Type | Description |
Done | Bool | FB実行成功 |
Busy | Bool | FB実行中 |
Error | Bool | FBがエラーあり |
ErrorID | WORD | FBのエラー情報 |
ErrorIDEx | DWORD | FBのエラー情報2 |
VAR_IN_OUT
Variable Name | Type | Description |
WriteDat | ANY | Modbus TCP ServerにRegisterを書き込むデータ |
TimeChart-Normal
TimeChart-Error
Function
AryMove
こちらの関数を使用すると配列変数間のデータ転送ができます。転送元と転送先のData Typeは不一致でもOKです。
VAR_INPUT
Variable Name | Type | Description |
In | Bool | 転送元 |
VAR_OUTPUT
Variable Name | Type | Description |
Out | Bool | 常時True |
VAR_IN_OUT
Variable Name | Type | Description |
AryOut | ANY | 転送先 |
Clear
この関数を使用することによりInOutの変数を初期化します。該当する変数が初期値に設定された場合は初期値に戻りますが、なかった場合はDefault初期値になります。
Default Initial Value
以下は各データタイプのDefault初期値です。
VAR_INOUT
Variable Name | Type | Description |
InOut | ANY | 初期化する変数 |
VAR_OUT
Variable Name | Type | Description |
Out | Bool | 常時Trueの出力 |
NumToEnum
DINT変数をEnum変数に変換する関数です。
VAR_IN
Variable Name | Type | Description |
In | DINT |
VAR_OUT
Variable Name | Type | Description |
InOut | Enum | Enum変数 |
Configuration
NX CPUの内蔵Ethernet/IP Port設定を行います。
Configuration and Setup>Controller Setup>Build-in Ethernet/IP Port Settingsをします。
使用するPortのIPアドレスを設定しましょう。
DUT
Socket FBやModbus TCP FBのFlagとまとめて定義する構造体です。
Program
プログラムの流れです。
VAR
Variable | Type | Description |
_SktTCPConnect | SktTCPConnect | SktTCPConnectのInstance |
_SktTCPClose | SktClose | SktCloseのInstnace |
bExecute | BOOL | SktTCPConnect FBを実行する |
bClose | BOOL | SktClose FBを実行する |
Socket | _sSOCKET | Socket変数 |
_ModbusTCPRead | ModbusTCPRead | ModbusTCPReadのInstance |
bError | BOOL | |
ModbusReadDat | ARRAY[0..99] OF word | ModbusTCPRead FBで使用するRead Buffer(Word) |
ModbusWriteDat | ARRAY[0..99] OF word | ModbusTCPWrite FBで使用するWrite Buffer |
ModbusReadDataCoil | ARRAY[0..99] OF bool | ModbusTCPRead FBで使用するRead Buffer(Coil) |
ModbusWrite_16 | ARRAY[0..99] OF word | FC16で使用するWord配列 |
ModbusRead_03 | ARRAY[0..99] OF word | FC3で使用するWord配列 |
ModbusRead_04 | ARRAY[0..99] OF word | FC4で使用するWord配列 |
ModbusRead_01 | ARRAY[0..99] OF bool | FC1で使用するBool配列 |
ModbusRead_02 | ARRAY[0..99] OF bool | FC2で使用するBool配列 |
ModbusWrite_15 | ARRAY[0..99] OF bool | FC15で使用するBool配列 |
ReadCmd | _sMODBUS_READ | ModbusTCPReadのコマンド(サイズ・FCなど) |
bReads | ARRAY[0..15] OF bool | ModbusTCPReadを実行する |
iStep | INT | |
bWrites | ARRAY[0..15] OF bool | ModbusTCPWriteを実行する |
bStart | BOOL | プログラムスタートする |
R_TRIG1 | R_TRIG | 立ち上げ検知のInstance |
ModbusTCPReadStatus | DUT_ModbusTCPReadStatus | ModbusTCPRead(Word)FBのStatus |
ModbusTCPReadCoilStatus | DUT_ModbusTCPReadStatus | ModbusTCPRead(Coil)FBのStatus |
SktBasicStatus | DUT_srtBasic | SktTCPConnect FBのStatus |
SktCloseStatus | DUT_srtBasic | SktClose FBのStauts |
_SktSetOption | SktSetOption | SktSetOption FBのInstance |
SktSetOptionStatus | DUT_srtBasic | SktSetOptionの設定Option |
bSetOptions | BOOL | SktSetOption FBを実行する |
bOptionNoDelay | BOOL | |
TONs | ARRAY[0..15] OF ton | |
Dummy | BOOL | |
_ModbusTCPWriteRegister | ModbusTCPWrite | ModbusTCPWrite FBのInstance |
WriteCmd | _sMODBUS_WRITE | ModbusTCPWriteのコマンド(サイズ・FCなど) |
ModbusTCPWriteRegisterStatus | DUT_ModbusTCPReadStatus | ModbusTCPWrite(Word)FBのStatus |
ModbusWriteDatCoils | ARRAY[0..99] OF bool | ModbusTCPWriteで使用するBool配列 |
_ModbusTCPWriteCoils | ModbusTCPWrite | ModbusTCPWrite FBのInstance(Coils) |
ModbusTCPWriteCoilsStatus | DUT_ModbusTCPReadStatus | ModbusTCPWrite(Coil)FBのStatus |
Code
Rung0-1
- Rung0はbStartの立ち上げを待ち、bStartなおかつ現在EIP Portが使用可能であればR_TRIG1のClkがTriggerされます。
- Rung1がStartがトリガーされたらiStep=1になります。
Rung2-4
- Rung2はComment Listを表示しやすいように作ったDummy回路です。
- Rung3はiStep=1ならbExecuteがTrueになり、SktTCPConnect Function Blockを実行し、DoneがTrueなら実行成功ならiStep=5で、ErrorがTrueなら実行失敗でiStep=9000になります。
- Rung4はiStep=5ならbSetOptionsがTrueになり、SktSetOptions Function Blockを実行し、DoneがTrueなら実行成功ならiStep=10で、ErrorがTrueなら実行失敗でiStep=9000になります。
Rung5-7
- Rung5はiStep=10、つまりNX CPUとRemote Serverと接続に成功した状態です。ModbusTCP Serverに送信する前BufferをクリアしiStepを15にします。
- Rung6はModbusTCPReadのFunction BlockをトリガーするbRead[0]をTrue同時に、Modbus Function Code3、Register 0から100を取得するようにReadCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=20にいき、Error=True、つまりFB実行エラーありならiStep=9001になります。
- Rung7は次のModbusReadの準備のためBufferをクリアし、0.1sのDelay後にiStepを25にします。
Rung8-9
- Rung8はModbusTCPReadのFunction BlockをトリガーするbRead[1]をTrue同時に、Modbus Function Code4、Register 0から100を取得するようにReadCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=30にいき、Error=True、つまりFB実行エラーありならiStep=9006になります。
- Rung9は次のModbusReadの準備のためBufferをクリアし、0.1sのDelay後にiStepを35にします。
Rung10-11
- Rung10はModbusTCPReadのFunction BlockをトリガーするbRead[2]をTrue同時に、Modbus Function Code1、Coil 0から100を取得するようにReadCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=40にいき、Error=True、つまりFB実行エラーありならiStep=9006になります。
- Rung11は次のModbusReadの準備のためBufferをクリアし、0.1sのDelay後にiStepを45にします。
Rung12
- Rung12はModbusTCPReadのFunction BlockをトリガーするbRead[3]をTrue同時に、Modbus Function Code2、Coil 0から100を取得するようにReadCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=50にいき、Error=True、つまりFB実行エラーありならiStep=9006になります。
Rung13
- Rung13はModbusTCPWriteのFunction BlockをトリガーするbWrite[0]をTrue同時に、Modbus Function Code16、Register 0から100を書き込むようにWriteCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=60にいき、Error=True、つまりFB実行エラーありならiStep=9006になります。
Rung14
- Rung14はModbusTCPWriteのFunction BlockをトリガーするbWrite[0]をTrue同時に、Modbus Function Code15、Coil 0から100を書き込むようにWriteCmdに設定を転送します。もしDone=True、つまりFB実行成功であればiStep=400にいき、Error=True、つまりFB実行エラーありならiStep=9006になります。
Rung15-18
- Run15はiStep=400、Remote Serverの接続を切断します。Done=Trueなら実行成功でiStep=0でErrorなら実行失敗でiStep=9002にします。
- Rung16はComment Listを表示しやすいように作ったDummy回路です。
- Rung17はSktTCPConnectのFunction Blockを呼び出します。
- Rung18はSktSetOptionsのFunction Blockを呼び出します。
Rung 19-20
- Rung19はModbusTCPRead(Register用)のFunction Blockを呼び出します。
- Rung20はModbusTCPRead(Coils用)のFunction Blockを呼び出します。
Rung21-23
- Rung21はModbusTCPWrite(Register用)のFunction Blockを呼び出します。
- Rung22はModbusTCPWrite(Coils用)のFunction Blockを呼び出します。
- Rung23はSktCloseのFunction Blockを呼び出します。
Download
こちらのLinkからSample ProjectをDownloadしてください。
https://github.com/soup01Threes/OMRON/blob/main/ModbuTCP_Test_with_pilz.smc2