PLC Solution Library · Modbus network simulator
Run a Modbus RTU and TCP network and find the fault
Your SCADA shows a value that has not changed for an hour. Is the transmitter stuck, the cable cut or the register map wrong? In this simulator, one M-Duino 21 polls four Modbus RTU slaves on RS-485 and serves the data to Modbus TCP clients on Ethernet. You see every frame, every CRC and every timeout.
One M-Duino 21 polls four Modbus RTU slaves and serves the data on Modbus TCP. Pick a fault and find it in the frames.
Switch a slave off, give two slaves the same address, change the word order or the baud rate. Then use the counters and the frames to find the cause.
Choose a fault to diagnose
At 1/10, one second on screen is 100 ms on the bus. Pause and step to read each frame.
RS-485 · Modbus RTU
Ethernet · Modbus TCP
What the SCADA sees
Field devices
The device side: supply and the address set in each device. All four use 19200 baud, 8E1.
Your PLC program
In both cases the status bit of that read goes to 0. The PLC retries after a timeout or a CRC error, never after an exception. The fault values are 0x8000 for int16, 0xFFFF for uint16, 0xFFFFFFFF for uint32 and NaN for float32.
Register map editor: what the PLC reads on RS-485
| Read | Slave | Function | Register | Type | Word order | Scale | Value | Quality | OK / failed |
|---|
One row is one Modbus transaction. Change a slave, a function, a register or a type and watch the answer: timeout, exception or a wrong value. If you change a data type, the TCP map below moves, and the clients must follow.
Modbus TCP server map of the PLC
| Address | Content | Registers | Value |
|---|
Holding registers, function 03, unit 1. The clients read them with function 03 from HR0. The PLC builds this map from its last reads. The clients never talk to the slaves.
Modbus TCP clients
| Client | Every | Reads | tid | Answer |
|---|---|---|---|---|
| SCADA | 1 s | - | ||
| Panel PC | 200 ms | HR0 + 10 | - | |
| Historian | 5 s | HR0 + 10 | - | |
| Laptop | on demand | below | - |
Build a request from the laptop
Frame inspector: the last transaction, byte by byte
How does a PLC poll several Modbus RTU slaves on one RS-485 bus?
The PLC is the only master on the bus. It sends one request, waits for the answer of one slave and only then asks the next one. Slaves never talk on their own. One full round of requests is a polling cycle.
- Request. Slave address, function code, first register, number of registers and a CRC. At 19200 baud with 8E1, one byte is 11 bits, about 0.57 ms, so an 8-byte request takes about 4.6 ms.
- Answer. The slave repeats its address and the function, adds a byte count, the data and its own CRC. How fast a slave starts to answer depends on the device. This simulator uses 5 ms as an example.
- Silence. Between two frames the bus stays quiet for at least 3.5 character times. Above 19200 baud, the standard fixes this silence at 1.75 ms.
- Next read. The PLC moves to the next row of its map. After the last row, a new cycle starts.
With 6 reads at 19200 baud, the cycle takes about 100 ms. When two values sit in consecutive registers of the same slave, one request with a larger count reads both and saves a full transaction.
Run the Healthy network scenario and press Pause, then Step, to follow one transaction at a time.
What is inside a Modbus RTU frame, and what does the CRC check?
A Modbus RTU frame is binary. The first byte is the slave address, from 1 to 247. The second byte is the function code. Then come the data, and the last two bytes are a CRC-16. The receiver computes the CRC of the bytes it got and compares it with the last two bytes. If they differ, it drops the frame.
- Function 03 reads holding registers and function 04 reads input registers. Both return 16-bit registers. One request reads up to 125 registers.
- The CRC goes low byte first. Example:
01 04 00 00 00 01 31 CAasks slave 1 for input register 0.31 CAis the CRC. - An exception answer has the function code plus 0x80, then an exception code: 01 illegal function, 02 illegal data address, 03 illegal data value, 04 slave device failure.
A CRC error means that bytes were damaged on the way: noise, a missing termination, a bad ground reference, or two slaves talking at once. An exception means that the slave understood the request and refused it. Then the fix is in the request, not in the wiring.
The frame inspector above shows every byte of the last transaction, with the CRC that this page computes.
What should the PLC do when a slave does not answer?
The PLC waits up to a timeout. If no valid answer arrives, it can try again, and then it moves on to the next read. A slave that does not answer costs the full timeout on every try, so one dead slave slows down the whole cycle. With a 200 ms timeout and 1 retry, a silent slave with two reads adds about 0.8 s to every cycle.
The last good value is still in the PLC memory. If the PLC passes it on as if it were fresh, the SCADA shows a stable, believable value from a device that is off. That is a stale value. There are two common ways to make it visible:
- Keep the last value and clear a status bit. The clients read the status register and mark the value as bad. In this simulator, the status register has one bit per read.
- Write a fault value that cannot be a real reading, for example 0x8000 for a signed 16-bit value or NaN for a float. A client that ignores the status still sees that something is wrong.
Add a heartbeat register that the PLC increments every cycle. If it stops changing, the clients know that the PLC stopped polling. Retry after a timeout or a CRC error. Do not retry after an exception: the slave has answered, and it gives the same answer again.
Run the A slave stops answering scenario and compare the value in the map editor with the quality in the SCADA view.
How do you find a duplicate Modbus address?
Two slaves with the same address both answer the same request, at the same time. Their signals overlap on the RS-485 pair and the master gets damaged bytes. The typical signs are:
- CRC errors on one address only, while the other addresses are clean.
- Values that jump between two readings, or answers that do not fit the device, such as exception 01 from a device that supports the function.
- Another address that suddenly stops answering: the device that should be there now has the wrong address.
This often happens after a replacement, because a new device keeps its factory address. Set the address of a new device before you connect it to the bus, and keep the list of addresses with the wiring diagram. To confirm, switch the suspect device off and watch the counters of that address.
Run the A drive is replaced scenario, find the cause and fix it on the device card.
Why does a 32-bit Modbus value come out wrong?
A Modbus register holds 16 bits. A 32-bit integer or a float uses two consecutive registers, and the standard does not fix which one comes first. Some devices send the high word first, others the low word first. Inside each register, the high byte always comes first.
Example: the total 1,284,560 L is 0x001399D0. A flow meter that sends the low word first puts 0x99D0 in register 0 and 0x0013 in register 1. If the PLC reads them high word first, it builds 0x99D00013, which is 2,580,545,555.
The CRC is fine and the read is OK, so no counter shows the problem. Check the word order in the manual of each device and test with a value you know. A float with the wrong word order often gives a tiny number, a huge number or NaN.
The same choice exists on the TCP side. The PLC decides the word order of its own server map, and every client must use the same order. Run the Wrong word order scenario, then change the word order of the TCP map and watch the SCADA.
How does a PLC serve Modbus TCP to several clients?
On Ethernet, the PLC is a Modbus TCP server on port 502. Each client opens a TCP connection and sends requests. The request is the same as in Modbus RTU: function code, first register and count. In front of it comes the 7-byte MBAP header. There is no CRC, because TCP already checks the data.
- Transaction ID, 2 bytes: the client sets it and the server copies it into the answer, so the client can match each answer to its request.
- Protocol ID, 2 bytes: 0 for Modbus.
- Length, 2 bytes: the number of bytes that follow, unit ID included.
- Unit ID, 1 byte: it identifies a serial slave behind a gateway. In this example, the PLC answers unit 1 from its own map.
Each client polls at its own rate: here the Panel PC every 200 ms, the SCADA every second and the historian every 5 seconds. The RTU cycle and the TCP requests run independently. A client reads the copy of the data in the PLC, never the slave itself, so a fast client does not load the RS-485 bus.
A request outside the map gets exception 02 and no data at all. A client that asks for 20 registers from a map of 10 loses all 20 values, not only the last 10. The Ethernet chip of the M-Duino 21, a W5500, has 8 hardware sockets, so plan how many clients connect at the same time.
Run the A client reads outside the map scenario, or build your own request from the laptop.
Design choices you make
1. Timeout and retries
Set the timeout above the slowest answer you expect, with some margin, and not much more. A long timeout makes every failure expensive. One retry catches a single damaged frame without doubling the cost of a dead slave again and again.
2. One request per value, or one per block
Reading a block of consecutive registers in one request makes the cycle shorter. Reading each value on its own makes a wrong register easier to find, because one exception affects only one value. Many maps mix both.
3. What a failed read writes
Keep the last value with a status bit, or write a fault value. Whatever you choose, write it into the register map document that you give to the SCADA integrator, together with the heartbeat register.
4. Word order of the TCP map
Choose one word order for all 32-bit values of your server map and write it into the same document. Convert in the PLC when a slave uses the other order.
5. Serial settings
All devices on one bus use the same baud rate and serial format. The Modbus serial line specification uses even parity as the default (8E1). Without parity, it asks for 2 stop bits (8N2). Many devices also accept 8N1. Use a daisy chain, not a star, with a 120 Ω termination at both ends.
The case study behind this simulator
This simulator goes with our case study on a temperature network with M-Duino PLCs: local PLCs read thermometers over Modbus RTU, a main PLC collects their data, and a server and a Panel PC read it over Modbus TCP.
Read the case study: a Modbus RTU and TCP temperature network
What you see here is a general pattern. The devices, addresses, register maps, times and faults are examples, not the design of a real installation.
To read energy meters and split the energy by machine and shift, use the energy meter simulator.
Learn the building blocks
These tutorials and examples cover each part of this network on an Arduino based PLC.
- Modbus RTU with Arduino and ESP32 based PLCs, master and slave
- Modbus TCP with Arduino and ESP32 based PLCs, master and slave
- Modbus RTU vs Modbus TCP vs OPC UA: which to use
- Modbus RTU master over RS-485 (PLC Solution Library)
- Read a 32-bit flow meter counter over Modbus (PLC Solution Library)
- Modbus TCP register map for a plant (PLC Solution Library)
- Modbus TCP to RTU gateway on an M-Duino PLC (PLC Solution Library)
More examples: PLC Solution Library · all simulators.
M-Duino 21: the specs that matter here
| Communication | Ethernet (W5500, 10/100 Mbit, RJ45), RS-485, RS-232, TTL serial, I2C, SPI |
|---|---|
| Modbus | Modbus RTU over RS-485 and Modbus TCP over Ethernet, as master or slave, with the Industrial Shields Arduino libraries |
| I/O | 13 inputs (6 analog 0-10 V), 8 outputs (3 analog/PWM 0-10 V) |
| Built in | Real-time clock, microSD slot |
| Controller | Arduino Mega 2560 inside |
| Power supply | 12 to 24 Vdc |
| Mounting | DIN rail TS35, IP20 |
| Programming | Arduino IDE with the Industrial Shields boards package |
Ports used in this example
| Port | Role | Peers |
|---|---|---|
| RS-485, half duplex, 2 wires | Modbus RTU master, 19200 baud, 8E1 | 4 slaves |
| Ethernet | Modbus TCP server, port 502, unit 1 | SCADA, Panel PC, historian, laptop |
| Inputs and outputs | Not used in this example | - |
The network uses one serial port and the Ethernet port, so the smallest M-Duino fits. The Modbus examples of the Industrial Shields library use the board name M-Duino 21+, which is this PLC. Set the RS-485 switches of the PLC as shown in the M-Duino family datasheet. Full specs: M-Duino 21 · M-Duino family.
FAQ
Why does my Modbus slave time out?
The PLC got no valid answer in time. If one slave times out, check its supply, its address, its connection to the bus and its serial settings. If all slaves time out together, check the master first: baud rate, parity, the A and B wires, the termination, and that the RS-485 port is in half duplex for a 2-wire bus.
What causes Modbus CRC errors?
Damaged bytes: electrical noise, a missing or extra 120 Ω termination, a star layout instead of a daisy chain, a bad ground reference, or two slaves with the same address answering at once. Count the CRC errors per address. Errors on one address point to that device or its address. Errors on all addresses point to the bus.
What is the difference between a Modbus timeout and an exception?
A timeout means that nothing valid came back. An exception means that the slave understood the request and refused it, for example 02 illegal data address when the register does not exist. Retry after a timeout or a CRC error. Fix the request after an exception.
How many slaves can one PLC poll before the cycle gets too slow?
The limit you hit first is usually the cycle time: every read adds a transaction, and every silent slave adds its timeouts. Count the reads, multiply by the time of one transaction and add the timeouts of the slaves that may fail. The protocol and the bus allow more: slave addresses 1 to 247, and 32 unit loads per RS-485 segment, more with transceivers of 1/4 or 1/8 unit load or with repeaters.
Why is my 32-bit Modbus value wrong?
The two registers are in the wrong order. Modbus does not fix the word order of 32-bit values, so each device chooses its own. Swap the word order and test with a value you know. If the value is a float, also check that the type is float32 and not a 32-bit integer.
Can several SCADA or HMI clients read one PLC over Modbus TCP?
Yes. The PLC answers each client from its own register map, so the clients do not load the RS-485 bus. Each client uses its own transaction IDs. How many connections stay open at the same time depends on the server program and on the Ethernet chip: the W5500 of the M-Duino 21 has 8 hardware sockets.
Do I need to be a programmer to build this network?
The PLC program is written in C++ with the Arduino IDE, using the Industrial Shields Modbus library and its public examples for Modbus RTU and Modbus TCP, linked above. If you prefer, an integrator can write the program from your register map.
Get a polling plan for your network
Tell us your slaves, their addresses and register maps, and which clients read the data. Our team replies with a proposed polling plan and server register map for your case. Your simulator settings go with the request.