今回はSiemensのPLCでModbus TCP serverを使うときの手順を説明します。
ここにも文章が乗っています↓。
http://soup01.com/ja/2019/12/24/post-1948/
TIAバージョン
実機バージョン
Function Block
ではまずF1でHelpをみましょう。
このMB_SERVER命令はModbus TCP serverとして動作しProfinet接続に通じてModbus TCP Clientと接続、送信、通信とModbusリクエストを処理することができます。
##S7-1200
- FirmwareV4.0ではこの命令のバージョンV3.1まで使えます。
- FirmwareV4.1ではこの命令バージョン全て使えます。
S7-1500
- この命令バージョン全て使えます。
!注意
セキュリティ上ではModbus ClientはModbus holding register上のメモリエリア全て読み書きすることができます。なので、ServerにアクセスできるClientのIPアドレスは制限するのはおすすめです。
##INPUT
- DISCONNECT:Bool
- 0:Passive Connectionが確立する。
- 1:Connectionは“TCON_IP_v4”に元にいて設定初期化する。初期化成功したらSTATUSは3にアウトプットされます。
##InOut
-
MB_HOLD_REG:Variant
- Siemensを使っている人にもVariantに対してわけわからない人も多いと思いますが、私いつも“なんでもあり”ということを説明します。つまり、この変数は結局単なるBoolでもいいし、構造体でもいいし、配列でもいいし、なんでも変数として扱えるってことです。
このFunctionのVariantほしいのはMemory Areaです。Modbus サーパーとして働いてるから当然Clientから読み書きしたいMemory Areaがあります。例えばParameterなど… - 注意:
- Memory Area最低2Byteにしましょう。
- アクセスできるのはModbus Function 3(よみ)、6(書き)、16(マルチ書き)と23(一つJobでマルチ書き)だけになります。
- Siemensを使っている人にもVariantに対してわけわからない人も多いと思いますが、私いつも“なんでもあり”ということを説明します。つまり、この変数は結局単なるBoolでもいいし、構造体でもいいし、配列でもいいし、なんでも変数として扱えるってことです。
-
CONNECT:Variant
- このCONNECTパラメータ使えいるのSDT(System Data Type)は二種類があります。
- TCON_IP_V4
- 通信成立するため必要なネットワークパラメータが含められてる。Defaultアドレスは0.0.0.0です。もちろんプログラム上で変更することが可能です。このSDTを使うと、通信成立するには“MB_SERVER”が呼びされてるときです。
- TCON_Configured
- アドレスパラメータのみが入っています。もしこのSDTを使うと、通信成立するにはCPUがハードウェア構成をダウンロードされたあとになります。
- TCON_IP_V4
- このCONNECTパラメータ使えいるのSDT(System Data Type)は二種類があります。
##Output
- NDR
- “New Data Ready”
- 0:新しいデータが来てません。
- 1:新しいデータが来ています(つまりClientから書き込みあります)。
- “New Data Ready”
- DR
- “Data Read”
- 0:データが読み込まれいません。
- 1:データがClientに読み込まれいます。
- “Data Read”
- ERROR
- MB_SERVERが実行してるときにエーラがあれば1になります。STATUSにはそのエラーコードが帰っています。
- STATUS
- MB_SERVERの実行状態が見えます。
##TCON_IP_V4とは?
まずData Typeのところに“TCON_IP_v4”を入れれば、自動的変数が作られいます。
- InterfaceId
- ID
- 1個目のMB_SERVERはIDを1にしましょう。もし一台のCPUの中に複数のMB_SERVERがあればこのIDをかぶれないようにしましょう。
- ConnectionType
- 11はTCP/IP、19はUDP
- ActiveEstablished
- いわゆるActiveかPassiveですね。今回はPassiveにします。
- RemoteAddress
- 長さ4のByte配列です。ここで接続しようとするClientのIPを設定できます。0.0.0.0ならどこのClientでも接続できます。
- RemotePort
- 相手のPortです。もしClientに特にPortのアクセス制限がなければ0にいいでしょう 。
- LocalPort
- 自分のPortで接続されたClientと通信を監視するPortになります。
これで、パラメータある程度把握できましたね。
##実装
これは私のやりかたですが、こういう構造体(Variant)が必要されるとき、もしパラメータそんなに多くなければいつも細かくばらします。つまりこうですね。これは私が作ったClass_ModbusServerのFunction Blockです。
Inputのところが多いと思われますが、よくみたら単なるTCON_IP_V4とMB_SERVERの変数だけです。そしてOutputはMB_SERVERの出力だけですね。
注意するのはioMB_HOLD_REGですね。ここに入れるのはP#DB3.DBX0.0です。このDB中には51のIntが入っています。
###Input Interface
###Output Interface
####Network3-10
パラメータをCONNECT変数に転送するだけです。
####Network11
MB_SERVERを呼び出します。先Network3-10まで転送した変数CONNECTをこおで使えいます。
####Network13
DISCONNECT=1はつまりパラメータ初期化すること。ここで読み書きのCounterをリセットします。
####Netowork14
まぁ、Clientにデータを読まれたら+1するだけです。
####Network15
まぁ、Clientがデータを書き込んでたときを+1するだけです。
####Network17-20
MB_SERVERの実行状態を出力するだけです。
お疲れ様です!と言いたいですが、せっかくですからここでPythonを使ってModbus TCP Clientを作ってアクセスしてみよう。
#PythonでModbus TCP/IPクライアント
##実装
#Library Import
from pyModbusTCP.client import ModbusClient
import time
import random
#Host,Port Settings
SERVER_HOST='192.168.0.17'
SERVER_PORT=502
#Client
client=ModbusClient()
#Debug
client.debug(False)
#Config
client.host(SERVER_HOST)
client.port(SERVER_PORT)
#Connect
client.open()
#Read and Write
while True:
if not client.is_open():
if not client.open():
print('Can not connect to {},{}'.format(SERVER_HOST,SERVER_PORT))
if client.is_open():
regs=client.read_holding_registers(0,10)
if regs:
print('data:'+str(regs))
else:
print('can not read.')
reg_list=[random.randint(1,32000) for i in range(10)]
regs=client.write_multiple_registers(0,reg_list)
if regs:
print('data is sent.')
else:
print('data can not sent')
time.sleep(0.02)
#Disconnect
client.close()
ではーお疲れ様です!