We continue the topic of programming the Modbus TCP protocol on Simatic S7-1500 controllers. Last time we talked about the server side, today we will describe the client side. A Modbus TCP client is a node that generates requests to the server, i.e. requests data and transmits setpoints / commands. In Modbus RTU terminology, this is a "master", a master device. Unlike RTU, TCP can have several "masters" (correctly - clients).
Client-side programming is more difficult. While one function block call and one data block are enough for the server, things are not so simple with the client. First, a client can communicate with multiple servers, which is what actually happens in practice. Secondly, there can (and does) more than one request to one server - to read input registers, read storage registers, write commands to output "coils", and all this with one "subscriber device". Thirdly, do not forget about the "pointed" and "blunt" byte order in words of different hardware platforms; if there is a mismatch, the bytes must be flipped independently.
For this reason, it makes sense to program the client in SCL (ST in IEC 61131-3 terminology) and wrap all processing in a function block. For realism, in this example, the controller will communicate with two Modbus TCP servers with multiple requests to each.
First of all, let's create a ModbusClient function block in the SCL language and add a call to its instance in OB1.
Further, in the STAT area of the variables of the function block, it is necessary to register two structures TCON_IP_v4. Why two? Because we have two connections to two different servers. In fact, we have two different connections and each needs to be described. As I said earlier, it is possible to use configurable connections, but they are not used in this example.
Two structures are declared to communicate with two servers
. , . .
, InterfaceId. ( « ») . Modbus №1 , ID .
ID 64. , , .
, ID. . . «» -. « » , 1 4096. «» . . ID = 1 .
, ConnectionType — TCP UDP. 0x0B hex 11 dec. , TCP.
ActiveEstablished. «». .
RemoteAddress. IP- . 192.168.43.100.
RemotePort. , Modbus TCP . «» 502.
LocalPort. .
, .
. , ID IP . .
. MB_CLIENT .
. - .
« »
. — 0 , , -, .
REQ . REQ = TRUE, .
DISCONNECT —
MB_MODE — «» . MB_DATA_ADDR Modbus TCP. . MODE 0.
MB_DATA_ADDR Modbus TCP. 40001 — « »
MB_DATA_LEN — . — . « 40001»
MB_DATA_PTR — , . , SingleHR INT, 2 Modbus. «» .
CONNECT — TCON_IP_V4
Modbus, , … . . . . . — , , … ( « » ). , , .
, (DONE) (ERROR) «» . , . . — .
, «» .
, . 80C6. MB_CLIENT , TCON ( TSEND, TRECEIVE ). : The connection partner cannot be reached (network error). . , - Modbus Windows Firewall. , , . , , . .
, . (REAL) — 4 . 2 . , 2, «» . — REAL ( ).
. , ModbusClient , Modbus, , 80A3. , , (- ). /. ( ), :
/ «» Srv1Req . «» ( , ) «» Srv1Disconnect, ( , .. , ), , . , REQ DISCONNECT , , , .
, «» (little-endian big-endian) . modbus 0.666. Modbus 1.663175E+38, (, , ). , , . . .
SWAP ( — ). , ( Data.Test) . , , «» , «», «». , 4 — .
, . 4 4 , .
Deserialize «» - , — . , Modbus.
, , , Modbus TCP, — () (). Modbus RTU «» . , , , . Unit ID, Device ID, — , , . Modbus TCP « » IP-. , Device ID . , . , «» Modbus TCP ID . Unit ID , Modbus RTU Modbus TCP (, , ). Modbus Unit ID. «» , , . , Modbus MB_Unit_ID. «» , .. Modbus. 0xFF 255. «» , TCP/IP. «», Unit ID . .
, , , , .. .
, . 3 (6 ), 40001, ( 40011). , «». ( «» ) . , , « » , ( Deserialize, ), . «» . Data , REAL.
, Data «» «», , — 818B.
, , «» .
, .
0.5, 0.7, 0.33 () « »
— ( ). , . , — . — , . « » ( « », ).
.
, , Server1Query ( Server2Query). CASE. « » .
, , . , , ( MODBUS_CLIENT) / .
With the second server, we have a separate connection configured, there is a separate instance of the modbus functional block. We can call it "simultaneously" with the communications of the first server, so the general program has two CASE statements that work independently of each other.
In principle, it would be logical to add an analysis of the response to a specific request and the formation of a sign of data reliability, and make some other improvements. For example - sending commands and settings is not compulsory, but only by change.
Nevertheless, this is where I finish the description of working with the Modbus TCP protocol. Next time, let's look at programming the Modbus RTU protocol.