modbusWaitData (Function)

Top  Previous  Next

Architecture:

X32 / NX32 / NX32L

Device support:

All devices with RS485 or LAN

Firmware version:

1.50 / 1.00.00


This function will wait until a data package is received from a MODBUS connection - or for an optional timeout.

This function only indicates that the data is received. To actually read the data, modbusReceive must be used.

 

Note: waiting for a package by using this function will block the calling thread.

 

 

Input:

net_id : INT

The ID of the MODBUS connection.

 

timeout : INT (-1,0..32000) (default -1)

Timeout period in milliseconds to wait.

0

- Disable timeout. The function will return immediately.

-1

- Wait forever. The function will only return when data is received.

 

Returns: BOOL

TRUE:

If data is ready to be read.

FALSE:

If no data is present.

 

Declaration:

FUNCTION modbusWaitData : BOOL;
VAR_INPUT
  net_id : INT;
  timeout : INT := -1;
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;
 
  // Check length
  IF length < 1 OR length > 32 THEN
     status := 1;
    RETURN;
  END_IF;
  IF index < 1 THEN
     status := 2;
    RETURN;
  END_IF;
 
  // Build command
  buf[1] := 16#02;
  setINT(adr := ADDR(buf[2]), v := index - 1);
  setINT(adr := ADDR(buf[4]), v := length);
 
  // Send command
  rc := modbusSend(net_id := net_id, unit_id := unit_id, frame := ADDR(buf), size := 5);
  IF rc <> 0 THEN
     status := 3;
    RETURN;
  END_IF;
 
  // Wait for reply
  IF NOT modbusWaitData(net_id := net_id, timeout := 5000) THEN
     status := 4;
    RETURN;
  END_IF;
 
  // Read reply
  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;
 
  // Parse reply
  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;
    // Set next reading
     linsec := clockNow() + 5;
  END_IF;
END;
END_PROGRAM;