Logic Machine Forum
Gateway Modbus RTU to Modbus TCP - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Gateway (https://forum.logicmachine.net/forumdisplay.php?fid=10)
+--- Thread: Gateway Modbus RTU to Modbus TCP (/showthread.php?tid=2078)



Gateway Modbus RTU to Modbus TCP - davidsilva - 10.05.2019

Hi,

I have 4 meters connected by Modbus RTU (attachment).

I would like that the Logic Machine works as a Modbus TCP Slave with this 4 meters and with same ID and registers, and then connect to other device. I.e. the Logic Machine works as a Gateway Modbus RTU to Modbus TCP.

Best regards,


RE: Gateway Modbus RTU to Modbus TCP - admin - 11.05.2019

This is not possible with default Modbus TCP slave as it only supports one slave ID / one set of registers. One solution is to use single slave ID but different registers addresses for each RTU slave.


RE: Gateway Modbus RTU to Modbus TCP - EBMel - 12.05.2019

Will it be possible to program the LogicMachine so that the meter 1 will useĀ  Modbus TCP slaveĀ register 1-100, meter 2 register 101-200 ........?

The Modbus TCP slave exampel only shows register starting from 1.

An exampel/instructions where defined registerts are set would be great!


RE: Gateway Modbus RTU to Modbus TCP - admin - 13.05.2019

Actual Modbus addressing starts from 0. Documentation for some devices have addressing starting from 1 which creates confusion.

Here's modified slave script where you can specify addresses directly and there can be gaps in register map, for example: 0..15 for meter 1; 100..115 for meter 2 etc.

This script supports 16-bit values only. If only one way communication is needed (Modbus values are read-only) then it can be modified to support 32-bit and 64-bit values internally without additional scripts for splitting values into 16-bit parts.

Code:
if not mb then
  require('luamodbus')

  -- list of coil mapping, register mapping and register data types
  coils, registers, regdt = {}, {}, {}

  -- coil definition
  coils[ 0 ] = '1/1/1'
  coils[ 1 ] = '1/1/2'

  -- register definition
  registers[ 0 ] = '2/2/2'
  regdt[ 0 ] = dt.int8
  
  registers[ 1 ] = '2/2/3'
  regdt[ 1 ] = dt.uint16

  -- knx group write callback
  function knxgroupwrite(event)
    local value

    -- try to find matching coil
    for id, addr in pairs(coils) do
      if event.dst == addr then
        value = busdatatype.decode(event.datahex, dt.bool)
        mb:setcoils(id, value)
      end
    end

    -- try to find matching register
    for id, addr in pairs(registers) do
      if event.dst == addr then
        value = busdatatype.decode(event.datahex, regdt[ id ])
        mb:setregisters(id, value)
      end
    end
  end

  -- coil write callback
  function mbwritecoils(coil, value)
    local addr = coils[ coil ]
    if addr then
      grp.write(addr, value, dt.bool)
    end
  end

  -- register write callback
  function mbwriteregisters(register, value)
    local addr = registers[ register ]
    if addr then
      grp.write(addr, value, regdt[ register])
    end
  end

  -- knx group monitor, handles group writes
  busclient = require('localbus').new(0.1)
  busclient:sethandler('groupwrite', knxgroupwrite)

  -- modbus slave, listen on all interfaces and default port 502
  mb = luamodbus.tcp()
  mb:open('0.0.0.0', 502)

  -- setting slave id is optional
  -- mb:setslave(1)

  mb:setreceivetimeout(0.1)
  mb:setmapping(table.maxn(coils) + 1, 0, table.maxn(registers) + 1, 0)

  -- init coils
  for id, addr in pairs(coils) do
    value = grp.getvalue(addr)
    mb:setcoils(id, value)
  end

  -- init registers
  for id, addr in pairs(registers) do
    value = grp.getvalue(addr)
    mb:setregisters(id, value)
  end

  -- set callbacks for coil and register write
  mb:setwritecoilcb(mbwritecoils)
  mb:setwriteregistercb(mbwriteregisters)
end

-- handle modbus and knx
mb:handleslave()
busclient:step()