← Articles
Modbus/6 min read/ views

One Unmapped Register Can Fail an Entire Modbus Block Read

How drivers group Modbus registers into block reads, why gap tolerance and block size matter, and how one unmapped address takes down a whole block.

ModbusSCADANetworkingTroubleshooting

Why block reads matter

A 400-tag Modbus map that times out on every third scan is usually not a slow PLC — it is a driver issuing 400 separate one-register reads when it could issue five. Modbus has no subscription model. The SCADA driver must poll, and every poll is a request and a response on the wire. A map with 400 tags read one register at a time is 400 transactions per scan. The same 400 tags read as a few contiguous blocks may be four or five transactions. The data is identical; the load on the PLC, the gateway, and the serial line is not.

Poll block optimization is the work of deciding which registers get read together in one function-code request. Done well, scan times drop and timeouts disappear. Done blindly, you either overload a slow device with hundreds of tiny requests or read large useless spans of registers the SCADA never displays.

This is separate from poll rate and timeout tuning. You can have correct timeouts and still have a slow, inefficient map because the driver is issuing one request per tag.

How a driver decides blocks

Most SCADA Modbus drivers build blocks automatically from the tag addresses you configure. The typical rules are:

  • Registers are grouped by function code and address range (holding registers, input registers, coils, discrete inputs are separate spaces).
  • Adjacent or near-adjacent addresses in the same space are merged into one request.
  • The driver splits a group when it crosses the maximum register count for one request.
  • A large address gap between tags breaks the group into two requests.

The knobs you usually get are maximum block size (how many registers per request) and gap tolerance (how many unused registers the driver will read to keep two tags in the same block). Understanding these two settings explains almost all block behavior.

The gap trade-off

Reading across a gap is a trade. If tag A is at register 100 and tag B is at register 140, the driver can either:

  • Issue two small requests (100 and 140), or
  • Issue one request for 100 through 140, reading 39 registers you do not use.

One larger request is almost always cheaper than two round trips, especially on serial Modbus RTU where turnaround time and silent intervals dominate. So a gap tolerance of 40–50 registers is often a net win. But tolerance set too high causes the driver to read hundreds of empty registers, and on some PLCs a read of an unmapped register returns an exception (illegal data address) that fails the entire block.

That last point is the trap. A single unmapped address inside an otherwise valid block can make the whole block fail, so every tag in the block goes bad-quality at once. Bulk reads are efficient but brittle: they succeed or fail together.

Practical grouping rules

  1. Lay out the register map so tags read together are contiguous. Optimization at the driver cannot fix a map scattered across the address space.
  2. Keep fast tags and slow tags in different blocks. If one alarm word needs 250 ms polling and 300 trend tags are fine at 5 seconds, do not let the driver merge them into one large fast block.
  3. Do not span gaps that cross into unmapped or reserved registers. Confirm with the device documentation, not assumption.
  4. Respect the real request limit. Modbus allows up to 125 holding/input registers or 2000 coils per request, but many gateways and legacy PLCs accept far less. Test the actual ceiling.
  5. Separate register types even when addresses look adjacent; a coil at 40001-style notation is not in the holding-register space.

Request size limits are not the spec limit

The protocol maximum is 125 registers per read, but that number is often wrong for real equipment. Serial gateways, protocol converters, and older controllers frequently cap responses at 32, 50, or 64 registers, or limit the total number of concurrent requests. If the driver is configured for 125-register blocks and the gateway silently truncates or rejects at 50, you get intermittent bad quality that looks like a timeout but is actually an oversized request.

When commissioning an unfamiliar device, start with a conservative block size, confirm clean reads, then increase it while watching for exceptions or truncated responses. Record the working maximum in the project notes so the next engineer does not rediscover it during an outage.

Mixed data types inside a block

A 32-bit float, a 32-bit integer, and a 16-bit status word can sit next to each other in the register map. The driver reads them as raw 16-bit registers in one block, then each tag applies its own decoding (word order, byte order, scaling) on top. Block optimization does not change decoding.

Two things to watch:

  • A 32-bit value spans two registers. Do not let a block boundary split it, or one half is read in a different request and the value can tear during transient reads.
  • Word-swap and byte-swap settings are per tag, not per block. Grouping registers together does not force them to share an endian convention.

Reading the results

After changing block settings, do not trust the theory. Measure.

  • Watch the driver diagnostics for request count per scan and average response time. Fewer, larger requests with stable response time is the goal.
  • Check for a rise in exception responses (illegal data address) after widening gap tolerance. That means a block is now reaching into unmapped registers.
  • Confirm the slow tags did not get pulled into the fast scan group, inflating fast-scan load.
  • On serial links, compare total scan time before and after; fewer transactions should shorten the cycle noticeably.

If request count dropped but bad quality appeared, the optimization went too far. Pull gap tolerance or block size back until reads are clean, then stop.

Commissioning checklist

  1. Export the register map and confirm frequently read tags are contiguous.
  2. Group tags by required poll rate before touching block size.
  3. Set a conservative maximum block size for unknown devices and verify clean reads.
  4. Increase block size until you find the device's real limit, then back off one step.
  5. Set gap tolerance high enough to merge nearby tags but not so high it reads unmapped registers.
  6. Verify no 32-bit value is split across a block boundary.
  7. Record request count per scan, average response time, and the working block size in the project notes.

Read tags together when they live together and share a poll rate; split them when a gap reaches unmapped registers or a value would tear across a boundary. The fewest requests that return clean, whole values wins — not the largest block the protocol will technically allow.