Skip to content

MODBUS-RTU

Function Blocks

FB_Component_ModbusRTUMaster

1
FUNCTION_BLOCK FB_Component_ModbusRTUMaster EXTENDS FB_ComponentBase IMPLEMENTS I_ModbusProvider

Contains required function blocks and logic to implement a Modbus-RTU master. Single and multi-drop configurations are supported.

Note

  • This component contains function blocks that require a TF6255 license
  • At this time, only KL/EL6xxx terminals implementing 22 byte buffers are supported

Design Notes

  • Modbus slaves should implement I_ModbusConsumer and at a minimum provide a unique identifier for the slave via SlaveID.
  • Modbus requests contain one or many operations. Operations are further divided into R/W operations. An R/W operation is defined by a start & end register(s), as well as a pointer to where the master should read/write the data for the above register(s).
  • Modbus requests are categorized as Sync or Async. Sync operations are analagous to EtherCAT process data, with a notable exception that they are processed serially versus completed cyclically. Async operations are meant to only be executed once (example a momentary pushbutton signal), and always take precedence over sync operations.
  • Care should be taken to understand the relationship between the task cycle time, the hardware buffering mechanisms, and the inherent limitation on data throughput that this creates. Note this is separate from baud rate. See Transfer Rates.
  • Process data links to/from the serial hardware are provided by the component.

Examples

Setting up sync requests in init
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
CASE SequenceState OF
    0:
        //Housekeeping--event creation, etc.
        IF SUPER^.Initialize() THEN
            SequenceState := SequenceState + 10;
        END_IF

    10:
        //Wait for Modbus master assigned
        //**This is application-dependant.  In this example the slave FB has a property for passing in an interface to FB_Component_ModbusRTUMaster**
        IF ipModbusMaster <> 0 AND _SlaveID <> 0 THEN
            SequenceState := SequenceState + 10;
        END_IF

    20:
        //Setup normal sync data reads
        SyncData.ipRequestor             := THIS^;  //Allows master to call back after request complete
        SyncData.ReadOps[1].StartAddress := 1000;
        SyncData.ReadOps[1].EndAddress   := 1010;
        SyncData.ReadOps[1].pAddress     := ADR(MySlaveStatusData); //This could be a DUT, group of vars, etc.

        IF ipModbusMaster.RegisterSyncRequest(Request := SyncData, RequestID => SyncData.RequestID) THEN
            SequenceState := SequenceState + 10;
        END_IF

    30:
        //Setup async requests
        //** In this case AsyncRequests is an array of ST_ModbusRequest **

        FOR i := 1 TO MAX_ASYNC_REQUESTS DO
            AsyncRequests[i].ipRequestor := THIS^;
        END_FOR

        // Stop Request - Write Stop Command
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Stop].WriteOps[1].StartAddress := 1023;
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Stop].WriteOps[1].EndAddress   := 1024;
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Stop].WriteOps[1].pAddress     := ADR(StopCommandFlag);

        // Move Request - Write Move Command
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Move].WriteOps[1].StartAddress := 1020;
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Move].WriteOps[1].EndAddress   := 1021;
        AsyncRequests[E_AsyncRequest.eAsyncRequest_Move].WriteOps[1].pAddress     := ADR(MoveCommandFlag);
        SequenceState                                                             := SequenceState + 10;

    40:
        Trace('Init complete');
        Initialize := TRUE;
END_CASE
Register an async request
1
2
3
4
5
IF ipModbusMaster
    .RegisterAsyncRequest(Request := AsyncRequests[E_Bansbach_AsyncRequest.eBansbachAsyncRequest_Stop], RequestID => AsyncRequests[E_Bansbach_AsyncRequest.eBansbachAsyncRequest_Stop].RequestID) THEN
    Trace('Stop commanded');
    Stop := TRUE;
END_IF
Handle request complete callback
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
METHOD ModbusRequestComplete
VAR_INPUT
    RequestID : ULINT;
END_VAR

VAR
    i : UDINT;
END_VAR
~~~~~~~~~~
//If the completed request is an async request, reset the RequestID to signal completed
CurrentCommsCount := CurrentCommsCount + 1;
FOR i := 1 TO MAX_ASYNC_REQUESTS DO
    IF AsyncRequests[i].RequestID = RequestID THEN
        Trace('Async modbus request completed');
        AsyncRequests[i].RequestID := 0;
        EXIT;
    END_IF
END_FOR

Interfaces

I_ModbusConsumer

Function blocks requiring R/W services from the master shall implement I_ModbusConsumer. This interface provides mechanisms for corellating particular function block instances with the Modbus slaves they represent, as well as a callback mechanism for the master to notify slaves of status information.

Properties

Property Type Access Description
SlaveID BYTE R Unique slave identifier on bus

Methods

Method Return Type Description
ModbusRequestComplete null Callback from I_ModbusProvider which signals that a particular request (sync/async) has been completed. Input parameter RequestID is given by the master to indicate which request completed.

I_ModbusProvider

Function blocks implementing I_ModbusConsumer register their R/W requests with the master via the methods provided by I_ModbusProvider.

Methods

Method Return Type Description
RegisterAsyncRequest BOOL Register a set of asynchronous R/W operations to be executed as soon as possible
RegisterSyncRequest BOOL Register a set of synchronous R/W operations to be executed cyclically, in order of registration

DUTs

ST_ModbusOperation

1
2
3
4
5
6
7
TYPE ST_ModbusOperation :
    STRUCT
        StartAddress : UINT;
        EndAddress   : UINT;
        pAddress     : PVOID;
    END_STRUCT
END_TYPE

ST_ModbusRequest

1
2
3
4
5
6
7
8
TYPE ST_ModbusRequest :
    STRUCT
        ipRequestor : I_ModbusConsumer;
        RequestID   : ULINT;
        ReadOps     : ARRAY[1..Parameters_ModbusRTU.MAX_MODBUS_RW_OPS_PER_REQUEST] OF ST_ModbusOperation;
        WriteOps    : ARRAY[1..Parameters_ModbusRTU.MAX_MODBUS_RW_OPS_PER_REQUEST] OF ST_ModbusOperation;
    END_STRUCT
END_TYPE

Globals/Parameters

Parameters_ModbusRTU

Parameter Type Default Description
MAX_MODBUS_REQUESTS UDINT 100 Maximum sync & async requests that can be registered with a master
MAX_MODBUS_RW_OPS_PER_REQUEST UDINT 100 Maximum operations per request
MODBUS_TIMEOUT TIME T#100MS Modbus-RTU communications timeout period