Modbus problem: endianness, encodiong, float, int 16bit

I’m using this code and try to get the repsonse value from rs485 but the value is alwasy incorrect, can I know how this is encoded so that i can get the correct value from the serial.

from pylibmodbus import ModbusRtu, get_float

ctx = ModbusRtu(device=b"/dev/rs485", baud=9600, data_bit=8, stop_bit=1, parity=b"N") 
ctx.connect()
ctx.set_response_timeout(100)
ctx.set_slave(1)


def get_float_abcd(data):
    return C.modbus_get_float_abcd(data)

ctx = ModbusRtu(device=b"/dev/rs485", baud=9600, data_bit=8, stop_bit=1,parity=b"N") 
ctx.connect()
ctx.set_response_timeout(10)
ctx.set_slave(1)

for i in range(1,400):
    reg = ctx.read_input_registers(i,2)
    value =get_float_abcd(reg)
    if value != 0 :
        print("Address, AddressValue: ",i,[reg[0],reg[1]],"Value: ",value,sep="\t")


ctx.close()

I got from the script:197749.40625
I got from modbus_db: 62.5 (correct one)

Hello,

May I know if the data is scaled for applied some formula so please tell me the scale factor, then I can fix this problem.

  1. Byte Order: The order in which bytes are arranged into larger numerical values can vary between systems1. This is known as endianness. Some systems use ‘Big-Endian’ and others use ‘Little-Endian’. If the byte order is not correctly interpreted, it can result in incorrect values1.
  2. Data Type: Modbus supports several data types including coils (binary), discrete inputs (binary), input registers (16-bit), and holding registers (16-bit)1. For floating point numbers, two 16-bit registers are combined to form a 32-bit IEEE floating point number1. If the data type is not correctly interpreted, it can result in incorrect values1.
  3. Scaling: Sometimes, values are scaled before being put into Modbus registers1. For example, a floating point number might be multiplied by 100 and then rounded to an integer before being stored. If the scaling is not correctly accounted for, it can result in incorrect values1.
  4. Signed vs Unsigned Values: Modbus can support both signed and unsigned integers1. If a value is interpreted as signed when it should be unsigned (or vice versa), it can result in incorrect values1.

I tried modbus_get_float_abcd but still not work.

Hello,

this is use byte order a,b,c,d, and reg = ctx.read_input_registers(i,2)
value =get_float_abcd(reg)

name Value Value
Address, AddressValue: 1 [52922, 0] Value: -1560281088.0 (Need 230.0 here)
Address, AddressValue: 29 [0, 32831] Value: 4.600602988224807e-41
Address, AddressValue: 30 [32831, 0] Value: -5.7856362579534463e-39
Address, AddressValue: 69 [0, 18242] Value: 2.5562486586213313e-41
Address, AddressValue: 70 [18242, 39921] Value: 49819.94140625
Address, AddressValue: 71 [39921, 31298] Value: -3.9949112784613077e-22
Address, AddressValue: 72 [31298, 7514] Value: 2.519752277422222e+35
Address, AddressValue: 73 [7514, 0] Value: 2.8852059765849605e-21
Address, AddressValue: 75 [0, 18241] Value: 2.556108528774899e-41
Address, AddressValue: 76 [18241, 11698] Value: 49453.6953125
Address, AddressValue: 77 [11698, 44092] Value: 2.0312744541950423e-11
Address, AddressValue: 78 [44092, 12552] Value: -2.6743624675917843e-12
Address, AddressValue: 79 [12552, 0] Value: 1.979060471057892e-09
Address, AddressValue: 85 [0, 22085] Value: 3.0947676584613585e-41
Address, AddressValue: 86 [22085, 13885] Value: 54209185579008.0
Address, AddressValue: 87 [13885, 0] Value: 2.816319465637207e-06
Address, AddressValue: 89 [0, 22085] Value: 3.0947676584613585e-41
Address, AddressValue: 90 [22085, 13885] Value: 54209185579008.0
Address, AddressValue: 91 [13885, 0] Value: 2.816319465637207e-06
Address, AddressValue: 93 [0, 13377] Value: 1.8745169557273078e-41
Address, AddressValue: 94 [13377, 47372] Value: 1.804184535103559e-07
Address, AddressValue: 95 [47372, 0] Value: -0.000133514404296875
Address, AddressValue: 263 [0, 29249] Value: 4.0986578783036575e-41
Address, AddressValue: 264 [29249, 2505] Value: 3.823515931107788e+30
Address, AddressValue: 265 [2505, 0] Value: 4.83889898527293e-33
Address, AddressValue: 341 [0, 31298] Value: 4.3857839336438125e-41
Address, AddressValue: 342 [31298, 7514] Value: 2.519752277422222e+35
Address, AddressValue: 343 [7514, 18497] Value: 2.888941415986912e-21
Address, AddressValue: 344 [18497, 12552] Value: 197828.125 !!I need 62.50 here!!
Address, AddressValue: 345 [12552, 0] Value: 1.979060471057892e-09


Currently, part of the problem is solved, by setting the get_float_dcba(), and address 343-2=341, work,
But, for start adress1, iI dont’t know how to subtract!


Tried many value none of them work.

Hello,

The byte order depends on your devices. It is possible that you need to use a different byte order to interpret the data correctly. So I suggest checking what order works for you.

Keep in mind that RUT/TRB devices use Modbus Register Numbers, while certain third-party devices might use Modbus Register Addresses. The key distinction here is that numbers start from 1, whereas addresses start from 0. So, for instance, if a specific piece of data is stored at Modbus Register Address 101 on the Modbus Slave, you would need to access it from a your RUT956 device by referencing Modbus Register Number 102. So, when using Register Numbers, you would typically add +1 to the Modbus Register Address.

Kind Regards,

This topic was automatically closed after 15 days. New replies are no longer allowed.