MODBUS MASTER
Name | ModbusMaster |
---|---|
Version | 1 |
Major release | 0 |
Minor release | 8 |
Title | Unit for implement a Modbus® master communication with extended addressing. |
1. DESCRIPTION
The unit implement a complete data exchange model for a Modbus master communication line. The main features are:
-
Usable with serial communication line (master) or with TCP/IP protocol (client).
-
Communication with several slaves (maximum 32) that can have inhomogeneous communication parameters.
-
Management of a process table to read and write data continuously.
-
Management of a parameter table with the possibility to perform complete read or write to or from a slave.
-
Internal state machine to clearly identify the operating status of the unit.
-
Message counters (processed successfully and error message).
2. STATE MACHINE
The large circles represent stable states. They are:
STOPPED: state where the unit does not perform any activity. It is also the initial state.
READY: state of full activity
ABORT: there is a serious error, the unit switches to the safe state and waits for a stop command. AbortCode provides an identification code of the reason that set that state.
The rectangles indicate transient states:
STARTING: state in which the unit checks all the settings data and if the values are within the limits opens the communication channel.
STOPPING: nothing do in this implementation.
ABORTING: nothing do in this implementation.
Baloons are commands that can be sent to change the state:
Prepare, commands the unit to switch into ready state. Prior to this command must be configured all the communication parameters.
Stop, commands the unit to switch into STOPPED state. The communication channel is closed if it was open.
3. OPERATION
3.1 Modbus® functions
The following table shows the Modbus standard functions that are available.
Value | Constant | Description |
---|---|---|
1 | READCOIL* | Reads the ON/OFF status of discrete outputs (coils) in the slave. |
3 | READREG | Reads the binary contents of holding registers in the slave. |
4 | READINREG | Reads the binary contents of input registers in the slave. |
5 | FORCECOIL* | Forces a single coil to either ON or OFF. |
6 | FORCEREG | Presets a value into a single holding register. |
15 | FORCEMCOIL* | Forces each coil in a sequence of coils to either ON or OFF. |
16 | FORCEMREG | Presets values into a sequence of holding registers. |
* These functions are currently selectable, but not yet fully developed.
3.2 Configuration tables
3.2.1 Slave table
It's a table that contains the communication parameters for each slave. You can enter the parameters for up to 32 slaves. Every column is a QCL global array with size 32.
For a serial communication line the table is:
SlaveId | SlaveBitrate | SlaveStopBits | SlaveParity | SlaveTimeout | SlaveAddrOffset | |
---|---|---|---|---|---|---|
row 1 | 2 | 38400 | 1 | 2 | 50 | 0 |
row 2 | 15 | 9600 | 2 | 0 | 200 | 1 |
… | ||||||
row 32 |
For a TCPIP communication the table is:
SlaveId | SlaveTcpAddr3 | SlaveTcpAddr2 | SlaveTcpAddr1 | SlaveTcpAddr0 | SlaveTcpChangeIpDly | SlaveAddrOffset | |
---|---|---|---|---|---|---|---|
row 1 | 1 | 192 | 168 | 0 | 20 | 100 | 0 |
row 2 | 1 | 192 | 168 | 0 | 21 | 200 | 1 |
… | |||||||
row 32 |
SlaveId : It's the real ID of the Modbus protocol set in the slave.
SlaveBitrate : It's the baud rate (we support all values compatible with the device MODBUS).
SlaveStopBits : It's the stop bit (0,1,2).
SlaveParity : It's the parity (0 = NONE, 1 = ODD, 2 = EVEN).
SlaveTimeout : It's the maximum value of waiting for a response before reporting a timeout error.
SlaveAddrOffset : It's a value that is added to the address before sending the Modbus message. It's used for matching the numbering of the address used in the tables of this unit with the values shown in the documentation of the slave.
SlaveTcpAddr3 : It's the tcpip address position 3 [Highest] ⇒ 3.2.1.0
SlaveTcpAddr2 : It's the tcpip address position 2.
SlaveTcpAddr1 : It's the tcpip address position 1.
SlaveTcpAddr0 : It's the tcpip address position 0 [Lowest].
SlaveTcpChangeIpDly : It's a waiting time in milliseconds used at every tcpip address change [min. 1, default 500].
Once the SlaveId is entered into this table, it allows you to identify a slave with generic index which we will call from now on “Slave index” and which corresponds to the row of the table.
3.2.2 Process table
It's a configuration table for a communication of data process (usually called cyclic data). The process values are stored on an array (called ProcessValue)
where each data element is located at a certain index value. The calculation of the index value for each data is done automatically by the unit based on the data of ProcessTable. The communication of process data can be enabled or disabled with the parameter ProcessEnable.
In order to optimize the occupation of the Modbus® channel, process table can use multiple messages. Also you can place in ProcessTable write command messages.
An example of the communication process can be a reading of the statusword inverter, writing of the motor speed, reading of the torque value of the motor, reading the temperature value by a temperature controller, etc..
The ProcessTable has a size of 100 rows that must be used for the process data exchange of all slaves; the array ProcessValue has a size of 300 elements. When the unit encounters a line with ProcessId equal to zero, it resumes scanning from beginning (row 1). To suspend temporarily a specific row communication, set ProcessId to a negative value.
ProcessTable
ProcessId | ProcessAddr | ProcessNum | ProcessType | ProcessOffset | ProcessDevErr | |
---|---|---|---|---|---|---|
row 1 | 1 | 100 | 2 | 3 | 1 | |
row 2 | 2 | 100 | 3 | 3 | 3 | |
… | ||||||
row 100 |
Every column is a QCL global array.
ProcessValue
1 | 2 | 3 | 4 | 5 | 6 | … | 300 |
---|---|---|---|---|---|---|---|
row 1 | row 1 | row 2 | row 2 | row 2 |
ProcessId : It's the slave index that indicates that you want to communicate with the slave whose parameters are represented by the row indicated by the value in SlaveTable.
ProcessAddr : It's the Modbus address.
ProcessNum : It's the number of elements (for multiple reading or writing).
ProcessType : It's the Modbus function type.
ProcessOffset : It's the ProcessValue array index where the values will start to be stored. This value is calculated automatically when you start the unit.
ProcessDevErr : It's the err parameter value of the device in the case of error communication.
3.2.3 Param table
It manages communication used to perform operations on slave configuration registers (call parameters). This table includes all the information needed to identify these parameters. It 'a single table for all slaves. This table can be included only the data manipulated by the message Modbus® 3 (read holding register) or 6 (force holding register). Are not possible communications using coils, inputs, inputs registers and multiple operations.
The size of this table is 200 rows.
To start communication with the Param table you must use the LowMailBox described below.
ParamId | ParamAddr | ParamNum | ParamOptions | ParamValue | |
---|---|---|---|---|---|
row 1 | 1 | 200 | 1 | 0 | 11 |
row 2 | 2 | 201 | 1 | 0 | 22 |
… | |||||
row 200 |
ParamId : It's the slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable.
ParamAddr : It's the Modbus address.
ParamNum : Normally set to 1, the value is set 2 to treat certain 32bit data which are composed of two words Modbus®.
ParamOptions : You can specify some details about communication (shown below).
ParamValue : It's the read value or the value to be written.
ParamOptions
The ParamOptions is used to set certain communication characteristics. It runs with the following bit masks:
Constant | Bit | Description |
---|---|---|
OPTION_SIZE | 0 | If true, it allows to perform writing parameter as a COIL. FORCECOIL (5) instead of FORCEREG (6) FORCEMCOIL (15) instead of FORCEMREG (16) |
OPTION_MULTI | 1 | If true, it allows to perform writing parameters with size (num) 1 with Modbus multiple functions FORCEMCOIL (15) and FORCEMREG (16). |
OPTION_ROUND | 2 | If true, it allows to tolerate differences of 1 unit during check parameters commands (the value in the slave can be less by one compared to the value in the table). Some slaves execute internal roundings processing of numerical values received via Modbus. |
3.3 MailBoxes
It's a technique of traffic light system for communication between the various units. This unit includes two Mailbox, the HighMbox and LowMbox.
This Mailboxes allows to various units of the Qview project to share Modbus® communication.
Here's an example:
Both HighMbox and LowMbox are an array of 38 elements, that will be explained subsequently.
In HighMbox[1] and LowMbox[1], there are states and commands to mailboxes:
Value | Constant | Desciption |
---|---|---|
0 | MBOX_FREE | Mailbox is free to be used. |
1 | MBOX_REPLY | Mailbox reply. |
2 | MBOX_SINGLE_REQUEST | Mailbox single request. |
3 | MBOX_PARAM_CHECK | Mailbox command to check all parameters of a single slave. Only for LowMbox. |
4 | MBOX_PARAM_CHECK_ALL | Mailbox command to check all parameters of all slaves. Only for LowMbox. |
5 | MBOX_PARAM_READ | Mailbox command to read all parameters of a single slave. Only for LowMbox. |
6 | MBOX_PARAM_WRITE | Mailbox command to write all parameters of a single slave. Only for LowMbox. |
The variable LowMboxProgress is updated during LowMbox commands and takes values from 0 to 100 to indicate the progress of the operation. It can be used in hmi progressbar.
Now we explain all the activities that can be done with the mailboxes:
3.3.1 Single request
HighMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 2 → MBOX_SINGLE_REQUEST |
|
HighMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
HighMbox[1] = MBOX_REPLY | HighMbox[1] = MBOX_SINGLE_REQUEST | |
---|---|---|
HighMbox[2] | slave index | |
HighMbox[3] | address | |
HighMbox[4] | type | |
HighMbox[5] | num | |
HighMbox[6] | return value 0 = OK 1 = error in communication 4 = error in opening or closing the COM port 5 = slave index out of range 6 = modbus type not valid | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
HighMbox[7..38] | values of the registers (in the case of reading) | values of the registers (in the case of writing) |
This is a sample code for a read request:
WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_FREE ; wait for empty mailbox MDBMAST1.HighMbox[2] = 1 ; first slave in configuration table MDBMAST1.HighMbox[3] = 100 ; address MDBMAST1.HighMbox[4] = MDBMAST1.READINREG ; type MDBMAST1.HighMbox[5] = 5 ; num MDBMAST1.HighMbox[6] = 0 ; tout (use default) MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; start request WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait for reply IF MDBMAST1.HighMbox[6] EQ 0 ; successfully ? Myvar = MDBMAST1.HighMbox[7] ENDIF MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_FREE ; mailbox is now free for other units
We can do the same function with LowMbox (the difference between High and Low will be explained subsequently).
LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 2 → MBOX_SINGLE_REQUEST |
|
LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_SINGLE_REQUEST | |
---|---|---|
LowMbox[2] | slave index | |
LowMbox[3] | address | |
LowMbox[4] | type | |
LowMbox[5] | num | |
LowMbox[6] | return value 0 = OK 1 = error in communication 4 = error in opening or closing the COM port 5 = slave index out of range 6 = modbus type not valid | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
LowMbox[7..38] | values of the registers (in the case of reading) | values of the registers (in the case of writing) |
3.3.2 Check parameters of a single slave
The function checks the parameters of a slave if they match with the values contained in ParamValue.
LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 3 → MBOX_PARAM_CHECK |
|
LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_CHECK | |
---|---|---|
LowMbox[2] | slave index | |
LowMbox[6] | return value 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
LowMbox[7] | In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error | |
LowMbox[8] | In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error | |
LowMbox[9] | In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error |
3.3.3 Check parameters of all slaves
The function checks the parameters of all slaves if they match with the values contained in ParamValue.
LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 4 → MBOX_PARAM_CHECK_ALL |
|
LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_CHECK_ALL | |
---|---|---|
LowMbox[2] | slave index | |
LowMbox[6] | return value 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
LowMbox[7] | In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error | |
LowMbox[8] | In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error | |
LowMbox[9] | In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error | |
LowMbox[10] | In the case of LowMbox [6] = 2, is shown the slave index of the parameter that caused the error |
3.3.4 Read parameters of a single slave
The function reads the parameters of a slave and stores them in ParamValue.
LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 5 → MBOX_PARAM_READ |
|
LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_READ | |
---|---|---|
LowMbox[2] | slave index | |
LowMbox[6] | return value 0 = OK 1 = error in communication 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
LowMbox[7] | In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication | |
LowMbox[8] | In the case of LowMbox [6] = 1, is shown the last word read by the device MODBUS | |
LowMbox[9] | In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS |
3.3.5 Write parameters of a single slave
The function writes the parameters of a slave with the values stored in ParamValue.
LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 6 → MBOX_PARAM_WRITE |
|
LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_WRITE | |
---|---|---|
LowMbox[2] | slave index | |
LowMbox[6] | return value 0 = OK 1 = error in communication 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
LowMbox[7] | In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication | |
LowMbox[8] | In the case of LowMbox [6] = 1, is shown the last word written by the device MODBUS | |
LowMbox[9] | In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS |
3.3.6 HighMbox vs LowMbox
The difference between HighMbox and LowMbox is that he HighMbox has the possibility of entering during a multiple request commanded on LowMbox, in order to have always the possibility of fast action on variables of high priority.
Let's see how the priority of requests are menaged. Denote by:
P = request regarding the ProcessTable
H = request regarding the HighMbox
L = request regarding the LowMbox
-
With process active, it is required a high priority reading:
The request is immediately inserted between each ProcessData request.
-
The LowMbox requests are inserted alternating with the ProcessData so the unit meets alternately one row of the ProcessTable and a row of the ParamTable (in the example it is assumed that the LowMbox requests an operation of read parameters of a slave, via the command LowMbox [1] = MBOX_PARAM_READ):
-
In the last example with the ProcessData active, a write parameters operation is requested, via the command LowMbox [1] = MBOX_PARAM_WRITE), and at the same time it is required a high priority reading:
4. PUBLIC SYMBOLS
Below there are some tables with an explanation of the public symbols.
4.1 Inputs
Name | Type | Size | Access Type | Description |
---|---|---|---|---|
Prepare | GLOBAL | F | IN | Command to set STARTING state, after all configuration tables were compiled. |
Stop | GLOBAL | F | INOUT | Command to set STOPPING state. |
ProcessEnable | GLOBAL | F | INOUT | Enable for process requests. |
ProcessErrReset | GLOBAL | F | INOUT | Command to reset all the errors of ProcessTable. |
StatReset | GLOBAL | F | INOUT | Command to reset all the values concerning statistics. |
HighMbox[1] LowMbox[1] | ARRGBL | W | INOUT | Commands to mailboxes : (2) MBOX_SINGLE_REQUEST (3) MBOX_PARAM_CHECK (4) MBOX_PARAM_CHECK_ALL (5) MBOX_PARAM_READ (6) MBOX_PARAM_WRITE Commands 3,4,5,6 are available only for LowMbox. It should be set to (0) MBOX_FREE when a request is completed. |
HighMbox[2] LowMbox[2] | ARRGBL | W | INOUT | Slave index. |
HighMbox[3] LowMbox[3] | ARRGBL | W | INOUT | Modbus address (only for MBOX_SINGLE_REQUEST). |
HighMbox[4] LowMbox[4] | ARRGBL | W | INOUT | Modbus function (only for MBOX_SINGLE_REQUEST). 1, 3, 4, 5, 6, 15, 16 |
HighMbox[5] LowMbox[5] | ARRGBL | W | INOUT | Modbus elements number (only for MBOX_SINGLE_REQUEST). |
HighMbox[6] LowMbox[6] | ARRGBL | W | INOUT | Timeout modbus reply. |
HighMbox[7..38] LowMbox[7..38] | ARRGBL | W | INOUT | Data area (in MBOX_SINGLE_REQUEST). |
4.2 Outputs
Name | Type | Size | Access Type | Description |
---|---|---|---|---|
State | GLOBAL | B | OUT | Actual state. The values can be STOPPED (0), STARTING (1), READY (2), ABORTING (3), ABORTED (4), STOPPING (5) |
ProcessError | GLOBAL | F | OUT | Modbus error during a request of process loop; it remains active until it is set to 0 by the command ProcessErrReset. |
LowMboxProgress | GLOBAL | B | OUT | Rate of progression in parameters LowMbox functions. |
HighMbox[1] LowMbox[1] | ARRGBL | W | INOUT | Mailboxes states. (0) MBOX_FREE (1) MBOX_REPLAY (2..6) active request |
HighMbox[6] LowMbox[6] | ARRGBL | W | INOUT | Return value. 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port |
HighMbox[7..38] LowMbox[7..38] | ARRGBL | W | INOUT | Data area in requests without errors (in MBOX_SINGLE_REQUEST). |
LowMbox[7] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication. |
LowMbox[8] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the last word read or written by the device MODBUS. |
LowMbox[9] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS. |
LowMbox[10] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST, MBOX_PARAM_CHECK, MBOX_PARAM_READ and MBOX_PARAM_WRITE → not used MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the slave index of the parameter that caused the error. |
Statistics | ||||
TotalStatCommOk | GLOBAL | L | OUT | Counter all requests completed without errors. |
TotalStatAttempt | GLOBAL | L | OUT | Counter all attempts performed in completed requests without errors. |
TotalStatCommKo | GLOBAL | L | OUT | Counter all requests not completed for exceeding the maximum number of attempts. |
TotalStatWrong | GLOBAL | L | OUT | Counter all requests not completed for a Modbus request error. |
UpdateProcessTime | GLOBAL | L | OUT | Current update time of all process table. |
Stat table | ||||
StatCommOk | ARRGBL | L | OUT | Counter of requests completed without error for each Modbus node. |
StatAttempt | ARRGBL | L | OUT | Counter all attempts performed in completed requests without errors for each Modbus node. |
StatCommKo | ARRGBL | L | OUT | Counter all requests not completed for exceeding the maximum number of attempts for each Modbus node. |
StatWrong | ARRGBL | L | OUT | Counter all requests not completed for a Modbus request error for each Modbus node. |
StatMaxReplyTime | ARRGBL | W | OUT | Maximum time (msec) for requests completed without attempts for each Modbus node. |
4.3 Parameters
Name | Type | Size | Access Type | Description |
---|---|---|---|---|
Protocol | GLOBAL | B | IN | Device MODBUS protocol selection. (0) = DEVICE_PROT_ASCII (1) = DEVICE_PROT_RTU (2) = DEVICE_PROT_TCPIP) |
TcpIpPort | GLOBAL | W | INOUT | TCPIP communication port. Used only with Protocol = DEVICE_PROT_TCPIP, defines the communication port for messages. If this parameter is left to zero, the unit uses the default value of the Modbus protocol (502). |
MaxAttempts | GLOBAL | B | INOUT | Maximum number of attempts. |
RelaxTime | GLOBAL | L | INOUT | Waiting time (msec) between an attempt and another (default = 200) |
Slave table | ||||
SlaveId | ARRGBL | W | INOUT | The real ID of the Modbus protocol set in the slave. |
SlaveBitrate | ARRGBL | L | INOUT | The baud rate (we support all values compatible with the device MODBUS). |
SlaveStopBits | ARRGBL | B | INOUT | The stop bit (0,1,2). |
SlaveParity | ARRGBL | B | INOUT | The parity (0 = NONE, 1 = ODD, 2 = EVEN). |
SlaveTimeout | ARRGBL | W | INOUT | The maximum value of waiting for a response before reporting a timeout error. |
SlaveAddrOffset | ARRGBL | B | INOUT | A value that is added to the address before sending the Modbus message. It's used for matching the numbering of the address used in the tables of this unit with the values shown in the documentation of the slave. |
SlaveTcpAddr3 | ARRGBL | W | INOUT | Tcpip address position 3 [Highest] ⇒ 3.2.1.0 |
SlaveTcpAddr2 | ARRGBL | W | INOUT | Tcpip address position 2. |
SlaveTcpAddr1 | ARRGBL | W | INOUT | Tcpip address position 1. |
SlaveTcpAddr0 | ARRGBL | W | INOUT | Tcpip address position 0 [Lowest]. |
SlaveTcpChangeIpDly | ARRGBL | L | INOUT | A waiting time in milliseconds when the new request is for another tcpip slave [min. 1, default 500]. |
Param table | ||||
ParamId | ARRGBL | W | INOUT | The slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable. |
ParamAddr | ARRGBL | W | INOUT | The Modbus address. |
ParamNum | ARRGBL | W | INOUT | Normally set to 1, the value is set 2 to treat certain 32bit data which are composed of two words Modbus®. |
ParamOptions | ARRGBL | B | INOUT | You can specify some details about communication (shown in relative chapter). |
ParamValue | ARRGBL | L | INOUT | The value read or the value to be written. |
Process table | ||||
ProcessId | ARRGBL | W | INOUT | The slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable. |
ProcessAddr | ARRGBL | W | INOUT | The Modbus address. |
ProcessNum | ARRGBL | W | INOUT | The number of elements (for multiple reading or writing). |
ProcessType | ARRGBL | W | INOUT | The Modbus function type. |
ProcessOffset | ARRGBL | W | INOUT | The ProcessValue array index where the values will start to be stored. This value is calculated automatically when you start the unit. |
ProcessDevErr | ARRGBL | B | OUT | The err parameter value of the device in the case of error communication. |
ProcessValue | ARRGBL | L | INOUT | In this area is stored the value read or to be written. |
4.4 Constants
Name | Value | Description |
---|---|---|
States | ||
STOPPED | 0 | State where the unit does not perform any activity. It is also the initial state. |
STARTING | 1 | State in which the unit checks all the settings data and if the values are within the limits opens the communication channel. |
READY | 2 | State of full activity. |
ABORTING | 3 | Nothing do in this implementation. |
ABORTED | 4 | There is a serious error, the unit switches to the safe state and waits for a stop command. AbortCode provides an identification code of the reason that set that state. |
STOPPING | 5 | Nothing do in this implementation. |
Modbus protocol | ||
DEVICE_PROT_ASCII | 0 | MODBUS ASCII protocol. |
DEVICE_PROT_RTU | 1 | MODBUS RTU protocol. |
DEVICE_PROT_TCPIP | 2 | MODBUS TCPIP protocol. |
Modbus functions types | ||
READCOIL | 1 | Reads the ON/OFF status of discrete outputs (coils) in the slave. |
READREG | 3 | Reads the binary contents of holding registers in the slave. |
READINREG | 4 | Reads the binary contents of input registers in the slave. |
FORCECOIL | 5 | Forces a single coil to either ON or OFF. |
FORCEREG | 6 | Presets a value into a single holding register. |
FORCEMCOIL | 15 | Forces each coil in a sequence of coils to either ON or OFF. |
FORCEMREG | 16 | Presets values into a sequence of holding registers. |
Param table request options | ||
OPTION_SIZE | &H01 | If checked, it allows you to perform writing parameter as a COIL. FORCECOIL (5) instead of FORCEREG (6) FORCEMCOIL (15) instead of FORCEMREG (16) |
OPTION_MULTI | &H02 | If checked, it allows you to perform writing parameters with size (num) 1 with Modbus multiple functions FORCEMCOIL (15) and FORCEMREG (16). |
OPTION_ROUND | &H04 | If this option is set, it allows to tolerate during the commands of check parameters differences of 1 unit (the value in the slave can be less by one unit spite the value in the table). It has been seen that some slaves execute internal roundings processing of numerical values received via Modbus for which a value previously written does not match the value reread. |
Mailboxes states and commands | ||
MBOX_FREE | 0 | Mailbox is free to be used. |
MBOX_REPLY | 1 | Mailbox reply. |
MBOX_SINGLE_REQUEST | 2 | Mailbox single request. |
MBOX_PARAM_CHECK | 3 | Mailbox command to check all parameters of a single slave. Only for LowMbox. |
MBOX_PARAM_CHECK_ALL | 4 | Mailbox command to check all parameters of all slaves. Only for LowMbox. |
MBOX_PARAM_READ | 5 | Mailbox command to read all parameters of a single slave. Only for LowMbox. |
MBOX_PARAM_WRITE | 6 | Mailbox command to write all parameters of a single slave. Only for LowMbox. |
5. EXAMPLES OF USE
To better understand the operation of this unit, we explain a real case.
The qmove controller must communicate with two servo drives. The connection media is a serial cable.
We want the processTable that continuously read/write the following parameters:
-
Read the current speed of the drive No. 1
-
Write the set speed of the drive No. 1
-
Read the actual current of the drive No. 1
-
Read the current speed of the drive No. 2
-
Write the set speed of the drive No. 2
-
Read the actual current of the drive No. 2
We also want to manage the parameters nr.1070, 1071 of the drive 1 and 2. When you powerup the controller may be useful to verify the parameters value. If qmove control change values than may be useful to write new values to drives.
Acyclic (for example every 10 seconds) we want to read the temperatures of the engine reading registers from 00A4 to 00A7 (with lowMbox).
Lastly, we want to perform a high priority write to disable the drive in case of emergency. The writing will be done using register 0474 (with highmbox).
5.1 Settings
-
Create a new project with QView-6
-
Add a unit type configuration. Edit BUS section according with your product name. In the section INTDEVICE insert the declaration of a device MOSBUS:
INTDEVICE MdbDevice MODBUS 0008 1
Pay attention to the last field number of the declaration (1) that is used to select the communication port. Usually it is 0 for PROG port, 1 for USER port, 2 for aux1, 3 for aux2 port and 43 for ethernet port (modbus tcpip). Check hardware manual for assurance.
-
In the REFERENCES section (always in the unit configuration) add the following code:
REFERENCES MDBMAST1.modbus = MdbDevice
-
Add a unit QCL with a name (for example, MAIN).
-
Add to the project the QCL Feature unit ModbusMaster10 and name MDBMAST1
-
Proceed on the task init of MAIN unit with the protocol setting and slaves setting:
MDBMAST1.Protocol = MDBMAST1.DEVICE_PROT_RTU ; modbus rtu ; setting unit ModbusMaster10 slave table ; node 1 MDBMAST1.SlaveId[1] = 1 MDBMAST1.SlaveBitrate[1] = 9600 MDBMAST1.SlaveStopBits[1] = 1 MDBMAST1.SlaveParity[1] = 0 MDBMAST1.SlaveTimeout[1] = 200 MDBMAST1.SlaveAddrOffset[1] = 0 ; node 2 MDBMAST1.SlaveId[2] = 3 MDBMAST1.SlaveBitrate[2] = 57600 MDBMAST1.SlaveStopBits[2] = 2 MDBMAST1.SlaveParity[2] = 1 MDBMAST1.SlaveTimeout[2] = 100 MDBMAST1.SlaveAddrOffset[2] = 1
Our network is RTU and consists of 2 drives, one with id 1 and the other with id 3, with different communication settings.
-
Simple process values for the two drives can be the current speed and the set speed. We add these two values also a value of the drive that can identify a working state (stopped, moving, alarm, etc.). Then set the process table:
; setting unit ModbusMaster10 process table ; read current speed of slave index 1 MDBMAST1.ProcessId[1] = 1 ; slave index (in slave table) MDBMAST1.ProcessAddr[1] = &H102B ; exadecimal address value MDBMAST1.ProcessNum[1] = 1 ; number of elements MDBMAST1.ProcessType[1] = MDBMAST1.READINREG ; type of modbus request ; write set speed of slave index 1 MDBMAST1.ProcessId[2] = 1 MDBMAST1.ProcessAddr[2] = &H0060 MDBMAST1.ProcessNum[2] = 1 MDBMAST1.ProcessType[2] = MDBMAST1.FORCEREG ; read current state of slave index 1 MDBMAST1.ProcessId[3] = 1 MDBMAST1.ProcessAddr[3] = &H00A8 MDBMAST1.ProcessNum[3] = 1 MDBMAST1.ProcessType[3] = MDBMAST1.READINREG ; read current speed of slave index 2 MDBMAST1.ProcessId[4] = 2 MDBMAST1.ProcessAddr[4] = &H102B MDBMAST1.ProcessNum[4] = 1 MDBMAST1.ProcessType[4] = MDBMAST1.READINREG ; write set speed of slave index 2 MDBMAST1.ProcessId[5] = 2 MDBMAST1.ProcessAddr[5] = &H0060 MDBMAST1.ProcessNum[5] = 1 MDBMAST1.ProcessType[5] = MDBMAST1.FORCEREG ; read current state of slave index 2 MDBMAST1.ProcessId[6] = 2 MDBMAST1.ProcessAddr[6] = &H00A8 MDBMAST1.ProcessNum[6] = 1 MDBMAST1.ProcessType[6] = MDBMAST1.READINREG
-
We also want to use the features of the mailbox to manage a short list of parameters. Then set the param table:
; setting unit ModbusMaster10 param table ; first parameter of the list (slave index 1) MDBMAST1.ParamId[1] = 1 ; slave index (in slave table) MDBMAST1.ParamAddr[1] = &H1070 ; exadecimal address value MDBMAST1.ParamNum[1] = 1 ; number of elements (maximum 2, to manage double word parameters) MDBMAST1.ParamOptions[1] = MDBMAST1.OPTION_MULTI ; parameter option (use multiple modbus write function) ; second parameter of the list (slave index 1) MDBMAST1.ParamId[2] = 1 MDBMAST1.ParamAddr[2] = &H1071 MDBMAST1.ParamNum[2] = 1 MDBMAST1.ParamOptions[2] = 0 ; third parameter of the list (slave index 2) MDBMAST1.ParamId[3] = 2 MDBMAST1.ParamAddr[3] = &H1070 MDBMAST1.ParamNum[3] = 1 MDBMAST1.ParamOptions[3] = MDBMAST1.OPTION_MULTI ; fourth parameter of the list (slave index 2) MDBMAST1.ParamId[4] = 1 MDBMAST1.ParamAddr[4] = &H1071 MDBMAST1.ParamNum[4] = 1 MDBMAST1.ParamOptions[4] = 0
-
After these configuration settings, prepare the feature unit to work:
; execute unit command Prepare MDBMAST1.Prepare = 1 WAIT (MDBMAST1.State EQ MDBMAST1.READY) OR (MDBMAST1.State EQ MDBMAST1.ABORTED) IF MDBMAST1.State EQ MDBMAST1.ABORTED MDBMAST1.Stop = 1 ; in case of error return to STOPPED state ... ; insert the code to notify the error ELSE MDBMAST1.ProcessEnable = 1 ; process requests can start ENDIF
5.2 Process values
To manage the process values, use the array ProcessValue:
Drive1Vel = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[1]] ; reading current speed MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[2]] = Drive1SetVel ; writing set speed Drive1State = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[3]] ; reading current state Drive2Vel = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[4]] MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[5]] = Drive2SetVel Drive2State = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[6]]
ProcessOffset automatically calculates the position of the process element on the array.
5.3 Manage parameters
In our example, we imagine to use the ParamTable once the drives are fully configured and ready to use. We decide the parameters that we could modify through our application. At this point at least the first time we go to read these parameters, and we have to save them in our retentive area.
The next code example shows how to read all parameters from second drive:
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.LowMbox[2] = 2 ; select slave index 2 MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_READ ; read parameters function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 ... ; read parameters successfully (message, change page, etc.) slDrive2Par1 = MDBMAST1.ParamValue[3] ; store the read value on ritentive variable slDrive2Par2 = MDBMAST1.ParamValue[4] ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
Normally at power, when you enable the connection of a Modbus network drives it is sometimes useful to analyze whether the parameters in the memory are aligned with those on the drives. To do this, we can use the corresponding commands of the mailbox:
MDBMAST1.ParamValue[1] = slDrive1Par1 ; load ritentive value on ParamValue array MDBMAST1.ParamValue[2] = slDrive1Par2 WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.LowMbox[2] = 1 ; select slave index MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_CHECK ; check parameters function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 ... ; check parameters successfully (message, change page, etc.) ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
You can also use the function MBOX_PARAM_CHECK_ALL to check all parameters of all slaves with a single command.
Finally, we use the write command to set the parameters on the first and on the second drive:
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.ParamValue[1] = slDrive1Par1 ; load ritentive value on ParamValue array MDBMAST1.ParamValue[2] = slDrive1Par2 MDBMAST1.ParamValue[3] = slDrive2Par1 MDBMAST1.ParamValue[4] = slDrive2Par2 MDBMAST1.LowMbox[2] = 1 ; select slave index 1 MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_WRITE ; write parameters function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 ... ; write parameters successfully (message, change page, etc.) ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[2] = 2 ; select slave index 2 MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_WRITE ; write parameters function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 ... ; write parameters successfully (message, change page, etc.) ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
Some parameters cannot be written in certain drive states.
See the drive documentation.
5.4 Single requests
In our example, each unit of a project has the possibility of using single requests for information, to set reference values, or force states of the drives. For these applications we offer 2 mailbox. Why 2 mailbox?
Basically to have two priorities for intervention.
If we use the HighMbox (high priority), we are going to intervene immediately after the current request, which is a read/write process, which is a request to check/read/write parameters, or other demands on LowMbox (low priority) from other units.
This feature was implemented considering the fact that some information must travel as quickly as possible, in our case we can say that in the event of an alarm condition must intervene immediately disabling drives.
Instead, the single requests on LowMbox are used for information that can wait for a while to be completed.
UNIT 1 - low priority request
For example, read some temperatures.
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.LowMbox[2] = 1 ; select slave index MDBMAST1.LowMbox[3] = &H00A4 ; address (&H = hexadecimal) MDBMAST1.LowMbox[4] = MDBMAST1.READREG ; read holding register modbus function MDBMAST1.LowMbox[5] = 4 ; number of elements (read from &H00A4 to &H00A7) MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 temperature[1] = MDBMAST1.LowMbox[7] ; store the read values on array temperature[2] = MDBMAST1.LowMbox[8] temperature[3] = MDBMAST1.LowMbox[9] temperature[4] = MDBMAST1.LowMbox[10] ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
UNIT 2 - high priority request
For example, disable drive for an alarm condition.
IF Alarm WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.HighMbox[2] = 2 ; select slave index MDBMAST1.HighMbox[3] = &H0009 ; address (&H = hexadecimal) MDBMAST1.HighMbox[4] = MDBMAST1.FORCEREG ; write holding register modbus function MDBMAST1.HighMbox[5] = 1 ; number of elements MDBMAST1.HighMbox[7] = &0474 ; example value in state register to disable drive MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.HighMbox[6] EQ 0 NOP ; not operation ELSE ... ; insert the code to menage errors ENDIF ENDIF
UNIT 3 - low priority request
For example, write a new setpoint on drive.
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free MDBMAST1.LowMbox[2] = 1 ; select slave index MDBMAST1.LowMbox[3] = &H88AF ; address (&H = hexadecimal) MDBMAST1.LowMbox[4] = MDBMAST1.FORCEREG ; write holding register modbus function MDBMAST1.LowMbox[5] = 1 ; number of elements MDBMAST1.LowMbox[7] = 5600 ; new setpoint value MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies IF MDBMAST1.LowMbox[6] EQ 0 NOP ; not operation ELSE ... ; insert the code to menage errors ENDIF MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
6. LIMITATIONS
-
The unit currently handles only Modbus messages type 3 (holding register read), 4 (read input register), 6 (force register) , 16 (force multiple registers). It does not handle modbus messages 1 (read coil) , 5 (force coil), 15 (force multiple coils). These functions are currently selectable, but not yet fully developed.
-
It's not possible to configure slaves RTU and TCPIP with the same master. And in that case you need to enter 2 device MODBUS and 2 ModbusMaster10 and divide the network, one for serial slaves and one for tcpip slaves.
-
The maximum number of configurable slaves is fixed at 32.
-
The maximum number of configurable parameters in Param table is fixed at 200.
-
The maximum number of configurable process requests in Process table is fixed at 100.
-
The maximum number of configurable process values in ProcessValue array is fixed at 300.
-
The maximum number of registers readable or writable with a single message is fixed at 32.
-
Mailbox requests relative to parameters, can read/write only one parameter at time (not multiple elements).
-
Not all qmove product supports baud rate of 115200 baudrate. Check product documentation.
7. NOTES
-
For a good use of the unit, it is good to remember to always wait for the mailbox is free before using it, and remember, once you have completed the request, to make it free so that they can be met other requests.
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free ... ; request MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; at the end release the mailbox
8. CHANGE LOG
QCL feature release | Description | Note | Date |
---|---|---|---|
1.0.8 | - Add constants for mailbox status and commands - Public constants for modbus protocol - Minor bugs fix - Add new example projects | 23/09/2015 |
9. DOWNLOAD
Click here to download unit and examples.
Zip contents:
File and folder name | Description |
---|---|
MDBMAST1.UNT | Qcl feature file |
MODBUS_MASTER_SERIAL_EXAMPLE | Example for serial communication |
MODBUS_MASTER_TCPIP_EXAMPLE | Example for client TCPIP communication |