Modbus 32-Bit Integer Data Types: Registers, Byte Order, and Scaling Explained
Modbus registers are 16 bits. But energy meters report kilowatt-hours as 32-bit values, drives report encoder positions as 32-bit values, and flow totals overflow a single register quickly. Every one of them uses two consecutive Modbus registers for one value — and the way those two registers are ordered and interpreted is where engineers lose hours.
This guide covers 32-bit integers in Modbus: the register-pair layout, word order (high word first vs low word first), signed vs unsigned interpretation, scaling and offset conventions, and the classic bugs that produce values like 4,294,967,295 instead of −1.
Why 32-Bit Values Need Two Registers
A Modbus holding register is a 16-bit unsigned integer: 0 to 65,535. That's plenty for a voltage reading, but it caps at 65,535 for anything else. A 32-bit value spans 0 to 4,294,967,295 (unsigned) — which needs two registers.
Register capacity
───────────────
1 register = 16 bits = 0 .. 65,535
2 registers = 32 bits = 0 .. 4,294,967,295 (unsigned)
−2,147,483,648 .. 2,147,483,647 (signed)
The two registers are always consecutive — for example, address 40001 and 40002. The device manual will say something like "Energy Total (U32): Registers 40001–40002."
Word Order: High Word First vs Low Word First
Once you know the value spans two registers, the next question is which register holds which half. There are two conventions:
| Convention | First register | Second register | Common in |
|---|---|---|---|
| High word first (big-endian words) | Most significant 16 bits | Least significant 16 bits | Most European meters, Schneider, many drives |
| Low word first (little-endian words) | Least significant 16 bits | Most significant 16 bits | Some PLC brands and PC-based tools |
Here's a worked example. A meter reports 1,500,000 Wh. In hex that's 0x0016E360, split across the word boundary:
Value: 1,500,000 decimal
Hex: 0x0016E360
High word (most significant): 0x0016 = 22
Low word (least significant): 0xE360 = 58,208
High word first (ABCD):
Register 40001 = 0x0016
Register 40002 = 0xE360
→ 0x0016E360 = 1,500,000 ✓
Low word first (CDAB):
Register 40001 = 0xE360
Register 40002 = 0x0016
→ 0xE3600016 = 3,813,736,470 ✗ (huge wrong value)
The same two registers, read in the wrong order, turn a sensible 1.5 MWh reading into 3.8 billion. That's the signature of a word-order mismatch: values that are either absurdly large or absurdly small.
Two different swaps: word order (register pair order) is independent from byte order within a register. A device can be high-word-first with big-endian bytes (the common case), or any combination. Always check both — Modbus tools expose both as separate settings.
Signed vs Unsigned: The −1 vs 4,294,967,295 Trap
The same 32 bits can be read as unsigned (0 to 4.29 billion) or signed (−2.1 billion to +2.1 billion). The meter doesn't tell you which — the manual does.
Bits: 1111 1111 1111 1111 1111 1111 1111 1111
As unsigned 32-bit: 4,294,967,295
As signed 32-bit: −1
Bits: 1000 0000 0000 0000 0000 0000 0000 0000
As unsigned: 2,147,483,648
As signed: −2,147,483,648
Common failure modes:
- A temperature that should be −5 °C reads 4,294,967,291. That's a signed value being decoded as unsigned.
- A totalizer that reads 4,294,967,295 and never increments. Either it's −1 (signed) or it genuinely overflowed — check which.
- Power factor readings jumping between −1 and +1 with huge values in between. Likely a signed/unsigned mismatch on a value stored as a signed scaled integer.
Debug shortcut: if a reading is exactly 4,294,967,295 (all ones) or 2,147,483,648, your signed/unsigned interpretation is inverted. Try the other one before touching byte order.
Scaling and Offset: The "Why Is It ×100?" Question
Most Modbus devices don't transmit raw engineering units. They transmit a scaled integer. The manual specifies a scale factor and sometimes an offset:
Raw value × scale + offset = engineering value
Voltage meter:
Raw register pair = 23,000
Scale = 0.01
→ 23,000 × 0.01 = 230.0 V
Energy meter:
Raw = 1,500,000
Scale = 0.001
→ 1,500 kWh
Temperature sensor (offset example):
Raw = 250, scale = 0.1, offset = −40
→ 250 × 0.1 − 40 = −15 °C
Scale factors to watch for:
| Typical scale | What it means | Example raw → real |
|---|---|---|
| 0.001 | Milli-units (kWh, kW) | 1,500,000 → 1,500.0 |
| 0.01 | Centi-units (volts, amps) | 23,000 → 230.0 |
| 0.1 | Deci-units (temps, power factor ×10) | 250 → 25.0 |
| 1 (no scale) | Whole units (counts, totals) | 42 → 42 |
When a value "looks right but off by a factor of 10/100/1000," that's a scale factor problem, not a byte order problem. Byte order errors produce wildly wrong values; scale errors produce recognizable-but-wrong ones.
Register Pairs and How to Read Them
Reading a 32-bit value as a master is just an FC03 read of two consecutive registers:
FC03 request: Slave 01, start 40000 (0x0000), quantity 2
Request frame: 01 03 00 00 00 02 C4 0B
FC03 response: Slave 01, 4 data bytes
Response frame: 01 03 04 00 16 E3 60 CRC
Decoded as high-word-first unsigned:
Register 0 = 0x0016, Register 1 = 0xE360
Value = 1,500,000
Two gotchas:
- Alignment. The pair must start at an even offset in most devices (register 0–1, 2–3, 4–5…). Reading 32-bit values at odd boundaries is undefined and device-specific.
- Quantity. FC03 quantity is in registers, so a 32-bit read requests 2 registers, a 64-bit read requests 4. The response data length tells you how many bytes came back.
A good Modbus poll tool handles pair alignment, word order, and signed/unsigned decoding for you — you just tell it the type (U32/S32) and the order, and it formats registers 40001–40002 as one value.
64-Bit Values and the Same Principles
Energy totalizers and gas meters sometimes use 64-bit integers (four registers). The same rules extend: four consecutive registers, ordered by word, with signed/unsigned and scale. The failure modes are identical, just with more bits to scramble — a wrong word order on a 64-bit value produces astronomically wrong numbers that are easy to spot.
Support for 64-bit types varies by device; when a manual says "INT64" or "U64," read four registers and apply the same reasoning.
How to Debug a 32-Bit Reading That Looks Wrong
Step-by-step, in the order that finds the bug fastest:
- Read the raw registers. Get the two hex values before any interpretation — most tools show this.
- Check signed vs unsigned first. If you see 4,294,967,295 or 2,147,483,648, flip the interpretation.
- Check word order. Assemble both high-word-first and low-word-first; one should be a plausible value.
- Apply the scale from the manual. If the raw value is plausible but ten times too big/small, it's scaling.
- Verify against a known state. Put the device into a known condition (0, full-scale, a calibration value) and confirm the reading tracks.
- Document the working combo — type, word order, byte order, scale — in your project notes so the next engineer doesn't redo the archaeology.
Test with a simulator first: if you're building a client, validate your 32-bit decoding against a Modbus slave simulator with known register values before pointing it at live equipment. It's the cheapest way to catch order and type bugs.
The Bottom Line
Modbus 32-bit integers span two consecutive registers, and every device picks its own word order, signedness, and scale. High-word-first unsigned is the most common default, but "common" is not "guaranteed" — the manual is the source of truth.
The three classic failure signatures: absurdly large values (word order), exactly 4,294,967,295 or 2,147,483,648 (signed/unsigned), and recognizable-but-wrong magnitudes (scale). Each has a distinct fix, and none of them require touching the hardware.
With a poll tool that decodes register pairs as typed values, most of this becomes a dropdown instead of a hex-decoding session.
Decode 32-Bit Modbus Values Instantly
Modbus Poll for macOS reads register pairs as U32, S32, float, and 64-bit values with word order and scaling built in. Test against the built-in simulator or live devices — natively on Mac.
Explore Modbus Poll →