Shopfloor

Modbus register decoder & byte-order check

Decode two Modbus registers as float32, int32 and uint32 in all four byte orders (ABCD, CDAB, BADC, DCBA), test each against known readings, and print the comparison card.

Register values are

Reading 1

Reading 2 optional

Reading 3 optional

Enter registers as read, lower address first — don't pre-swap them. A 0x prefix always means hex. Tolerance left blank is half the last digit of the device value (230.5 → ±0.05); type an amount (0.2) or a percentage (0.5%) to override. Results update as you type and stay in this browser.

From the maintainer: Understanding the Shop Floor — a practical companion to the systems behind these tools; also How to Remain Valuable When Intelligence Becomes Cheap — on staying valuable as AI and automation reshape engineering work.

Paste the two 16-bit registers exactly as your master, gateway or scan tool read them — lower address first — and the table shows every way they can be put together. Add what the device itself displays for up to three readings and each of the 12 interpretations (4 byte orders × float32, int32, uint32) is kept or eliminated. Everything is computed in your browser; the page cannot contact a PLC or device, and it never builds a Modbus request.

Why a Modbus float reads completely wrong

The Modbus application protocol defines 16-bit registers and sends each one most-significant byte first. That is all it defines. A 32-bit float, a 32-bit counter or a 32-bit setpoint has to be spread across two registers, and the specification does not say which register holds the upper half — or whether the bytes inside each register are swapped as well. Each manufacturer chose, and drivers, gateways and SCADA packages each picked a default.

When the master's assumption differs from the device's, the result is rarely a little off. An IEEE 754 float32 packs a sign bit, eight exponent bits and 23 fraction bits into 32 bits. Swap the words and the low half of the fraction lands in the exponent field: a meter reading of 230.5 V decodes as a negative number around 10⁻⁴¹, or as something near 10²³. That is why "Modbus float wrong value" problems look like garbage rather than calibration errors — and why a value that is plausible but slightly wrong usually points to a scale factor or the wrong register instead.

ABCD, CDAB, BADC and DCBA

Name the four bytes of the 32-bit value A (most significant) to D (least significant). The label lists which bytes arrive in register 1, then register 2, high byte of each register first:

LabelRegister 1 carriesRegister 2 carriesWhat changed
ABCDA BC DNothing: upper word first, big-endian throughout
CDABC DA BWords swapped; bytes inside each register normal
BADCB AD CBytes swapped inside each register; word order normal
DCBAD CB ABoth swapped: fully little-endian

Software calls these by different names — "big-endian", "word swap", "little-endian byte swap", "swapped float", "inverse" — and the same name does not always mean the same arrangement in two products. The letters are unambiguous, so record the order per device using them.

How two 16-bit registers become one 32-bit float

  1. Read both registers in one request (function 03 or 04, quantity 2), so both halves come from the same moment.
  2. Split each register into its high and low byte: register 1 gives two bytes, register 2 gives two more.
  3. Arrange the four bytes into A B C D according to the device's order.
  4. Interpret those 32 bits as an IEEE 754 float32 — or as a signed (int32) or unsigned (uint32) integer if the register map says so.

The same bytes are a different number under each data type, so the type matters as much as the order. A device that stores an energy counter as uint32 will show nonsense if the master reads it as a float, in every byte order.

Worked example: 0x8000 and 0x4366

A panel meter shows 230.5 V. The two registers mapped to voltage read 0x8000 (register 1) and 0x4366 (register 2). Decoding them every way gives:

OrderBytes A B C Dfloat32int32uint32
ABCD80 00 43 66-2.4178e-41 (subnormal)-21474663942147500902
CDAB43 66 80 00230.511307909121130790912
BADC00 80 66 431.1791628e-3884147878414787
DCBA66 43 00 802.3021767e+2317156670721715667072

Read as ABCD, the sign bit is set and the exponent field is all zeros, so the result is a negative subnormal float: −2.4178 × 10⁻⁴¹. Read as CDAB, the 32-bit word is 0x43668000: sign 0, exponent 0x86 (134, meaning 2⁷), fraction 1.80078125 — and 1.80078125 × 128 = 230.5.

CDAB float32 is the only interpretation that matches this reading. That makes it the leading candidate, not a proven answer: check a second and third reading at different voltages, and confirm against the register map before you configure the tag.

Why one plausible value is not proof

With 12 interpretations on the table, a single reading can be matched by more than one of them, or by the wrong one by coincidence. Some ambiguities are structural:

The tool therefore reports candidates as compatible with all readings, eliminated, or ambiguous — never "correct". Three readings at clearly different values, at least one negative if the quantity can go negative, plus the register map is the evidence worth recording.

When nothing fits

If every candidate is eliminated, the byte order is probably not the problem. Check, in this order:

Frequently asked questions

Why does my Modbus float look completely wrong?

Because the master put the two registers (or the bytes inside them) together in a different order from the device. Swapped halves move fraction bits into the exponent, which turns a normal value into something astronomically large, vanishingly small, negative, or NaN. Decode the same registers in all four orders and compare with what the device displays.

What are ABCD, CDAB, BADC, and DCBA?

They name the arrangement of the four bytes of a 32-bit value across two Modbus registers, with A as the most significant byte. ABCD is upper word first, CDAB swaps the two words, BADC swaps the bytes inside each register, and DCBA swaps both. The Modbus specification does not mandate any of them, so each device documents (or doesn't document) its own.

How do two 16-bit Modbus registers become a 32-bit float?

Each register contributes two bytes, sent high byte first. The four bytes are arranged in the device's order to form a 32-bit word, and that word is interpreted as an IEEE 754 single-precision float: 1 sign bit, 8 exponent bits, 23 fraction bits. For 0x4366 followed by 0x8000, the word is 0x43668000, which is 230.5.

Can one correct-looking value prove the byte order?

No. One reading only shows that an interpretation is compatible with that value. Another order or data type may match too — int32 and uint32 are identical for positive values, and zero matches everything. Use several readings at different values and the device register map before trusting a configuration.

Does this tool connect to my device or write anything?

No. It only does arithmetic on the numbers you type, inside your browser. The page's security policy blocks network connections from scripts, it has no device driver, and it never builds Modbus requests — read or write.

Sources

Sources checked 2026-10-07. The explanation and examples on this page are original; values in the worked example are produced by the same code as the tool and covered by its tests.

Cite this page: Modbus register decoder & byte-order check, Shopfloor. https://shopfloor.space/tools/modbus-register-decoder/

Share: X · LinkedIn · Facebook · Hacker News · Email