LM as Modbus TCP Slave
Example: LM as Modbus TCP Slave, interconnection with PLC
Task
Interconnect LogicMachine with PLC and HMI panel over Modbus TCP.
Resident script
Sleep time = 0. It only supports binary objects as coils and 1-byte / 2-byte integer objects as registers. Number of coils and registers is not limited, object mapping can be set by filling coils, registers and regdt tables.
- if not mb then
- require('genohm-scada.eibdgm')
- require('luamodbus')
-
- -- list of coil mapping, starting from 0
- coils = { '1/1/1', '1/1/2' }
-
- -- list of register mapping, starting from 0
- registers = { '2/2/2', '3/3/3' }
-
- -- list of register data types, element count must match registers table
- regdt = { dt.int8, dt.uint16 }
-
- -- knx group write callback
- function knxgroupwrite(event)
- local value
-
- -- try to find matching coil
- for id, addr in ipairs(coils) do
- if event.dst == addr then
- value = knxdatatype.decode(event.datahex, dt.bool)
- mb:setcoils(id - 1, value)
- end
- end
-
- -- try to find matching register
- for id, addr in ipairs(registers) do
- if event.dst == addr then
- value = knxdatatype.decode(event.datahex, regdt[ id ])
- mb:setregisters(id - 1, value)
- end
- end
- end
-
- -- coil write callback
- function mbwritecoils(coil, value)
- local addr = coils[ coil + 1 ]
- if addr then
- grp.write(addr, value, dt.bool)
- end
- end
-
- -- register write callback
- function mbwriteregisters(register, value)
- local addr = registers[ register + 1 ]
- if addr then
- grp.write(addr, value, regdt[ register + 1])
- end
- end
-
- -- knx group monitor, handles group writes
- knxclient = eibdgm:new({ timeout = 0.1 })
- knxclient: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(#coils, 0, #registers, 0)
-
- -- init coils
- for id, addr in ipairs(coils) do
- value = grp.getvalue(addr)
- mb:setcoils(id - 1, value)
- end
-
- -- init registers
- for id, addr in ipairs(registers) do
- value = grp.getvalue(addr)
- mb:setregisters(id - 1, value)
- end
-
- -- set callbacks for coil and register write
- mb:setwritecoilcb(mbwritecoils)
- mb:setwriteregistercb(mbwriteregisters)
- end
-
- -- handle modbus and knx
- mb:handleslave()
- knxclient:loop(0.1)