Skip to main content

Brownfield Modbus Devices

Mobdbus binding

Configuration

brownfieldDevices:
modbus:
- name: MB1
type: TCP
address: 127.0.0.1
port: 8502
tables:
- type: coils # discrete output read/wirte
start: 1000
length: 32
pollingRate: 10000 # polling rate in ms
- type: discreteInputs # read only
start: 2000
length: 10
pollingRate: 10000 # polling rate in ms
- type: holdingRegisters
start: 3000
length: 10
pollingRate: 100 # polling rate in ms
  • The pollingRate in the brownfieldDevices section defines how often the Modbus registers are read.
  • You can define multiple tables of different types (coils, discreteInputs, holdingRegisters, inputRegisters) to read different types of data from the Modbus device at different polling rates.
  • The start and length parameters define the range of registers to read.
  • The type parameter defines the type of register to read.
  • The pollingRate parameter defines how often the Modbus registers are read.
  • Make sure that tables do not overlap.
  • tha max length of a table is 2000 registers. (limit of the modbus protocol)

mapping a Mobus register to your OPC UA Variable

You can use the m̀apping section in the configuration file to map Modbus registers to OPC UA Variables.

JSONata is used to map the Modbus registers to the OPC UA Variables. The mapping is done in the mapping section of the configuration file.

function namedescription
modbusGetHoldingRegisterreads a holding register and returns the value and status code
modbusGetDiscreteInputreads a discrete input and returns the value and status code
modbusGetCoilreads a coil and returns the value and status code
modbusGetFloat32BEreads a float and returns the value and status code
modbusGetFloat32LEreads a float and returns the value and status code
modbusGetInt32BEreads a int32 and returns the value and status code
modbusGetInt32LEreads a int32 and returns the value and status code
modbusGetInt16reads a int16 and returns the value and status code
modbusGetInt16ArrayBEreads an array of int16 and returns the value and status code
modbusGetInt16ArrayLEreads an array of int16 and returns the value and status code
modbusGetUint16ArrayBEreads an array of uint16 and returns the value and status code
modbusGetUint16ArrayLEreads an array of uint16 and returns the value and status code
modbusGetUint32ArrayBEreads an array of uint32 and returns the value and status code
modbusGetUint32ArrayLEreads an array of uint32 and returns the value and status code
modbusGetFloat32ArrayBEreads an array of float and returns the value and status code
modbusGetFloat32ArrayLEreads an array of float and returns the value and status code
  • the arguments of the functions are the following:

    • connectionName: the name of the Modbus connection as defined in the brownfieldDevices section.
    • address: the address of the starting register
    • count: (for array fu
    • nctions only) the number of values to reads to read
  • most of the time , modbus registers are composed using the big-endian format. However we provide functions to read the registers in little-endian format as well.

  • the first argument is the name of the Modbus connection as defined in the brownfieldDevices section.

  • the second argument is the address of the register

  • the function returns an object with value and statusCode properties. |

When connecting a Modbus device to a non-Modbus network via a gateway, you need obtain documentation from the manufacturer detailing the registers and their addresses. Modbus does not support self-identification of registers, so this information must come from the manufacturer

Modbus TypeType
Coil (Discrete Output)1 bit RW
Discrete Input (or Status Input)1 bit RO
Holding Register16 bit RW
Input Register16 bit RO
mapping:

# read a 32bit value in big-endian format (register 3000 and 3001)
- node: /di:DeviceSet/own:MyObject/own:MyInt32
value: $modbusGetInt32BE("MB1",3000)

# read a 32bit float value in big-endian format (register 3001 and 3002)
- node: /di:DeviceSet/own:MyObject/own:MyFloat1
value: $modbusGetFloat32BE("MB1",3001)

# read a discrete input 16 bit value (input register 2002) and store it to a float with a formula
- node: /di:DeviceSet/own:MyObject/own:MyFloat2
value: |
(
$mb := $modbusGetInt16("MB1",2002);
{
"value": $mb.value / 10.0 + 3.14,
"statusCode": $mb.statusCode
};
)
# read a 16bit value (holding register 3002) and convert it to float
- node: /di:DeviceSet/own:MyObject/own:MyFloat2
value: |
(
$mb := $modbusGetInt16("MB1",3002);
{
"value": $mb.value / 10.0 + 3.14,
"statusCode": $mb.statusCode
};
)

enocoding of other data types

The following table shows how to encode other data types in Modbus. The value field in the mapping section must be a JSON object with the value and statusCode fields.

Flexibility of the mapping

  • You can use the full power of JSONata to map the Modbus registers to the OPC UA Variables. This allows you to perform calculations, transformations, and other operations on the Modbus data before storing it in the OPC UA Variable.

  • When you pass a value to the Variable , the omni-edge will automatically convert the value to the correct data type of the OPC UA Variable (e.g., Int32, Float, etc.). or automatically detect that the uaVariable is array.

  • Whe the UAVariable is an array or a matrix-., you need to pass a array as a vlue the omni-edge will automatically convert the element of the array of the correct data type.

Notes

  • OmniEdge will automatically adapt the Mobdus value to the actual DataType of the OPC UA Variable.

references