Serving database points as modbus slave

Actiweb 9 can serve database points as a modbus slave device. Points can be mapped to registers by adding a modbusMapping field to a point and assigning a configuration value to said field. Configuration value is made of multiple parts.

Configuration value

Configuration value uses following pattern:

<register type>/<register address>[?firstParameter=value...&LastParameter=value]

Example: holding/332?size=2&datatype=int32&scale=0.01

Explanation:
  • holding: register type is holding

  • 332: register address is 332

  • size=2 register is 32-bit long. Default size is 16-Bits if not given.

  • datatype=int32 datatype is int32. Defaults to uint16 if not given.

  • scale=0.01 0.01 scaling is done on the value when communicating in modbus. More examples

Register type

Register type determines which kind of register the value should be mapped to

Possible values:
  • holding

  • input

  • coil

  • discrete

Register Address

Register address can be anything from 0 to 65535

Attention

Known issue: Last (i.e. largest address number) register in the modbusMapping list needs to be a regular 16bit register. If last register is larger than 16bits the bits after 16 will be “cut off” and the last register will not work as expected.

Parameters

modbusMapping has two special prameters that are unique to it’s functionality:

Size:
  • Only works on holding registers

  • Determines the size of the modbus register in word size (16-bit or two bytes). defaults to 1, i.e. one register is 16-bits

  • Example: if the parameter is size=2 the register is considered as 32-bit register. Maximum size is 4 (64-bits).

  • Keep in mind that if mapping is holding/10?size=2 the next free register is at holding/12 as 32-bit register takes the size of two regular registers

  • If registers collide (one register would overwrite another) StatusWarning is set for the application and “error” is written to mapping field on the related point

Field:
  • By default modbus mapping is done on the points pv-field, but other fields can be used by using field-paramter

  • Example: if field=srcCommStatus the value of srcCommStatus would be mapped to modbus instead of the value of pv

In addition to the previous parameters, the same parameters that can be used on dataUrls (dataSource and dataTarget) can also be used on modbusMapping.

Important

Because modbus register values are always integers, scaling is needed almost always when mapping analog values, as pv values are handled as floats (decimal numbers).

Scale examples when serving values to modbus:
  • scale=0.01 pv: 28,321 => modbus register value 2832

  • scale=0.1 pv: 28,321 => modbus register value 282

  • scale=1 pv: 28,321 => modbus register value 28

And the other way around: if mapped register has a scale of 0.1 and a value of 223512 is written to the modbus register pv will be 22351.2

Supported Function Codes

Actiweb 9 supports following function codes in modbus slave mode:
  • 1 : Read coils

  • 2 : Read discretes

  • 3 : Read holdings

  • 4 : Read inputs

  • 6 : Write single holding

  • 16 : Write multiple holding

Requests with other function codes will be replied with modbus exception respones code 1 (Illegal Function)