In this lesson

What this lesson covers

  • Silence, a CRC error and an exception each point at a different domain
  • What an exception already proves about wiring, parameters and address
  • The FC08 diagnostic counters, and changing one variable at a time

Read first: The Modbus RTU frame byte by byte, plus CRC, Multiple Modbus devices on one RS485 bus, Read your first Modbus device with mbpoll

Modbus RTU troubleshooting starts with one question: what exactly are you seeing? Silence, a CRC error and an exception are three different fault pictures, and each one sends you to a different set of causes. After this lesson you can place a fault in the right domain before you unscrew a single terminal, and you can produce all three pictures deliberately to prove where the problem is not.

Three fault pictures, three different worlds

Every Modbus RTU problem you will ever meet arrives as one of three pictures, and which one you have decides where you spend the next hour.

What you seeWhat it meansWhere you lookSilence, timeoutThe frame never arrived,or was dropped before itwas readWiring: D0, D1, common,terminationSerial: baud rate,parity, stop bitsAddress: server address1 to 247Exception, forexample 01 83 02The device is alive andanswering. It is refusingthis one requestAddressing: theoff-by-one on 40001Block: FC03 againstFC04Quantity: start pluslength off the endA value that is notrightThe transport is fine, theinterpretation is notData type and wordorderScaling factor and unitWrong register from thedatasheet
These three symptoms are mutually exclusive and each one points at a different domain. Decide which column you are in first, and you have halved the search.

The middle column is the one people skip past. An exception is not a broken bus, it is a completed transaction with a negative answer. Keep Modbus RTU explained open next to this lesson as the reference on the transport itself.

When nothing comes back at all

Nothing back means the frame died somewhere, and you rule the causes out from cheap to expensive, not from the terminal block outwards.

Start with the server address. Factory default is almost always 1, individual addresses run from 1 to 247, address 0 is broadcast and 248 to 255 are reserved. Next the serial parameters: the standard prescribes 19200 with even parity and almost no manufacturer follows it, so 9600 8N1 is the sensible second guess on an unknown energy meter. Only then do you touch wires.

Measure the idle voltage before you start swapping wiresWired correctlyD1 sits positivewith respect to D0Multimeter, DC volts+−D0 (A, D-)D1 (B, D+)CommonD0 and D1 swappedthe reading flips signMultimeter, DC volts+−D0 (A, D-)D1 (B, D+)CommonMeasure with the bus idle: stop the client for a moment so nobody is transmitting.
A reversed pair gives no error and no damage, only silence. Measure the direction with the black probe on D0 and the red one on D1 instead of guessing from the labels.

Last on the list: a missing common conductor, a break in the cable, and a device that is not powered or whose Modbus interface was never enabled in its menu.

When you get something but it is wrong

Frames arriving damaged, or working nine times out of ten, is a physical layer story and almost never a protocol story.

Termination and length are the usual suspects. Terminate at the two ends of the trunk and nowhere else: the standard allows no more than two line terminations on one pair, and never one on a spur. Length is bounded too, 1000 m at 9600 baud with AWG26 or thicker, dropping to 600 m on Cat5, with spurs under 20 m. A duplicate address gives the same picture: two devices answering at once collide into random CRC errors that look exactly like a cable fault.

RS485 bus, 120 Ω120 ΩTIA-485-A · Belden 9841/9842CAT6 patch cable, 100 Ω100 ΩTIA-568 · CAT5e / CAT6 UTPIncoming signalReflection: about 9 percent comes backPassed through: 91%Γ = (Z₂ − Z₁) / (Z₂ + Z₁) = −0,091 → 9,1 %
A length of network cable in the middle usually works, right up until the bus gets long or fast. Then the reflection returns inside one bit time.

For what to pull in and how to lay it, the RS485 wiring guide has the cable and termination detail this lesson does not repeat.

When the device politely says no

An exception is good news. Send the FC03 request 01 03 00 6B 00 03 74 17 and suppose five bytes come back instead of eleven.

ByteHexFieldWhat it says
101Server addressServer 1 answers, so it heard you
283Function code0x03 plus 0x80, a refusal
302Exception codeIllegal data address
4 and 5C0 F1CRC-16Valid, so the frame is clean

That five byte reply proves three things at once: the physical layer carries data, the serial parameters match, and the server address is right. Only your request is in question. Exception 01 means the device does not implement that function code, typically FC03 on a device that only offers FC04. Exception 02 means the address, or the address plus the quantity, falls outside the map, nearly always the off-by-one between datasheet number 40108 and PDU address 107. Exception 03 means the quantity is out of range: the protocol ceiling is 125 registers per read, and many meters allow far fewer.

When the number looks right but is not

Here the communication is finished and correct, and the mistake is in how you read the bytes.

Check plausibility against something you know. Mains voltage sits between roughly 207 and 253 V and grid frequency around 50 Hz, so a frequency field showing 5001 tells you a scaling factor of -2 was never applied. A temperature that jumps to about 6500 in winter is a signed value read as unsigned. A 32-bit energy counter that is stable but wildly wrong is word order, and swapping the two registers is the fastest way to confirm it. All of that is data types and word order; here you only recognise the picture.

Finding a fault without wrecking the bus

One change, one observation, then put it back. That discipline separates a fault you can explain from a bus that mysteriously works again. Write down what you changed and what happened every time, and revert anything that made no difference.

The bus can also tell you what it has seen. FC08 asks a device for its own diagnostic counters, and every conforming server keeps them: subfunction 0x0B returns how many frames it saw, 0x0C how many it could not verify, 0x0D how many exceptions it sent, and 0x0A clears the lot. Clear them, poll for ten minutes, then read 0x0B and 0x0C. A climbing 0x0C against a healthy 0x0B is a physical problem; 0x0C at zero with exceptions coming back is a configuration problem. One caution: 0x0C also counts parity errors, character overruns and frames shorter than 3 bytes, so it is not purely a cable counter.

When it is the environment

The signature of an environmental fault is timing: it works, then a machine starts, then it stops working, then it recovers.

Variable speed drives, contactors and switching power supplies are the usual sources, and the coupling path is almost always a shared cable tray or a screen that is not earthed properly. Log your errors with a timestamp before you go measuring, and ask what switches on at those moments. Earth loops give the same pattern more slowly: a screen earthed at both ends, or a common run between two buildings at different earth potentials. To find out what is still answering afterwards, how to scan a Modbus network covers the sweep.

That logging does not have to be manual. The Data Logger in ModbusCloud Diagnostics records several registers over time and exports to CSV, and the error counter in the Protocol Analyzer counts the failed transactions alongside it. You then put the moment of the dropout next to the moment something switched on, instead of assuming they line up.

Common mistakes

Pulling at the wiring the moment you see a timeout. A wrong server address produces exactly the same silence and takes thirty seconds to rule out. Do the free tests first, in order, and only then open the terminal block.

Treating an exception as a fault. An exception is a completed transaction. Once you have one, stop suspecting the cable, the baud rate and the address, because all three are proven. Read the exception code and go back to your request.

Changing several things at once and then finding it works. You now have a working bus and no idea why, so the next time this happens you start again from nothing. One variable, one note, then revert.

Trusting a patch cable because it happens to have eight cores. Cat cable has roughly 100 Ω characteristic impedance against the roughly 120 Ω of RS485 cable. Over a couple of metres you will never notice. Over a long run it comes back as CRC errors that look like interference.

Get hands-on

Produce all three fault pictures yourself, in one session, on one working setup. The point is not to break something, it is to see that each break looks different.

  1. 1

    Read a register that works and note the statistics

    Use a device you can already talk to, and write down frames transmitted against frames received before you change anything.

  2. 2

    Fault picture 1: reverse D0 and D1

    Read again. Transmitted keeps climbing, received stays at zero: 100 percent loss, no error message. Put the wires back.

  3. 3

    Fault picture 2: use a server address that is not there

    Read again. The picture is identical, nothing comes back. Now go back to the correct address and you get an answer immediately, which is how you separate address from wiring.

  4. 4

    Fault picture 3: ask for a register that does not exist

    Pick an address far past the end of the map. You get exception 02, and that single reply proves cabling, serial parameters and address are all three correct.

  5. 5

    Put the three observations in a table

    One row per picture, with the conclusion about which domain it points at. This table is the lesson.

  6. 6

    Optional: watch the counters move

    With a client that supports FC08, clear the counters with subfunction 0x0A, repeat fault picture 1, then read 0x0C and watch the rejected frames add up.

mbpoll -m rtu -a 1 -b 9600 -P none -t 4 -r 1 -c 2 -1 /dev/ttyUSB0

No hardware. Run the pymodbus simulator and do fault picture 3 against it with a register far outside its map. Both mbpoll and pymodbus are free to use, including commercially.

mbpoll -m tcp -p 5020 -a 1 -t 4 -r 60000 -c 1 -1 127.0.0.1

Fault pictures 1 and 2 can be imitated on TCP with a wrong port and a wrong unit id, but note that the mechanism differs: on TCP the connection itself is refused, while on RS485 the frame disappears into the cable. The frame level detail sits in the RTU frame and CRC lesson and the electrical background in RS485 explained.

Expected result: three fault pictures in a table, each with the domain it rules in or out.

Summary

  • Silence, a CRC error and an exception are three separate fault pictures, and each points at a different domain.
  • An exception proves the frame arrived intact and correctly addressed, ruling out wiring, serial parameters and server address in one go.
  • Reversing D0 and D1 causes 100 percent frame loss and no damage, so it is a cheap test, but only after the address and the parameters.
  • A fault that follows a machine switching on is coupled interference, so you look at cable route, screening and earthing.
  • A climbing FC08 counter 0x0C alongside a healthy 0x0B points at a physical problem, not a configuration one.

Check yourself

Four questions about this lesson. Every answer comes with an explanation.

Question 1 of 4
A device answers you with exception 02. What can you rule out on the spot?
Everything runs fine until the compressor kicks in. CRC errors climb while it runs and stop when it shuts down. Where do you look?
You swap D0 and D1 on a device that was working. What do you expect the poll statistics to show?
Why is silence a less useful symptom than an exception?

Stuck on a project?

Describe what you see and where it goes wrong. We will look at it and tell you what we would do.

Further reading in the knowledge base