Logic Machine Forum
Modbus, reading registers with strings - 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: Modbus, reading registers with strings (/showthread.php?tid=1245)



Modbus, reading registers with strings - schippi - 20.02.2018

Hello,

I'm using  a json profile to read modbus registers from a 4g router.
Reading normal values work perfect but I didn't find a solution how to read out 16 registers and convert it to string format.

A possible solution in LUA is also welcome.

Definition:
   

Thank you  in advance,

Uwe


RE: Modbus, reading registers with strings - Erwin van der Zwart - 20.02.2018

Hi Uwe,

Can you try this? I'm not sure how the chars are written in the register so it could not work like this (maybe it's HEX based)

require('luamodbus')
mb = luamodbus.rtu()
mb:open('/dev/RS485', 19200, 'E', 8, 1, 'H')
mb:connect()
mbConfusedetslave(1)
r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16 = mb:readregisters(7,16)
result = lmcore.inttostr(r1) .. lmcore.inttostr(r2) .. lmcore.inttostr(r3) .. lmcore.inttostr(r4) .. lmcore.inttostr(r5) .. lmcore.inttostr(r6) .. lmcore.inttostr(r7) .. lmcore.inttostr(r8) .. lmcore.inttostr(r9) .. lmcore.inttostr(r10) .. lmcore.inttostr(r11) .. lmcore.inttostr(r12) .. lmcore.inttostr(r13) .. lmcore.inttostr(r14) .. lmcore.inttostr(r15) .. lmcore.inttostr(r16)
log(result)
mb:close()

BR,

Erwin


RE: Modbus, reading registers with strings - schippi - 21.02.2018

Hello Erwin,

many thanks!

I tried your code, but unfortunately I got no result anywhere. "log(result)" serves nothing! It looks like the code stops at the (in homelynk unknown ?) function called "lmcore.inttostr()" ???
Code:
require('luamodbus')
mb = luamodbus.tcp()

mb:open('192.168.2.1', 502)
mb:connect()

r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16 = mb:readregisters(71,16)
log(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16)

result = lmcore.inttostr(r1) .. lmcore.inttostr(r2) .. lmcore.inttostr(r3) .. lmcore.inttostr(r4) .. lmcore.inttostr(r5) .. lmcore.inttostr(r6) .. lmcore.inttostr(r7) .. lmcore.inttostr(r8) .. lmcore.inttostr(r9) .. lmcore.inttostr(r10) .. lmcore.inttostr(r11) .. lmcore.inttostr(r12) .. lmcore.inttostr(r13) .. lmcore.inttostr(r14) .. lmcore.inttostr(r15) .. lmcore.inttostr(r16)

log(result)
mb:close()

I read out the registers 71 to 87 which should contain the router name: "RUT955" and  logged the variables (r1 to r16) directly and this is the current log

Code:
RouterModbus 21.02.2018 20:07:10
* arg: 1
 * number: 21077
* arg: 2
 * number: 21561
* arg: 3
 * number: 13621
* arg: 4
 * number: 18487
* arg: 5
 * number: 22064
* arg: 6
 * number: 12848
* arg: 7
 * number: 0
* arg: 8
 * number: 0
* arg: 9
 * number: 0
* arg: 10
 * number: 0
* arg: 11
 * number: 0
* arg: 12
 * number: 0
* arg: 13
 * number: 0
* arg: 14
 * number: 0
* arg: 15
 * number: 0
* arg: 16
 * number: 0


I attached the routers short modbus manual.

B.R,

Uwe


RE: Modbus, reading registers with strings - Erwin van der Zwart - 21.02.2018

Hi Uwe,

Thanks for the values, now i could figure out that each register holds 2 chars.

Try this (:

PS: Result is RUT955H7V020

Code:
require('luamodbus')
mb = luamodbus.tcp()

mb:open('192.168.2.1', 502)
mb:connect()

r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16 = mb:readregisters(71,16)

function twobytetochars(value)
 charsvalue = lmcore.hextostr(lmcore.inttohex(value,2))
 return charsvalue
end

if r1 then r1 = twobytetochars(r1) else r1 = "" end
if r2 then r2 = twobytetochars(r2) else r2 = "" end
if r3 then r3 = twobytetochars(r3) else r3 = "" end
if r4 then r4 = twobytetochars(r4) else r4 = "" end
if r5 then r5 = twobytetochars(r5) else r5 = "" end
if r6 then r6 = twobytetochars(r6) else r6 = "" end
if r7 then r7 = twobytetochars(r7) else r7 = "" end
if r8 then r8 = twobytetochars(r8) else r8 = "" end
if r9 then r9 = twobytetochars(r9) else r9 = "" end
if r10 then r10 = twobytetochars(r10) else r10 = "" end
if r11 then r11 = twobytetochars(r11) else r11 = "" end
if r12 then r12 = twobytetochars(r12) else r12 = "" end
if r13 then r13 = twobytetochars(r13) else r13 = "" end
if r14 then r14 = twobytetochars(r14) else r14 = "" end
if r15 then r15 = twobytetochars(r15) else r15 = "" end
if r16 then r16 = twobytetochars(r16) else r16 = "" end

result = r1 .. r2 .. r3 .. r4 .. r5 .. r6 .. r7 .. r8 .. r9 .. r10 .. r11 .. r12 .. r13 .. r14 .. r15 .. r16
log(result)

mb:close()
BR,

Erwin


RE: Modbus, reading registers with strings - admin - 22.02.2018

More universal solution:
Code:
require('luamodbus')
mb = luamodbus.tcp()

mb:open('192.168.2.1', 502)
mb:connect()

function readstring(mb, address, length)
  local data = { mb:readregisters(address, length) }
  local bytes = {}

  for _, reg in ipairs(data) do
    if type(reg) == 'number' then
      -- high 8 bits
      local b1 = bit.band(bit.rshift(reg, 8), 0xFF)
      if b1 > 0 then
        bytes[ #bytes + 1 ] = b1
      end

      -- low 8 bits
      local b2 = bit.band(reg, 0xFF)
      if b2 > 0 then
        bytes[ #bytes + 1 ] = b2
      end
    end
  end

  -- convert table of byte values to string
  return string.char(unpack(bytes))
end

result = readstring(mb, 71, 16)
log(result)

mb:close()



RE: Modbus, reading registers with strings - schippi - 22.02.2018

Hello Erwin,

the result is:

RouterModbus2 22.02.2018 11:46:00
* string: RUT955H7V02043

Your solution works perfect and i prefer the second one, caused on it's flexibility! Big Grin 

I'll give you a very big "THANK YOU" for your enthusiastic service Exclamation

Have a nice day and b. r.,

Uwe

PS.: I know, that the success of this product depends essentially on such colleagues as you.