For one PLC, one GUI and a fixed register set, write the Modbus client: 9600 baud 8N1, a 500 ms response timeout, one retry and a 1 s poll period. Choose an OPC server when two or more applications need the same PLC data, or the PLC speaks a protocol you cannot implement yourself.
A VB.NET GUI can reach a small PLC two ways. You write a Modbus client that speaks the wire protocol itself, or the GUI connects to an OPC server whose driver owns the PLC conversation. For one PLC, one screen and a fixed register map, write the client. The protocol job is framing, a CRC check, a timeout and a retry. This page settles the three numbers behind it: the response timeout, the poll period and the register ceiling. An OPC server earns its install when two or more applications need the same PLC data, or when the PLC speaks a protocol you cannot implement and test yourself. Both paths are compared below, the timing is worked for a 40-register screen at 9600 baud, and the decision closes the page.
Is it easier to write a Modbus client or use an OPC server?
Write the Modbus client when one PLC serves one GUI and the whole register map fits one read request. Add an OPC server only when a second application needs the same values or the PLC's protocol is one you cannot implement. Easier comes down to three inputs: how many applications consume the data, whether you can implement the PLC's protocol, and how large the register map is. The table turns those inputs into the choice.
| Decision input | Hand-written Modbus client | OPC server plus an OPC client |
|---|---|---|
| Choose it when | One PLC, one GUI, a fixed map that fits one or two read requests | Two or more applications share the data, or the PLC's protocol is one you cannot implement |
| What you write | Frame build, CRC check, timeout, retry, scaling | An OPC client against the server's items |
| Starting settings | 500 ms response timeout, 1 retry, 1 s poll period | The server's driver defaults, then item scan rates |
| What you install and run | Nothing beyond the GUI | A licensed server service and its PLC driver |
| What tells you data is bad | Your own timestamp goes stale | The item's quality flag |
| First proof | One known register matches the PLC's online value | Items read correctly outside the GUI before you bind them |
The client path puts every failure on your code: timeout, retry, stale values, reconnection. The server path moves the wire protocol out of your hands and hands you item quality instead. It adds a service to license, configure and keep alive, plus version matching between server and clients. Both paths leave the mapping work with you: addresses, data types, word order and scaling.
What does a hand-written Modbus RTU client have to do?
It opens the port at 9600 baud with 8 data bits, no parity and 1 stop bit, the Modbus serial default. It sends an 8-byte read request, checks the response CRC, and keeps 3.5 character times, about 4 ms at 9600 baud, of silence between frames. On a serial line the protocol calls the client the master, and the line carries one request at a time: send, wait for the answer, then send the next. The full list of jobs:
- Framing. A read-holding-registers request is 8 bytes: slave address, function code 03, start address, register count, CRC. The response carries the same address and function, a byte count, and two bytes per register.
- CRC check. Two checksum bytes end every frame. On a mismatch, discard the response and let the retry logic run.
- Exceptions. A refused request comes back with the function code raised by 128 (03 becomes 131) plus an exception code. Log it; it points at the register map, not the wiring.
- Silent gap. RTU measures silence in character times, and a serial RTU character is 11 bits. The gap runs about 4 ms at 9600 baud, 2 ms at 19200, and a fixed 1.75 ms minimum on faster lines.
- The register map. Addresses, 16-bit words, byte order and scaling are yours in either path. They cause more first-read errors than the protocol does.
What timeout and poll interval should you start with?
Start at a 500 ms response timeout with one retry and a 1 s poll period. Serial slaves normally answer within tens of milliseconds, so 500 ms leaves roughly a tenfold margin. Some PLCs trip their own communications watchdog when polled slower than once per second. Two adjustments follow from watching real traffic:
- Masters commonly ship at a 100 ms timeout with a single retry, and a slow slave fails its first request at that setting. Set 500 ms, log how fast replies actually land, and raise the value if responses arrive in the last quarter of the window.
- The 1 s poll period is a ceiling as well as a start. Keep the poll at or under 1 s on serial links; a quiet line longer than that can fault a slave's port watchdog even though the wire is healthy.
Once the screen is live, two symptoms tell you which knob to turn. Replies landing near the timeout point at the timeout value. Data that updates slowly on a healthy link points at the poll rate. The fix for Modbus TCP data that updates slowly walks that diagnosis, and the intermittent PLC communication timeout article lists the causes in the order to check them.
How many registers can one read request carry?
A read-holding-registers request returns at most 125 registers, because the Modbus protocol caps the request data field at 253 bytes, so count your map first. A screen of a few dozen values needs one request per cycle and one poll routine. The arithmetic: a response is capped at 253 bytes, function code and byte count take 2, and 251 ÷ 2 = 125 registers at 2 bytes each. A map above 125 registers splits into consecutive reads. Every extra read adds its wire time to the cycle, which the example below works out. Writes travel as separate requests; keep them out of the poll cycle and validate each one against the PLC's data behavior before it goes live.
Worked example: how long does one poll cycle take for 40 registers at 9600 baud?
Scenario: a status screen written in VB.NET reads 40 holding registers from one PLC over an RS485 drop at 9600 baud. The arithmetic below decides the timeout, the poll period and the register ceiling for that screen.
- Request frame: 1 byte address + 1 function + 2 start address + 2 count + 2 CRC = 8 bytes.
- Response frame: 1 address + 1 function + 1 byte count + (40 × 2) data + 2 CRC = 85 bytes.
- Total on the wire: 93 bytes × 11 bits per RTU character = 1,023 bits.
- Wire time: 1,023 ÷ 9,600 bit/s = 106.6 ms, call it 107 ms.
- Silent gaps: two per cycle at 4 ms = 8 ms, so about 115 ms before the PLC thinks.
- Slave processing: tens of milliseconds is normal; take 20 ms and the cycle is about 135 ms.
- Against the settings: 135 ms is 13.5% of the 1 s poll period, and the 500 ms timeout leaves 365 ms of margin for a slow answer before the retry fires. A retried cycle takes 500 + 135 = 635 ms, which slips one poll and catches up on the next.
Result: one read request covers the whole screen, the timeout holds with margin, and the link idles more than 85% of each second. If the map grew past 125 registers, a second request would add roughly another 115 ms of wire time, still comfortable, but the polling code would need a request queue rather than a single call.
When does an OPC server win?
An OPC server wins when two or more applications need the same PLC data, when the PLC speaks a protocol you cannot implement yourself, or when a second consumer is already on the roadmap. One GUI with one register map is not that job.
The server's driver owns the wire. Your GUI reads named items with a quality flag, and a second client subscribes to the same items without anyone touching the PLC again.
The price sits on the software side: a licensed service to install and keep alive on the machine that runs your GUI, a driver configured against the PLC's exact endpoint, and client and server editions that must line up. A mismatch there is its own troubleshooting job; the notes on an OPC DA client that cannot connect to an OPC UA server show what that diagnosis looks like.
Several consumers on one PLC also raise a network question: does each PC poll directly, or does one feed serve them all? The direct-or-relay comparison for multiple PCs polling one PLC covers that choice. For the server side end to end, the CODESYS walkthrough of an OPC UA server for HMI clients shows what the configuration involves.
What should you prove before building the screens?
Read one known, non-critical value first and compare it with the PLC's online value. Then pull the cable for ten seconds and confirm the GUI flags the data bad and recovers. Both paths fail on mapping and recovery, not on protocol choice. The sequence that finds a wrong value in minutes:
- From the PLC project, record the protocol, the port settings and whether the port answers requests or initiates them; a client needs an answering endpoint.
- Read one known, non-critical register and compare it against the PLC's online value.
- If the value is wrong, check address offset, data type, word order and scaling, in that order, before touching the transport code.
- Pull the RS485 drop for ten seconds: the GUI must flag the values bad, keep the timestamps visible, and resume on the first good CRC.
- Leave writes out of the client until every read in the map is checked against the PLC's online values.
One safety note belongs here. A write to the wrong address can stop a machine or clear a fault someone is counting on, so the client stays read-only until the whole map has been checked register by register.
Which one do you build?
Build the Modbus client for one PLC and one GUI with a map under 125 registers. Build the OPC server path when a second consumer of the data already exists or the PLC's protocol is beyond what you can implement and test.
Recommendation: For one PLC and one VB.NET screen whose register map fits one read request of 125 registers or fewer, write the Modbus client at 9600 baud 8N1 with a 500 ms response timeout, one retry, a 1 s poll period, a timestamp on every read, and a stale flag after two missed polls. Move to an OPC server when a second application needs the same values, or when the PLC's protocol is one you cannot implement and test yourself.
If the screen ends up on a dedicated panel at the line, size the panel for its viewing distance before drawing a single screen. Then check the shop-floor screen notes for mounting, power and brightness where it will live.
Questions
Can I write the Modbus master in VB.NET without a library?
Yes. A plain serial port and a byte array are enough: the request is 8 bytes, the CRC is two checksum bytes you can generate from a published 256-entry lookup table, and the timing rules are the silent gap and the response timeout. What you must get from the PLC project is the register map, the slave address, the port settings and which data areas accept writes.
Does an OPC server remove the PLC-side configuration work?
No. The server still needs a driver that matches the PLC's configured protocol and endpoint, and the PLC still needs its port set and answering. A server repackages what its driver reads; when the driver cannot reach the PLC, nothing above it sees data. Confirm protocol and port settings from the PLC project before installing anything.
What if the project notes name a driver acronym nobody recognizes?
Treat the acronym as unresolved. Look for the protocol name in the PLC project's port configuration and in the installed server's driver list, and ask the panel builder for a communications summary if both come up empty. Screens planned around an unmatched acronym cannot be commissioned, so settle the name before estimating the work.
Can the same PLC values feed a wall board on the plant floor?
Yes, if the board runs software you write. Our panel-mount displays play offline media and can run your own Android app, so the same Modbus client logic and timing values live there too. The HDMI port on those units is an output only, so a PC cannot cable a duplicate of its screen to the board; the board's app reads the PLC directly. Confirm ports and configuration on the quote.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.