← Articles
Modbus/6 min read/ views

When a Modbus Float Reads 1.2e-41: Getting Byte and Word Order Right

Modbus has no standard endianness for 32-bit values, so two registers can decode to garbage. Proving byte and word order on site instead of guessing.

ModbusTroubleshootingCommissioningSCADATags

The register address is only half the answer

A Modbus register map may say that a flow value is at 40021 and uses two holding registers. That still does not tell the whole story. The SCADA driver must also know how bytes and words are ordered when those two 16-bit registers become one 32-bit value.

This problem shows up during commissioning as values that are stable but obviously wrong:

  • A temperature reads 1.2e-41 instead of 84.7.
  • A totalizer jumps by huge amounts after restart.
  • A signed value looks correct until it crosses zero.
  • A vendor test tool works, but the HMI tag does not.

Here is the root cause. The Modbus Application Protocol Specification (V1.1b3) defines a register as 16 bits and says nothing about how to combine two of them into a 32-bit value. There is no standard endianness in the protocol. Every 32-bit float, long integer, and packed double word is a convention the vendor bolted on top. So treat byte order and word order as part of the interface spec, not a driver checkbox you sort out later.

Name the four common 32-bit layouts

For a 32-bit value split across two registers, engineers usually describe the layout by byte order inside each register and word order between registers. Unfortunately, different tools use different labels. Write the actual byte sequence in the project note.

Assume the real 32-bit bytes are A B C D.

Field layoutRegister NRegister N+1Common label
AB CDABCDBig-endian word order
CD ABCDABWord swapped
BA DCBADCByte swapped per register
DC BADCBAByte and word swapped

Many PLCs and meters use AB CD for documentation examples, but gateways often expose configuration choices such as normal, swap words, swap bytes, or swap both. Do not rely on the label alone. Test with a known value.

The one that bites most, in my experience, is word swap (CD AB). Plenty of energy meters and drive gateways store the low word first while their manual prints the value big-endian. So if a float comes out wildly wrong but the sign looks plausible, try a word swap before you touch anything else — it clears more startup tickets than the other three layouts combined.

Commission with values that prove the order

A single live process value is a poor test. A temperature of 25.0 may produce several wrong-looking but not impossible values depending on scaling. Use a test value that makes byte and word errors obvious.

Good commissioning methods:

  • Ask the device vendor for a register map example with raw register values and decoded engineering value.
  • Force a simulator value such as IEEE-754 float 123.456 and record the two raw registers.
  • For integer counters, use a value above 65535 so the high word is not zero.
  • For signed integers, test one positive value and one negative value.
  • For scaled integers, document both raw count and scale factor.

Example note for a flow meter:

Tag: FT101_TOTAL_M3
Modbus: holding registers 40210-40211
Type: unsigned 32-bit integer
Raw test value: 0x0001 0x86A0
Decoded value: 100000 m3
Driver setting: word order normal, byte order normal
Scale: raw x 1.0

This note is more useful than saying "32-bit unsigned" because it captures the actual layout proven in the field.

Separate scaling problems from ordering problems

Byte or word order errors often get confused with scaling errors. Diagnose them separately.

SymptomLikely causeCheck
Value is wildly tiny or huge for a floatWord or byte orderView raw hex registers and try all four layouts in a calculator
Value is exactly 10, 100, or 1000 times offScale factor or unitCompare raw count and engineering unit in vendor manual
Value is correct below 32767 but wrong above itSigned/unsigned mismatchCheck whether the device sends int16, uint16, int32, or uint32
Value resets around 65535Only one register is being readConfirm the driver tag length and starting address
Value changes but jumps in blocksWrong word used or stale registerRead both registers in one request if possible

Do not fix an endian problem by adding a strange multiplier. That may make one test point look right while the whole operating range remains wrong.

Watch addressing conventions at the same time

Byte order is not the only Modbus convention that causes off-by-one mistakes. While proving a multi-register value, also record the addressing convention used by the driver.

Common sources of mismatch:

  • Documentation says 40001, while the driver wants zero-based address 0.
  • A gateway calls the first holding register 1, while a PLC driver calls it 400001.
  • Input registers and holding registers have separate address spaces but similar numbers.
  • A 32-bit value starts at an odd register and the driver assumes even alignment.
  • The driver reads register N and N+1, while the device documentation lists high word and low word in reverse order.

When possible, capture one Modbus poll in Wireshark or the driver diagnostic log. It gives you the function code, starting address, quantity, and returned bytes. That removes a lot of debate.

Packed status words need bit numbering notes

The same issue appears in packed status registers. A manual may say "bit 0 = running" and "bit 8 = fault," but HMI tools may display bits left-to-right or right-to-left. Some drivers number bits from 1 instead of 0.

For each packed register, document:

  • Register address and function code.
  • Whether bit numbering is 0-based or 1-based.
  • Which bit is least significant bit (LSB).
  • Whether alarm bits are active-high or active-low.
  • Whether a bit is momentary, latched, or valid only in a specific mode.

Test packed bits by forcing one status at a time if the device allows it. If not, use a known machine state such as stopped, running, interlocked, and faulted, then compare the raw register value to the expected bit pattern.

What goes in the point list before handover

Before handing over the Modbus point list, make sure the project record includes:

  • Raw register examples for at least one float, one 32-bit integer, and one packed status word.
  • Driver settings for byte order and word order, written as byte sequence where possible.
  • Addressing convention used by the SCADA driver.
  • Signedness, scale factor, unit, and engineering range.
  • Poll grouping notes for multi-register values so words are read consistently.
  • Screenshots or logs from the device, driver, or packet capture used to prove the value.

It is ten minutes of paperwork against the worst Modbus failure mode there is: a value that updates, trends, and alarms like it is healthy while quietly reporting the wrong number.