Since Schneider devices are very common in the industry, maybe some of you may have encountered this problem and can help me.
Trying to read holding registers of a iEM3255 through a COM'X 510 using modbus but I get completely wrong values for both INT64 and FLOAT32 registers.
Registers at page 68: https://download.schneider-electric.com/files?p_enDocType=Catalog&p_File_Name=iEM31003200_UserManual.pdf&p_Doc_Ref=DOCA0005EN-01
Using modpoll with the following command to read FLOAT32 registers I get the correct values:
./modpoll -f -t 4:float -r 3110 -a 1 -1 192.168.97.11 (In this case I'm reading the frequency)
Value: 50.007988
By looking at the "Usage" section of modpoll (https://www.modbusdriver.com/modpoll.html) I notice that by using -f option your slave operates on big-endian 32-bit floats. Looks like this is what is missing for the telegraf plugin to get the correct readings.
Telegraf reading: -2560641796792856000000000000000
Same thing happens by reading INT64 registers but the only way I can check if the values are correct, since modpoll doesn't support INT64 registers, is to read them as INT16 and use this formula to get the correct value as INT64:
281474976710656 * Register1 + 4294967296 * Register2 + 65536 * Register3 + 1 * Register4
Command: ./modpoll -f -t 4:hex -r 3204 -c 4 -a 1 -1 192.168.97.11
Values:
3204: 0000 hex -> 0 dec * 281 474 976 710 656 -> 0 +
3205: 0001 hex -> 1 dec * 4 294 967 296 -> 4 294 967 296 +
3206: 341D hex -> 13341 dec * 65 536 -> 87 4315 776 +
3207: 8443 hex -> 33859 dec * ​ 1 -> 33 859 =
Final value: 5 169 316 931 Wh -> 5.17 GWh
Telegraf reading: 338782i
[[inputs.modbus]]
name = "Slave Test"
slave_id = 1
timeout = "1s"
controller = "tcp://192.168.97.11:502" # Gateway IP - COM'X 510
holding_registers = [
{ name = "frequenza", byte_order = "ABCD", data_type = "FLOAT32-IEEE", scale=0.01, address = [3110,3111]},
{ name = "importazione_energia_attiva_totale", byte_order = "ABCDEFGH", data_type = "INT64", scale=0.000000001, address = [3204,3205,3206,3207]},
]
frequenza: -2560641796792856000000000000000 (Register 3110 - FLOAT32)
importazione_energia_attiva_totale: 338782i (Register 3204 - INT64)
frequenza: 50.007988
importazione_energia_attiva_totale: 5169316931 (converted with the formula I wrote above)
#
If you need more information just let me know!
Thank you for your time.
Hey @ImSteph,
I've looked into importazione_energia_attiva_totale and compared it to the _modpoll_ value you get. Converting both values back to hex I get
hex(5169316931) --> '0x1341d8443'
for you _modpoll_ reference value and
hex(int(338782 / 0.000000001)) --> '0x1341ed4c42c00'
for the raw register reading of _telegraf_.
As you can see, the telegraf reading strangely has an "additional register" (2-bytes) at the end 2c00. If we leave out these additional bytes we get int(0x1341ed4c4) --> 5169403076 which is approximately the value you are searching...
To me it seems like _modpoll_ starts the registers at one while _telegraf_ is zero-based! So to get the correct readings you should subtract 1 from your registers in the telegraf config. Could you please give it a try!?
Furthermore, did you get the register values from a datasheet? For me I always used the datasheet values for different sensors (no Schneider thou) and got correct values which indicates that those registers specifications follow the telegraf schema...
Additional comment:
The modbus specification clearly states that input register addresses start at zero (section 6.4 in Modbus Specification). It seems that _modpoll_ starts registers at 1 (see comment for -r option) but also specifies the zero-based addressing through the -0 option...
So I'm pretty sure that using
holding_registers = [
{ name = "frequenza", byte_order = "ABCD", data_type = "FLOAT32-IEEE", scale=0.01, address = [3109,3110]},
{ name = "importazione_energia_attiva_totale", byte_order = "ABCDEFGH", data_type = "INT64", scale=0.000000001, address = [3203,3204,3205,3206]},
]
you get exactly the values you are looking for.
Thanks @srebhan, that solved my issue!
By the way to check the correct values I used Schneider's web interface and the registers' indexes from the datasheet I linked at the start.
I've actually had a similar problem some time ago and I totally forgot about the starting register.
Moving back all register by one worked flawlessly thank you!
Thanks for the fast response!
Stefano
Can you please close the issue if it is resolved. :-)