Modbus protocol reference

Modbus Data Types Explained: INT16, UINT32, FLOAT32, DWORD

Modbus only knows about 16-bit registers. Everything else — signed integers, 32-bit values, floats — is a convention built on top. Here's how each common data type is actually packed onto the wire.

Quick take: Modbus itself has no concept of INT16, FLOAT32, or DWORD. It only moves raw 16-bit registers. The data type is an agreement between the device and your master application about how to interpret those bits — get it wrong and you'll read a technically valid but meaningless number.

What Modbus actually transmits

A Modbus holding or input register is always exactly 16 bits. The protocol has no built-in idea of "integer" or "float" — it just moves 16-bit words back and forth using function codes like FC03 (Read Holding Registers) and FC04 (Read Input Registers). Every data type you see in a device's register map documentation is a convention layered on top of that raw 16-bit register, agreed between the device vendor and whatever reads it.

Common Modbus data types

Data typeRegisters usedRange / notes
UINT16 / WORD10 to 65,535 — the "native" Modbus register type
INT161-32,768 to 32,767 — same 16 bits, interpreted as two's complement signed
UINT32 / DWORD20 to 4,294,967,295 — two registers combined per the device's word order
INT32 / DINT2-2,147,483,648 to 2,147,483,647 — signed 32-bit across two registers
FLOAT322IEEE-754 single precision — same 32 raw bits as UINT32, reinterpreted as a float
FLOAT64 / DOUBLE4IEEE-754 double precision across four registers, less common but used for high-precision totals
STRINGNASCII characters packed two per register, length defined by the device
BCD1 or moreBinary-coded decimal — each nibble represents one decimal digit, common on older meters

Why the same bits can mean different things

Because Modbus has no native type system, the exact same two registers on the wire — say 0x42C8 0x0000 — could be intended as a UINT32 (1,120,403,456), an INT32, or a FLOAT32 (which happens to decode to 100.0). None of these interpretations are "more correct" at the protocol level; the device's register map documentation tells you which one to apply. This is also why data type mismatches are one of the most common causes of nonsense readings in SCADA and HMI projects — the communication itself is working perfectly, but the wrong decode rule is applied on the receiving end.

Data type vs byte order — two separate problems

Data type and byte order are often confused but are two independent settings you need to get right together:

Getting the data type right but the byte order wrong (or vice versa) both produce incorrect values, so when a reading looks wrong it's worth checking both settings, not just one.

How to confirm a device's data types safely

  1. Start with the vendor's register map — most documents label each register with its type (UINT16, FLOAT32, etc.) directly in the register table.
  2. If undocumented, write a known test value using each candidate data type and compare the raw register bytes returned against what you'd expect.
  3. Use a Modbus slave simulator to safely replicate the register map and test decoding logic in your master application before connecting to production hardware.
  4. Document the confirmed data type and byte order together in your own project notes — the two settings should always be recorded as a pair.

Related pages

Test data type decoding before touching live hardware

Write INT16, UINT32, or FLOAT32 values to simulated registers in ModbusSimulator and confirm your master application reads them correctly.

Download Free tier

FAQ

What data types does Modbus support natively?

Modbus only defines a 16-bit register and single-bit coils/discrete inputs. Types like INT16, UINT32, and FLOAT32 are conventions built on top, not part of the base protocol.

How is a 32-bit integer stored in Modbus?

It's split across two consecutive 16-bit registers. Which register holds the high or low 16 bits depends on the device's word order convention.

How is a floating point value stored in Modbus?

A 32-bit float is stored as the raw IEEE-754 bit pattern split across two registers, the same way a 32-bit integer is stored — only the interpretation differs.

What is the difference between DWORD and FLOAT32?

Both use two registers with identical raw bits on the wire. DWORD is interpreted as an unsigned 32-bit integer, while FLOAT32 is interpreted as an IEEE-754 float. Picking the wrong one produces a meaningless number.

Can I test data types without real hardware?

Yes. A Modbus slave simulator lets you write a value as a specific data type into a register or register pair and confirm your master application decodes it correctly.