— Endianness, 32-bit Floats, Strings & Advanced Representations

(Module 4 · Modbus Data Model & Function Codes)


Learning objectives

After you finish this chapter you will be able to …

  1. Pack and unpack every common data type—signed/unsigned integers, IEEE-754 floats, 64-bit doubles, ASCII strings, BCD—into the 16-bit register lattice Modbus provides.
  2. Identify and correct the four real-world byte/word-swap patterns (“ABCD”, “BADC”, “CDAB”, “DCBA”).
  3. Explain the difference between little-endian bytes and little-endian words—and why careless mixing causes 256× or 65 536× errors.
  4. Implement robust conversion code in Python, C/C++, and IEC-61131 that never breaks across CPUs.
  5. Audit an existing register map and spot hidden pitfalls (bit packing, signed vs unsigned, mixed scaling).

12.1 Why data representation matters

Modbus is transport-layer simple: everything is a 16-bit word (or a single bit). Real-world values rarely fit this neat box:

  • Temperatures need one decimal place (25 .3 °C).
  • Total energy may need 64-bit accumulation.
  • Firmware version or date stamp is text.

Unless master and slave agree exactly how multi-word values are stacked, the SCADA may show nonsense—often 256× off (byte swap) or 65 536× off (word swap).


12.2 Unsigned & signed integers

WidthRegistersRangeTypical use
16-bit uint10 … 65 535Pulse counters, set-points
16-bit int (two’s comp)1–32 768 … 32 767± current, temperature offset
32-bit uint20 … 4 294 967 295Total pulses, kWh totals
32-bit int2–2 147 483 648 … + 2 147 483 647± position, ΔP

Packing order – default Modbus convention is Big-endian word, Big-endian byte (“AB CD”).
Hi word sent first, hi byte of each word sent first.

Tip — If the datasheet does not mention word order, assume the standard “ABCD”.


12.3 IEEE-754 floating-point

12.3.1 32-bit float layout

Sign 1 bit | Exponent 8 bit | Fraction 23 bit

12.3.2 Four swap patterns you’ll meet in the field

Word orderByte orderNicknameExample hex for 123.456 f
A B C Dbig-endianABCD (standard)42 F6 E9 79
B A D Cbig-endianBADCF6 42 79 E9
C D A Bbig-endianCDABE9 79 42 F6
D C B Abig-endianDCBA79 E9 F6 42

Byte-swap is rare; word-swap is common on Rockwell, GE, some ABB drives.

12.3.3 Python helper — Listing 1

import struct

def decode_float32(reg_hi, reg_lo, pattern="ABCD"):
    words = [reg_hi, reg_lo]
    if pattern == "BADC":
        words = [(reg_hi << 8) | (reg_hi >> 8),
                 (reg_lo << 8) | (reg_lo >> 8)]
    elif pattern == "CDAB":
        words = [reg_lo, reg_hi]
    elif pattern == "DCBA":
        words = [((reg_lo << 8) | (reg_lo >> 8)),
                 ((reg_hi << 8) | (reg_hi >> 8))]
    raw = struct.pack('>HH', *words)
    return struct.unpack('>f', raw)[0]

12.4 64-bit double & long-long

Requires four consecutive registers.

ParameterFloat64Uint64
Registers44
Word-order optionsSame four patterns as float32Same

Performance note — many 8-bit MCUs cannot decode float64 natively; they may map the value to two 32-bit floats (hi, lo) instead.


12.5 Scaling strategies

StrategyExampleProsCons
Implicit decimal253 ⇒ 25.3 °CIntegers only, no FPLimited resolution
Fixed-point Qn.mQ8.8 => 0x1234 ⇒ 0x12.34Cheap mathNeeds doc
Engineering units ×1000101325 Pa ⇒ 101 kPaClearOverflows sooner
IEEE-754 float25.3 → 0x41CA 999AWide rangeRequires FP lib

Use a single scaling convention per table; mix-and-match leads to operator errors.


12.6 Strings & ASCII blobs

MethodDetail
2 chars per registerRegister Hi-byte = first char
Pascal styleFirst reg = length
Null-terminated (C)0x00 sentinel

Always allocate an even number of characters; pad unused bytes with 0x20 (space) or 0x00.


12.7 Bit-level access inside registers

Use FC01/02 for true coils; but if memory limited, you can pack 16 status bits into one holding register:

BitMeaning
0LimitSW_A
1LimitSW_B
15System_ready

Master must read full word and mask bits:

status = client.read_holding_registers(100, 1).registers[0]
if status & (1 << 0):
    print("Limit A hit")

Downside: cannot write single bits without Read-Mod-Write-Write race condition—use cautiously.


12.8 Binary-Coded Decimal (BCD)

2 decimal digits per byte.

TypeExample valueRegister hex
Date YYYYMMDD2025-06-070x20 25, 0x06 07
Packed counter123456780x12 34, 0x56 78

Validation rule — nibble > 9 = data corruption.


12.9 Troubleshooting table

SymptomLikely causeOn-the-wire clueField fix
256× too largeByte swapHi-byte/Lo-byte reversed in captureSwap bytes in code
65 536× too largeWord swapWord order reversedSwap register order
Negative value when should be unsignedSigned vs unsigned read0xFFFF FF38 displayed –200Interpret as uint or extend map
Random chars in stringOdd-length + missing paddingSecond half of reg overwrittenPad with 0x00 or 0x20

12.10 Design checklist for device vendors

  1. Document every field: address, type, units, scale, word order, R/W.
  2. Keep multi-word values even-aligned (start on odd human numbers — 40001, 40003).
  3. Include sample raw frames in the datasheet.
  4. Provide open-source decoding snippet (C or Python) to remove ambiguity.
  5. Reserve extra registers now; firmware upgrades later will thank you.

Chapter recap

  • Modbus transports only bits + 16-bit words; everything else is a packing problem.
  • Know the ABCD → DCBA taxonomy and build swap guards into your code.
  • IEEE-754 floats give clarity, but require explicit word-order statement.
  • Strings, BCD, and bit-packed flags are space-savers—use judiciously.
  • Publish an unambiguous register book; it is the eternal contract between device and every system that will ever talk to it.

Assets to create

IDVisual idea
Fig-12-1Word & byte order matrix (ABCD/BADC/CDAB/DCBA)
Fig-12-2Float32 bit-field diagram (sign, exponent, mantissa)
Fig-12-3BCD vs packed-int comparison graphic
Listing-1Python swap-aware float decoder
WorksheetExcel: input raw registers → live decode (downloadable)

Next: Chapter 13 – Modbus Exception Responses: Understanding & Handling Errors. We’ll dissect every exception code, map it to root-causes, and build a solid retry/back-off strategy that keeps masters from flooding the bus when something goes wrong.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts