####################################### 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: ``/[?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. :ref:`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, :ref:`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: 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)