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
pollingRatein thebrownfieldDevicessection 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
startandlengthparameters define the range of registers to read. - The
typeparameter defines the type of register to read. - The
pollingRateparameter 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 name | description |
|---|---|
| modbusGetHoldingRegister | reads a holding register and returns the value and status code |
| modbusGetDiscreteInput | reads a discrete input and returns the value and status code |
| modbusGetCoil | reads a coil and returns the value and status code |
| modbusGetFloat32BE | reads a float and returns the value and status code |
| modbusGetFloat32LE | reads a float and returns the value and status code |
| modbusGetInt32BE | reads a int32 and returns the value and status code |
| modbusGetInt32LE | reads a int32 and returns the value and status code |
| modbusGetInt16 | reads a int16 and returns the value and status code |
| modbusGetInt16ArrayBE | reads an array of int16 and returns the value and status code |
| modbusGetInt16ArrayLE | reads an array of int16 and returns the value and status code |
| modbusGetUint16ArrayBE | reads an array of uint16 and returns the value and status code |
| modbusGetUint16ArrayLE | reads an array of uint16 and returns the value and status code |
| modbusGetUint32ArrayBE | reads an array of uint32 and returns the value and status code |
| modbusGetUint32ArrayLE | reads an array of uint32 and returns the value and status code |
| modbusGetFloat32ArrayBE | reads an array of float and returns the value and status code |
| modbusGetFloat32ArrayLE | reads 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 thebrownfieldDevicessection.address: the address of the starting registercount: (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
brownfieldDevicessection. -
the second argument is the address of the register
-
the function returns an object with
valueandstatusCodeproperties. |
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 Type | Type | |
|---|---|---|
| Coil (Discrete Output) | 1 bit RW | |
| Discrete Input (or Status Input) | 1 bit RO | |
| Holding Register | 16 bit RW | |
| Input Register | 16 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.