Skip to content
EnergyCalcHQ
7 min read

Modbus RTU on energy meters: six things that break

Wiring, termination, byte order, register offsets, phantom registers and polling intervals — the real RS485 failure modes, and how to tell them apart.

Written byDivakar

Reading an energy meter over RS485 should be simple. Two wires, a request, a response. In practice a new meter integration fails for one of six reasons, and they produce very similar symptoms — garbage numbers or no response at all. Here is how to tell them apart quickly.

1. Wiring and polarity

A+ to A+, B− to B−, and a common ground reference. Reversed A/B gives you silence, not garbage. If you get no response at all from any address, swap A and B before you touch anything else. It costs ten seconds.

Ground matters more than people think. On a long run between separate panels, the two ends can sit at meaningfully different potentials and the transceivers stop seeing valid levels. Run the reference conductor.

2. Termination

120 Ω across A/B at each end of the bus — the two physical ends, not every device. Symptoms of missing termination are the ones that waste days: it works on the bench with a 1 m cable, and fails intermittently at 200 m on site.

Intermittent is the tell. Consistent failure is usually wiring or config; intermittent failure that gets worse with cable length is reflection.

3. Serial parameters

Baud rate, parity, stop bits, and the slave address all have to match. The common trap is that many meters ship at 9600 8N1 but the manual documents 9600 8E1, and parity mismatch gives you a response that looks like noise rather than nothing.

If you can see bytes coming back but the CRC never validates, suspect parity before you suspect the meter.

4. Register offset — the off-by-one

This one catches everyone once.

Modbus documentation uses two conventions. Some manuals list registers as 40001, 40002, 40003 (the older "data model" numbering). Others list the raw address the protocol actually puts on the wire: 0, 1, 2.

A meter documented as holding register 40011 is read at protocol address 10, not 11 and not 40011. If every value you read belongs to the register next door, this is why.

The Modbus address converter does the subtraction either way and tells you the function code that goes with the block — 3 for holding registers, 4 for input registers. Worth checking which one your client library expects before you convert a whole map, because some subtract the offset for you and some do not.

5. Byte and word order

A 32-bit float spans two registers, and there are four ways to arrange them:

Order Name Common on
ABCD Big-endian Schneider, most European meters
DCBA Little-endian some Chinese meters
BADC Big-endian byte swap Selec, some Indian meters
CDAB Word swap very common, catches people out
Two Modbus registers decoded under all four byte orders, only one giving the correct value of 200.0
The registers are identical in all four rows. Only your interpretation of them differs, which is why the meter can never tell you that you got it wrong.

The diagnostic is easy once you know it: read a value you can verify independently, like line voltage, which should be around 230 V or 415 V.

  • Correct order → 230.4
  • Word-swapped → an absurd number like 1.2e-19 or 4.5e28
  • Byte-swapped → also absurd, but differently

Rather than swapping bytes in code and re-reading each time, paste the two registers into the Modbus float decoder. It shows the value under all four orderings side by side, so the one that produces a sensible voltage is visible immediately. Usually only one does, and that settles it in seconds.

Current is the better test if the voltage reads fine but you still suspect a problem, because you can predict what it should be. Work out the expected line current for the connected load with the three-phase current calculator and compare. A 45 kW motor at 0.86 power factor should draw about 79 A — if the meter says 7.9 A or 790 A you have a CT ratio set wrong, and if it says something with an exponent in it you have a word order problem.

If the number is wildly wrong rather than slightly wrong, it is word order, not calibration. Slightly wrong is a CT ratio problem. Wildly wrong is byte order. This distinction saves hours.

6. Phantom registers

Here is the one that is genuinely hard, because nothing about it looks like an error.

Many meters respond to a read on a register they do not actually implement. Instead of returning an exception code, they return whatever happens to be in that memory location — stale data, zeros, or a fragment of an adjacent value.

So you read "THD on phase 2" from a register the manual lists, get a number back, and it is meaningless. The meter is not broken and your code is not broken. The register simply is not populated on that model.

How to confirm: read the same register across two identical meters carrying different loads. A real register tracks the load. A phantom register returns the same value on both, or a value that never changes when the load changes.

A second confirmation, if you only have one meter: check whether the value is internally consistent with the others. Real kW, kVA and power factor readings satisfy S = P / cos φ. Put the meter's own kW and power factor into the kW, kVA and kVAr converter — if the kVA it should be reporting and the kVA it actually reports disagree, at least one of those three registers is not real.

The fix is not byte order — people burn days re-swapping bytes on phantom registers. The fix is to check the model-specific register map, and if the register is not implemented, stop displaying the field rather than showing a number nobody can trust.

Polling interval

Once it works, do not hammer it. Most meters need 200–500 ms between requests. Poll faster and you get timeouts that look exactly like a wiring fault, which sends you back to step one on a problem you already solved.

For a bus with several meters, poll each in sequence with a gap rather than in parallel — RS485 is half duplex, and two masters talking at once corrupt both messages.

Quick triage

Symptom Look at
No response, any address A/B reversed, baud, address
Bytes return, CRC fails Parity
Works short, fails long Termination, ground reference
Value one register off 40001 vs 0 offset
Wildly wrong number Word/byte order
Plausible but static number Phantom register
Random timeouts under load Polling too fast

Work down the table in order. It is roughly the order of how often each one is the cause.

Checking the numbers once it talks

Getting bytes back is not the same as getting correct readings. Once the bus is stable, sanity-check what the meter reports against what the load should be doing:

  • Modbus float decoder — two registers in, all four byte orders out. Settles step 5 without touching your code.
  • Modbus address converter — the 40001-versus-0 offset and the matching function code, for step 4.
  • Three-phase current calculator — expected line current for a known kW load. Catches CT ratio errors and word order faults.
  • kW, kVA and kVAr converter — confirms the meter's power readings are internally consistent, and tells you whether the power factor it reports is bad enough to be costing you a tariff penalty.

A meter that communicates perfectly and reads 10× low is worse than one that does not communicate at all, because you will trust it.

Related articles

More on metering & iot.

Comments

Loading…

Add a comment

Corrections especially welcome. Comments are approved by hand before they appear.

Your email is never published. We use it only to reply.