This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

F&F LE-03MQ Modbus energy counter
#1
Hello,

I try integrate above modbus energy counter but it has a little special conditions. It has 66 registers(float16) and on 1 request it is possible to read only 40. So LM must request 2 times. Is this possible by Modbus mapper or I must prepare script and connect this counter to other RS-485?

Is this possible to divide the profile to 2 parts and use read_delay parameter and some shift for start register for second one?
Reply
#2
Hi,

Why do you want to read all registers at once?

Normaly you read the registers by value point, most of the time as 1,2 or 4 registers at once depending on the value type (16, 32 or 64 bits).

As far as i know this is the same for the modbus mapper, there we specify them also as 16, 32 or 64 bits and that is equal to 1, 2 or 4 registers.

BR,

Erwin
Reply
#3
I thinked that mapper read all data at once and I saw in the counter's manual that it is not possible. I see also in instruction that there are 3 function commands by which I can read a data:
function 04 - is for reading measured data,
function 03 - is for checking parameters of counter,
function 16 - is for changing parameters of counter.

Where can I type this function code and also the other question is that LM sends 03 command for reading or other?

I must tell that this is much more complicated Modbus device for me than others beforeWink
Reply
#4
Hi,

Function codes are equal to read register, read input register, read coil, write register etcetera. 

Function codes are normal for modbus, nothing special.

In my opinion you must create a normal profile with 66 points and read the device just like any other device.

BR,

Erwin
Reply
#5
Thanks for your very helpful and fast answer Erwin. If it is about this function code and possibility to read and write parameters(function codes 03 and 16) for this counter there is a little problem because the measured values registers starts from register 0 and parameters starts also from register 0 so I don't know how can I use parameters when I will use measured values(they are more important).
Reply
#6
Hi,

Yes the different function codes can have equal addresses, by specifying read register or read input register you get the data from different registers. (different device table)

http://www.simplymodbus.ca/FAQ.htm#FC

For function code 3 you need mapping field type 'register' and for function code 16 you also need mapping field type 'register' , mapping field 'writable' as true and you need to add the mapping field 'write_multiple' and set it to 'true' 

See also: http://openrb.com/docs/modbus.htm for mapping fields

BR,

Erwin
Reply
#7
I try read properly L1 voltage which should be ~230V. In the manual there is the information that every value is hold in 2 x float16 registers so I've tried such json definition:
{ "address": 0, "read_count": 2, "name": "Napięcie fazowe L1", "bus_datatype": "float32", "type": "register", "datatype": "float16", "units": "V", "writable": false }

And the result is 1597.440V so there is some bad in my definition.
Reply
#8
Hi,

Just checked manual and you should try type inputregister instead of register

BR,

Erwin
Reply
#9
0/00 (Dec/Hex)

I've tried in Read test Holding register and float32 and then the result is 2.37 which is much more similar(x10) to real value. But when I've tried use read test with the same parameters for checking frequency the result is 0.


What is the difference between read 2x float16 registers and read 1x float32 register?
Reply
#10
Hi,

Registers are always 16 bits, so float32 is divided over 2 registers, please try type inputregister (function code 4 according to manual)

BR,

Erwin
Reply
#11
(22.09.2017, 20:09)Erwin van der Zwart Wrote: Hi,

Registers are always 16 bits, so float32 is divided over 2 registers, please try type input register (function code 4 according to manual)

BR,

Erwin

Yes, this was the cause, but for the frequency this is not solution, but I will be 100% confident when I will tomorrow connect counter as should be because now it is only connected to 1 phase and frequency is the parameter of all 3 phases so it could be the cause of this second issue. Thanks Erwin, you're the bestWink

After a few minutes, register starts respond. A little strange but true. But still there are some errors in communication(timeout errors).
Reply
#12
Hi,

Have you tried to set the timeout in the device parameters? (default is 0.5 so set it to 1 or something) or maybe you need to place a EOL terminator. (not sure it's build in)

BR,

Erwin
Reply
#13
I set the interval 10s and 3s for timeout. I will check EOL tomorrow. Every 3 requests there is 1 with timeout error.
Reply
#14
If admin can say how precisely modbus mapper works. Timeouts, intervals and how mapper reads every devices.
Reply
#15
Each register is read separately by default. You can use read_count and read_offset to read a range in one request. There's no extra delay between reads in a single polling cycle. Delay between cycles is specified by the user. Default timeout for RTU is 0.5 seconds, but can also be configured.
Reply
#16
Thanks for clear info. Can you provide some example for modbus rtu by script(of course on other rs-485 input)?  Every inputregister is float32 and read_swap is "w".
Reply
#17
Hi,

Try this: ( i think your second port is RS485-2 but please check this )

Code:
require('luamodbus')
mb = luamodbus.rtu()
mb:open('/dev/RS485-2', 9600, 'N', 8, 1, 'H')
mb:connect()
mb:setslave(1)

-- L1 - N
r1, r2 = mb:readinputregisters(0, 2) 
if r1 then 
  value = lmcore.inttohex(r1, 2) .. lmcore.inttohex(r2, 2) 
  value = knxdatatype.decode(value, dt.float32)  
 currentvalue = grp.getvalue('32/1/1') 
  if currentvalue ~= value then
    grp.update('32/1/1', value)
  end
end

-- L2 - N
r1, r2 = mb:readinputregisters(2, 2) 
if r1 then 
  value = lmcore.inttohex(r1, 2) .. lmcore.inttohex(r2, 2) 
  value = knxdatatype.decode(value, dt.float32)  
  currentvalue = grp.getvalue('32/1/2') 
  if currentvalue ~= value then
    grp.update('32/1/2', value)
  end
end

-- L3 - N
r1, r2 = mb:readinputregisters(4, 2) 
if r1 then 
  value = lmcore.inttohex(r1, 2) .. lmcore.inttohex(r2, 2) 
  value = knxdatatype.decode(value, dt.float32)  
  currentvalue = grp.getvalue('32/1/3') 
  if currentvalue ~= value then
    grp.update('32/1/3', value)
  end
end

mb:close()

BR,

Erwin
Reply
#18
While Erwin's code works it easier to use built-in datatype read function:
Code:
-- read 32-bit floating point value from input register nr 123, use word swap
res, err = mb:readinputregistervalue(123, "float32", "w")
Reply
#19
I've been on the installation exceptionally today and the main cause was that I've connected the cable like on the diagram A. When I've connected this energy like on diagram B, there are still timeouts only on energy meter but 1 time for 1 hour on settings reading every 10s with timeout 3s. Now I also changed 10s to 30s.

Attached Files
.svg   Diagram A.svg (Size: 21.81 KB / Downloads: 42)
.svg   Diagram B.svg (Size: 25.51 KB / Downloads: 20)
Reply
#20
(23.09.2017, 16:38)uadmin Wrote: While Erwin's code works it easier to use built-in datatype read function:
Code:
-- read 32-bit floating point value from input register nr 123, use word swap
res, err = mb:readinputregistervalue(123, "float32", "w")

Aha, i thought i know most stuff by now but still new items to discover (:

Is this all documented somewhere? 

Thanks admin!

BR,

Erwin

Hi Buuuudzik,

Modbus specification specify daisy chain ( in -> out ) and not a star topology...

The reflections in your star can cause weird behavior..

BR,

Erwin
Reply


Forum Jump: