This function will send a package to a device on a MODBUS connection.
Input:
net_id : INT
The ID of the MODBUS connection.
unit_id : INT
The address of the device on the MODBUS connection to receive the data.
Note: if the MODBUS connection is opened in slave mode, this parameter is ignored.
ip : DINT
The IP address of the receiving device. This parameter is only used by MODBUS TCP connections.
Note: if the MODBUS connection is opened in slave mode, this parameter is ignored.
port : DINT (default 502)
The IP port of the receiving device. This parameter is only used by MODBUS TCP connections.
Note: if the MODBUS connection is opened in slave mode, this parameter is ignored.
iface : SINT (default 2)
The network interface to use. 1 = Mobile network, 2 = LAN network, etc. (See Network)
This parameter is only used on NX32L devices for MODBUS TCP connections.
Note: if the MODBUS connection is opened in slave mode, this parameter is ignored.
tid : DINT
The transaction ID of the package. This parameter is only used by MODBUS TCP connections.
frame : PTR
Address of the buffer that contains the package to send.
size : INT (1..253)
Number of bytes to send from the buffer.
Returns: INT
0
|
- Success.
|
-1
|
- Illegal MODBUS connection ID.
|
-2
|
- The size is too large.
|
-3
|
- No data to send.
|
-4
|
- MODBUS connection is busy.
|
-5
|
- Illegal IP parameters. (MODBUS TCP only)
|
-6
|
- TCP communication error. (MODBUS TCP only)
|
Declaration:
FUNCTION modbusSend;
VAR_INPUT
net_id : INT;
unit_id : INT;
frame : PTR;
size : INT;
ip : DINT;
port : DINT;
iface : SINT;
tid : DINT;
END_VAR;
Example:
INCLUDE rtcu.inc
VAR
mbNet : INT;
mbRcv : modbusReceive;
END_VAR;
FUNCTION setINT;
VAR_INPUT
adr : PTR;
v : INT;
END_VAR;
memcpy(dst := adr + 1, src := ADDR(v) , len := 1);
memcpy(dst := adr , src := ADDR(v) + 1, len := 1);
END_FUNCTION;
FUNCTION_BLOCK modbusReadDiscreteInputs;
VAR_INPUT
net_id : INT;
unit_id : INT;
index : INT;
length : INT;
END_VAR;
VAR_OUTPUT
status : INT;
size : INT;
input : ARRAY[1..32] OF BOOL;
END_VAR;
VAR
rc, i : INT;
buf : ARRAY[1..253] OF SINT;
mask : SINT;
END_VAR;
IF length < 1 OR length > 32 THEN
status := 1;
RETURN;
END_IF;
IF index < 1 THEN
status := 2;
RETURN;
END_IF;
buf[1] := 16#02;
setINT(adr := ADDR(buf[2]), v := index - 1);
setINT(adr := ADDR(buf[4]), v := length);
rc := modbusSend(net_id := net_id, unit_id := unit_id, frame := ADDR(buf), size := 5);
IF rc <> 0 THEN
status := 3;
RETURN;
END_IF;
IF NOT modbusWaitData(net_id := net_id, timeout := 5000) THEN
status := 4;
RETURN;
END_IF;
mbRcv(net_id := net_id, frame := ADDR(buf), maxsize := SIZEOF(buf));
IF mbRcv.status <> 0 THEN
status := 5;
RETURN;
END_IF;
IF mbRcv.unit_id <> unit_id THEN
status := 6;
RETURN;
END_IF;
IF buf[1] <> 16#02 THEN
status := 7;
RETURN;
END_IF;
mask := 1;
FOR i := 1 TO length DO
input[i] := BOOL(buf[3 + ((i - 1) / 8)] AND mask);
mask := shl8(in := mask, n := 1);
IF mask = 0 THEN mask := 1; END_IF;
END_FOR;
size := length;
status := 0;
END_FUNCTION_BLOCK;
PROGRAM ModbusExample;
VAR
dinRead : modbusReadDiscreteInputs;
linsec : DINT;
i : INT;
END_VAR;
DebugMsg(message := "Initializing...");
mbNet := modbusOpen(port := 2, baud := 19200, parity := 0, mode := 0);
DebugFmt(message := "modbus...\1", v1 := mbNet);
BEGIN
IF clockNow() > linsec THEN
DebugMsg(message := "------------------------------");
DebugMsg(message := "Reading inputs:");
dinRead(net_id := mbNet, unit_id := 9, index := 1, length := 4);
DebugFmt(message := "-status=\1", v1 := dinRead.status);
IF dinRead.status = 0 THEN
FOR i := 1 TO dinRead.size DO
DebugFmt(message := "-input[\1]=\2", v1 := i, v2 := INT(dinRead.input[i]));
END_FOR;
END_IF;
linsec := clockNow() + 5;
END_IF;
END;
END_PROGRAM;
|