OPC UA explained for PLC programmers: what it is, how servers, nodes and subscriptions work, OPC UA vs Modbus vs OPC Classic, and what it means for your tags.
OPC UA (Open Platform Communications Unified Architecture) is how your PLC's tags get out of the controller and into everything else — SCADA, HMIs, historians, MES, dashboards, the cloud. If ladder logic and function blocks are how a machine thinks, OPC UA is how it talks, and it has quietly become the default answer to "how do we read the PLC's data" across vendors. This post explains OPC UA from the PLC programmer's side of the cable: what a server and a node actually are, what happens when a SCADA package subscribes to your tags, how it compares to Modbus and OPC Classic, and what it changes about how you should name and structure your logic.
What OPC UA Actually Is
OPC UA is a vendor-neutral standard (IEC 62541) for industrial data exchange. The model is client–server:
- The server holds the data. Today it's usually inside the PLC itself — Siemens S7-1500s, many CODESYS-based controllers and Beckhoff systems ship an embedded OPC UA server; for controllers without one (most Allen-Bradley Logix PLCs), a gateway or middleware box (Kepware/KEPServerEX, for instance) runs the server and talks the PLC's native protocol behind the scenes.
- Clients connect to read, write and subscribe: SCADA, HMIs, historians, custom apps, other PLCs.
Three properties explain why it won. It's platform- and vendor-neutral — the same client code reads a Siemens, a Beckhoff and a gatewayed Allen-Bradley identically. It carries structure and meaning, not just values — more on that next, because it's the big one. And it has security built in — certificates, signed and encrypted sessions, per-user access rights — which matters now that controllers sit on networks that reach far beyond the control panel.
Nodes, the Address Space, and Why This Beats Register Maps
Everything an OPC UA server exposes is a node in a browsable tree called the address space. Your Motor1_Run BOOL becomes a node with a path like PLC1 → Conveyor → Motor1 → Run, carrying not just its current value but its data type, timestamp, quality (is this value fresh or stale?), units, and description.
The contrast with Modbus makes the point. In Modbus, the motor status is holding register 40017, bit 3 — and the meaning of that bit lives in a spreadsheet someone maintains by hand, and the temperature next to it is a raw integer you must know to divide by 10. In OPC UA, a client browses the live server, discovers Motor1.Run as a named, typed Boolean, and subscribes to it. No register map, no scaling folklore, no "what's in 40018 again?" — the controller describes itself.
This is also why OPC UA replaced OPC Classic (the 1990s COM/DCOM version): Classic only ran on Windows, and anyone who ever fought DCOM permissions at 2 a.m. understands the migration. UA kept the good idea — a standard way to serve tags — and dropped the Windows dependency, adding security and the richer data model.
How Data Moves: Subscriptions, Not Polling
A naive integration polls every tag every second forever. OPC UA's native pattern is the subscription: the client says "monitor these 200 nodes; tell me when one changes by more than X, checking every 500 ms," and the server reports only changes. Less network load, fresher data, and per-tag quality stamps when something goes wrong.
For PLC-to-PLC and controller-to-cloud cases there's also PubSub (publish/subscribe, often over MQTT), but client–server subscriptions are the pattern you'll meet first and most.
Writes flow the other way — a SCADA setpoint lands in your DB/tag — which is why access rights matter: expose setpoints as writable, status as read-only, and never let an external write reach an output coil directly without passing through your own interlock logic. An OPC write is just another input to validate, exactly like a flaky sensor; the interlock discipline doesn't relax because the "operator" is software.
What OPC UA Changes About Your PLC Code
This is the part most OPC UA articles skip: the protocol is configured, not programmed, but it rewards certain habits in the logic itself.
- Name tags as if strangers will browse them — because they will.
Conveyor.Motor1.Runbrowses beautifully;B3[12].4punishes everyone downstream. Structured tags (UDTs / STRUCTs) map directly onto the address-space tree. - Expose engineering units, not raw counts. Scale the 4–20 mA input in the PLC (the scaling pattern is four lines) and serve
TempCas a REAL, so every client gets 87.3 °C instead of 13,214 counts and its own copy of the scaling math. - Mark the OPC boundary explicitly. Keep a dedicated folder/DB of tags meant for external consumption, and expose only that — both a security measure and a kindness: the SCADA integrator sees 60 intentional tags, not 4,000 internal ones.
- Expect stale values. A subscription that loses its session delivers "last known value, bad quality." Logic (and dashboards) that treat quality as part of the data don't lurch when a cable is pulled.
OPC UA vs the Alternatives, Honestly
| OPC UA | Modbus TCP | OPC Classic | |
|---|---|---|---|
| Data model | Browsable, typed, self-describing | Flat registers, meaning lives in a spreadsheet | Tags, but Windows/DCOM-bound |
| Security | Certificates, encryption, users | None in the protocol | DCOM (painful) |
| Discovery | Client browses the server | None — you must know the map | Limited |
| Footprint | Heavier; embedded servers or gateway | Tiny — runs on anything | Legacy only |
| Best fit | SCADA/MES/cloud integration, new builds | Simple devices, legacy gear, tiny links | Maintaining old systems |
Modbus isn't dead — for a power meter serving twelve registers it remains perfectly sensible, and half the installed base of industrial gear speaks it. The realistic plant runs both, with OPC UA as the layer where everything converges.
Where This Sits in the Learning Path
OPC UA is layer two of PLC competence: first the logic itself — the languages, timers, interlocks — then how that logic's data reaches the rest of the plant. You can practice the first layer entirely in the free simulator (the tag-naming habit included: structured names in your programs cost nothing and pay forever); the second layer starts the day your machine needs a dashboard. When that day comes, the checklist is short: confirm whether your controller embeds a UA server or needs a gateway, define the exposed-tag folder, set certificates (never anonymous-open in production), and hand the SCADA team a browsable tree they'll compliment you on.