Posts: 7
Threads: 2
Joined: Oct 2016
Reputation:
0
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
Posts: 1800
Threads: 7
Joined: Jul 2015
Reputation:
120
20.02.2018, 22:23
(This post was last modified: 20.02.2018, 22:23 by Erwin van der Zwart .)
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()
mb
etslave(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
Posts: 7
Threads: 2
Joined: Oct 2016
Reputation:
0
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:
1 2 3 4 5 6 7 8 9 10 11 12 13
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
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
Attached Files
Posts: 1800
Threads: 7
Joined: Jul 2015
Reputation:
120
21.02.2018, 21:56
(This post was last modified: 21.02.2018, 22:00 by Erwin van der Zwart .)
Hi Uwe,
Thanks for the values, now i could figure out that each register holds 2 chars.
Try this (:
PS: Result is
RUT955H7V020
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
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
Posts: 8130
Threads: 43
Joined: Jun 2015
Reputation:
471
More universal solution:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
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
local b1 =
bit.band (
bit.rshift (
reg ,
8 ),
0xFF )
if b1 >
0 then
bytes [ #
bytes +
1 ] =
b1
end
local b2 =
bit.band (
reg ,
0xFF )
if b2 >
0 then
bytes [ #
bytes +
1 ] =
b2
end
end
end
return string.char (
unpack (
bytes ))
end
result =
readstring (
mb ,
71 ,
16 )
log (
result )
mb :
close ()
Posts: 7
Threads: 2
Joined: Oct 2016
Reputation:
0
22.02.2018, 10:57
(This post was last modified: 22.02.2018, 11:01 by schippi .)
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!
I'll give you a very big
"THANK YOU" for your enthusiastic service
Have a nice day and b. r.,
Uwe
PS.: I know, that the success of this product depends essentially on such colleagues as you.