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 →