— Conventions, Offsets, Vendor Quirks & Mapping Best-Practices

(Module 9 · Advanced & Specialised Topics)


Learning objectives

  1. Master every published addressing convention—0-based, 1-based, 30 000/40 000 legacy, PNO “x.y.z register” style, and prefix notation (4x00017).
  2. Diagnose & fix vendor-specific quirks: Allen-Bradley word-swap + offset, Danfoss “decade code”, Siemens S7 byte addressing inside word confusion, Schneider floating blocks, ABB “tabbed offsets”.
  3. Design register maps that scale to ≥ 65 536 addresses without ambiguity—using banked tables, file records, or 32-bit “extended register” patterns.
  4. Document maps in a future-proof way (semantic YAML + auto-generated XLS/PDF) and version-control every change.
  5. Automate conversion and validation with open-source tools (modbus-map-linter, yaml-to-excel.py, Node-RED RegMap validator).

27.1 The three core numbering schemes

SchemeHuman example (Holding Reg)PDU start addressComment
Legacy 1-based400170x0010Most manuals pre-2000; still common
Prefix notation4x0017 (or 4X:17)0x0010Unambiguous; recommended
IEC-PNO4.17 (table.index)0x0010Popular in Profinet docs

Mnemonic: “Remove the table prefix, subtract one.”


27.2 0-based vs 1-based under the hood

27.2.1 Derivation

PDU_offset = Human_number – Table_base – 1   (for 1-based docs)
Human_number = PDU_offset + Table_base + 1   (for generating manual)

Table_base = 0 (0X), 10000 (1X), 30000 (3X), 40000 (4X).

27.2.2 Pitfall pattern

Symptom: All reads return neighbour value or zero.
Signature: (desired_value << 16) == returned_word often true.
Fix: Subtract 1 from start address; retest.

(Fig-27-1 placeholder: off-by-one ladder.)


27.3 Vendor-specific wrinkles

VendorQuirkExampleMitigation
Rockwell Micro-820Start address 400001400001 → PDU 0Subtract 1 000 00 then 1
Danfoss FC302 VFDRegisters “0-99” internal mapping then +1k offsetParameter 16-01 → HR 16101Use vendor CSV converter
Siemens S7 1200Byte addressing inside word (DBX)DB10.DBW4 → HR40003 but high/low bytes swappedMap with word-swap flag
ABB TotalflowTabs: 4.x.y → file recordsGas Vol 4.12.3Use FC 20/21 not 03
Wago 750-880Bit addressing via “X” suffix4x0002.3 = bit 3 of HR2Mask in gateway

(Table 27-A; keep growing in Appendix A6.)


27.4 Large address-space strategies

27.4.1 Banked tables

Divide 0–65 535 into “banks” of 10 000.

  • Bank 0: Process real-time (0…9999)
  • Bank 1: Config (10000…19999)
  • Bank 2: Historical snapshot (20000…)

Master can burst-poll each bank; easier CoV diff.

27.4.2 File Record model (FC 20/21)

FieldSizeMeaning
File Num2 B“Block ID” (0…65535)
Record Num2 BIndex inside block
Length2 BWords

Use-case: 600 k-word historian; leaves 4X unpolluted.

27.4.3 32-bit “extended register” convention

  • Some vendors let FC 23 address >125 registers by treating “word count” as 32-bit across two bytes.
  • Not standard; always pair with vendor API or update SCADA driver.

(Fig-27-2: extended register framing.)


27.5 Best-practice mapping patterns

PatternProsConsThickness
Dense numeric (classic)Minimal doc overheadOff-by-one risk; zero semanticsThin
Prefixed blocks (AI, AO, DI, DO)Visual separation of I/O typesExtra gaps → wasted addressesMedium
Semantic YAML (name:, unit:)Machine-readable, auto-docsNeeds generator toolingThick (future-proof)

27.5.1 YAML snippet example

- reg: 40001
  name: TankLevel
  type: float32
  unit: "%"
  byte_order: "CDAB"
  rw: R
  desc: Raw ultrasonic tank level, scaled 0-100
- reg: 00001
  name: PumpA_Enable
  type: coil
  rw: RW

Run yaml-to-excel.py registers.yaml map.xlsx → generates colour-coded XLS for manual + JSON for SCADA auto-import.

(Listing 27-1: Python generator, 80 LOC).


27.6 Documentation & version control strategy

  1. Source of truth: YAML/CSV in Git.
  2. Auto-generate:
    • PDF register book (pandoc).
    • XLS for non-tech users.
    • HTML interactive table (DataTables).
  3. CI linter (modbus-map-lint) checks:
    • Duplicated addresses.
    • Hole > n words.
    • Illegal type/byte order combo.
  4. Release tag vMajor.Minor.Patch; bump patch on non-breaking re-order, major when addresses change.

(Fig-27-3: CI pass/fail dashboard.)


27.7 Validation techniques

TechniqueToolGoal
Golden framepymodbus.framerConfirm PDU vs spec after firmware change
Auto-echoDevice responds with same data to “test register”Detect word-swap early
SCADA import diffScript compares SCADA tag DB ↔ YAMLBlocks off-by-one rollouts
Fuzz readmodbus-fuzz-addr.py sweeps entire 0-65 535Reveal undocumented registers (security review)

27.8 Case-study: Resolving 2 000-register overlap in 24 h

Factory X added new heat-treat oven; vendor used 40001…40030 already occupied by historian. Symptoms: historian data flickered every 5 s.

Steps:

  1. YAML diff: overlap highlighted red.
  2. Temp fix: firewall rule blocks oven write FC 16 to conflicting range.
  3. Vendor patched firmware → shifted oven registers to bank 4.
  4. CI linter gate added to integration pipeline to prevent recurrence.

Result: 30 min downtime vs projected 12 h manual debug.


27.9 Best-practice checklist

✔︎Rule
Use prefix notation 4x/3x/1x/0x — no bare numbers.
Reserve 100+ spare registers per bank for growth.
Commit YAML/CSV map to Git; tag releases with device firmware.
Document byte+word order per multi-word entry.
Validate map with linter before flashing or shipping device.
Provide machine-readable export for SCADA and edge gateways.
Never overload same address for two units (even if “read” vs “write”).

Chapter recap

Data-address mastery is not trivia—it’s the difference between stable 24 × 7 operation and phantom faults that drain weeks. With formal map generation, rigorous version control, and linting, you bullet-proof both engineering workflows and cybersecurity posture.


Assets to create

IDVisual / file
Fig-27-1Off-by-one ladder / equation graphic
Fig-27-2Extended-register frame diagram
Fig-27-3CI linter pass/fail dashboard
Table 27-AVendor quirk cheat-sheet
Listing 27-1YAML-to-Excel generator

Next: Chapter 28 – Performance Optimisation for Modbus Networks will quantify throughput limits, poll-rate calculus, and smart batching, then deliver code and oscilloscope proof for each optimisation lever.

Leave a Reply

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

Related Posts

Chapter 9 – Modbus Gateways

— Bridging Serial & TCP/IP Worlds (Module 3 · Modbus TCP/IP) Ambition for this chapter: Build the best single source on earth for everything that happens inside a Modbus gateway—PCB…

Chapter 3 – Core Modbus Concepts

— The Mechanics of Communication (Module 1 · Foundations – Understanding the Modbus Universe) Learning Objectives After completing this chapter you will be able to … Describe the canonical Modbus…