Networking

How do I find the byte order of a Modbus float value?

Short answer

A 32-bit float spans two 16-bit Modbus registers. Devices may order those registers and their bytes differently; common orders are ABCD, CDAB, BADC and DCBA. Test each order against a known value, such as 25.0 (0x41C80000), and confirm the chosen order with a second known value.

Why there are four orders

The Modbus specification defines 16-bit registers and their values, but not floating-point types. The device manufacturer therefore decides how a 32-bit float is split across two registers, and documents the result.

Label the four bytes of the float A (most significant) to D (least significant). Within each register, Modbus sends the high byte first (big-endian). The orders differ in two ways: which register comes first, and whether the bytes inside each register are swapped. ABCD keeps the natural order. CDAB swaps the two registers. BADC swaps the bytes inside each register. DCBA reverses the whole byte sequence.

The datasheet should name the order the device uses. When it does not, the four candidates cover the usual cases.

Worked example: 25.0 in four orders

Hypothetical example: a sensor reports 25.0. In IEEE 754 single precision, 25.0 is 0x41C80000: sign 0, exponent 10000011, fraction 1001 followed by zeros. The four bytes are A = 0x41, B = 0xC8, C = 0x00 and D = 0x00.

  • ABCD: register 1 = 0x41C8, register 2 = 0x0000 (decimal 16840 and 0)
  • CDAB: register 1 = 0x0000, register 2 = 0x41C8 (decimal 0 and 16840)
  • BADC: register 1 = 0xC841, register 2 = 0x0000
  • DCBA: register 1 = 0x0000, register 2 = 0xC841

If the device sends ABCD and you decode as CDAB, the bits form 0x000041C8. That is a value of about 2.4e-41, effectively zero, and nothing signals an error. Compare the result with what the process actually shows.

Common mistakes

The first mistake is addressing. Register references such as 40001 are usually 1-based, while the protocol address starts at 0, so 40001 is requested as address 0. Some manuals give 0-based addresses directly, so check which convention applies. An off-by-one error reads a neighbouring register, which is hard to spot when the neighbour is also a plausible number.

The second mistake is reading the two registers in separate requests. If the process changes between them, the value combines two moments. Read both registers in one request.

The third mistake is trusting one plausible value. Some wrong orders produce reasonable-looking numbers. A second known value, such as a reading from a local gauge, is the most reliable check.

Follow-up questions

Which function code should I use to read a float?

Function code 03 reads holding registers and 04 reads input registers. A float needs two consecutive 16-bit registers, so read both in one request. The device documentation states which register table holds the value.

What if the device stores the value as an integer?

Some devices store the value as one 16-bit integer with a scale factor. Word order does not apply in that case. The scale factor, and whether the value is signed or unsigned, must come from the device documentation.

Sources

Example numbers are hypothetical, not measured field results.

Related questions

All questions