Reading process values from a Siemens S7-300 CPU through the SIMATIC NET OPC Server (DA 3.0) is the most common path for a custom VB.NET HMI, but it is also one of the easiest configurations to mis-tune. Engineers frequently discover that animation refresh slows to a crawl as soon as a screen contains more than a handful of tags, and the instinctive reaction — lowering the UpdateRate — usually makes things worse. The genuine fix is to switch from a poll-based OPC architecture to a subscription-based architecture, then co-tune the CPU-side communication jobs, the S7 connection count on the CP 343-1, and the DB / Merker layout in STEP 7.
1. Problem Profile: When OPC Reads Get Slow
A typical failing configuration looks like this on a CPU 317F-2 paired with a CP 343-1 Lean:
- SIMATIC NET OPC Server (DA 3.0, ProgID
OPC.SimaticNET) running on a Windows node and exposed to a custom HMI. - VB.NET client using the legacy
OPCAutomation.dllCOM interop wrapper. - One
OPCGroupcontaining a mix of contiguous Merker double words (e.g.MD3000..MD3100) and scattered bits/bytes inside data blocks such asDB100.DBX. - Mixed
AsyncReadcalls and synchronousOPCItem.Read(OPCDevice)calls invoked from the UI refresh loop or a fast timer. -
UpdateRatedropped to 100 ms or even 50 ms in an attempt to "speed things up".
The observable symptom is an HMI whose display lag increases non-linearly with the number of items and the number of screen changes. CPU online diagnostics (STEP 7 > PLC > Module Information > Communication) show an elevated OB1 cycle and a "Communication load" slice that frequently hits the configured 20 % ceiling. The root cause is rarely the Ethernet cable or the OPC server itself; it is almost always the read pattern.
UpdateRate makes the HMI slower, you are already saturating either the OPC server's internal cache, the S7 connection on the CP, or the CPU's communication-job budget. Throwing more cycles at a saturated resource only deepens the queue.2. SimaticNet OPC DA Architecture Fundamentals
The SIMATIC NET OPC Server sits on top of the S7 protocol stack. For S7-300 systems, the relevant product variant is SIMATIC NET PC Software with the OPC Server component installed. Each OPC DA group corresponds to a subscription inside the server, and each subscribed item corresponds to one read job against an S7 connection. The server caches the most recent value and re-publishes it via IOPCDataCallback::OnDataChange (DA 3.0) or the legacy OPCAutomation DataChange event (DA 2.0 wrapper).
For the official product description and supported operating systems, refer to the SIMATIC NET OPC Server manual entry on the Siemens Industry Online Support portal at support.industry.siemens.com — SIMATIC NET OPC Server. The entry-point page for SIMATIC NET product documentation is SIMATIC NET PC Software documentation overview.
Two architectural choices drive the throughput ceiling:
-
Subscription vs. polling. A subscription item is read once on
IsActive=True, then refreshed only by the server's internal sampler atUpdateRateintervals. A poll item is fetched on demand by the client. Subscriptions scale; polls do not. -
Item packing. The server can pack contiguous bytes into a single S7 read PDU.
MD3000, 25is one read PDU covering 100 bytes; 25 separateMWitems become 25 separate PDUs. The packing gain is 25× in the best case and is limited by item contiguity and the server's item-cache alignment.
3. Polling vs Subscription: The DataChange Model
The legacy OPCAutomation wrapper exposes both models. The poll model uses OPCGroup.AsyncRead or OPCItem.Read(OPCDevice). Each call consumes a transaction slot and, in the case of OPCDevice, forces a physical read of the PLC every time it is invoked. The subscription model uses the DataChange event:
- Add items once via
OPCItems.AddItem(ItemID, ClientHandle). - Set
OPCGroup.IsSubscribed = TrueandOPCGroup.IsActive = True. - Set
OPCGroup.UpdateRateto the desired sample interval in milliseconds. - Handle the
DataChangeevent; the server pushes only items that have changed.
The behavioural difference is fundamental: polling is pull-based and runs at the client's timer rate; subscription is push-based and runs at the server's sampler rate, firing only when values change. For a screen with 100 tags that change infrequently, the subscription model can drop the CPU-side read load by 1–2 orders of magnitude because the OPC server stops re-issuing read PDUs for unchanged data.
The trade-off is that UpdateRate becomes the floor on detection latency for changed values; for animations driven by slowly-changing setpoints this is irrelevant, but for fast loops it matters. The empirical sweet spot for HMI animation on S7-300 hardware is 200–500 ms.
4. Tuning OPCGroup.UpdateRate and Deadband
The OPC DA 2.0 specification defines two timing parameters and one filtering parameter on OPCGroup:
| Parameter | OPC Automation property | Typical value | Effect |
|---|---|---|---|
| Sample (Refresh) rate |
UpdateRate (ms) |
200–500 | Server-side interval between cache reads of the S7 connection. |
| Keep-alive rate | Derived (≤ UpdateRate) | 0 (disabled) | Forces a callback even if nothing changed; leave disabled. |
| Deadband | Per-item (DA 3.0) or group-level (DA 2.0) | 0 (analog); 1 (digital) | Suppresses DataChange callbacks for changes smaller than the deadband. |
Lowering UpdateRate below the OB1 cycle of the CPU is a common error. If the CPU runs at 100 ms OB1 and the OPC sampler at 50 ms, every other sample is a duplicate. Set UpdateRate > OB1 with a 1.5×–2× margin. For a CPU 317F-2 with a typical 50–150 ms OB1, UpdateRate = 300 ms is a safe default.
DataChange fires only when the cached value differs from the new value (or when the deadband is exceeded for analog items). For boolean items this is effectively free filtering.5. CPU-Side Communication Job Configuration
Every OPC subscription item that maps to an S7 read consumes one communication job (Auftrag) on the CPU's communication resource pool. The S7-300 family defines a fixed number of communication jobs per OB1 cycle. The relevant knob is the Scan Cycle Load from Communication parameter in the CPU object properties under STEP 7 (HW Config > CPU > Properties > Cycle/Clock Memory tab).
| CPU | Order number example | Communication jobs per OB1 (typ.) | Notes |
|---|---|---|---|
| CPU 312 / 314 | 6ES7 312-… / 6ES7 314-… | 6–8 | Smallest budgets; sensitive to item count. |
| CPU 315-2 DP / PN | 6ES7 315-2EH14-… | 10–12 | Most common mid-range target. |
| CPU 317-2 DP / PN | 6ES7 317-2EK14-… | 12–16 | Source CPU; ~12 named connections in practice. |
| CPU 319-3 PN/DP | 6ES7 318-3EL01-… | 32 | High-end S7-300 / pre-S7-1500 bridge. |
The exact value for a given CPU is documented in the CPU's data sheet on Siemens Industry Online Support; cross-reference the order number (MLFB) to obtain the specific job count for the firmware version in use. The umbrella S7-300 CPU manual entry is at S7-300 CPU 31x and CPU 31xC — Manual.
If a single OPC group contains 50 items and each item maps to one job, the CPU will spend a measurable slice of OB1 servicing those jobs. The "Scan Cycle Load from Communication" ceiling (default 20 %) clamps how much wall-clock time OB1 will give to communication. Raising this from 20 % to 50 % is a legitimate fix when OPC throughput is the bottleneck and the application OB1 headroom allows it, but it should be done deliberately and with the documented value of the CPU's communication-job budget in mind.
6. S7-300 Connection Budget and CP 343-1 Limits
Each OPC DA group that resolves to a different S7 connection consumes one S7 connection on the CP 343-1. The CP 343-1 family has fixed S7-connection resources (typically 16 / 32 / 48 depending on the variant). For the CP 343-1 Lean, the maximum number of S7 connections is documented in the device manual at CP 343-1 Lean — Manual; for the CP 343-1 Advanced variants, see the corresponding entries under the SIMATIC NET / CP documentation index.
Best-practice limits:
- One S7 connection per OPC server channel. Do not exceed 8 active connections on a CP 343-1 Lean for HMI traffic; reserve the remainder for PG, routing, and other HMIs.
- If the OPC client cannot reduce its item count, split it across multiple
OPCGroupsthat share one S7 connection, or across multiple S7 connections if the CP budget permits. Within a single connection, the OPC server still serialises PDUs; multiple connections give parallel read paths. - PG and HMI connections compete for the same CP resources. STEP 7 online diagnostics ("Connected stations", "Connection diagnostics") reveals the active connection table.
Formula: Effective Throughput per Connection
For a packed contiguous read of N bytes over a single S7 connection at T ms per PDU, the effective data rate is:
R = N / T [bytes/ms] = (N / T) × 1000 / 1024 [kB/s]
For a CP 343-1 with a typical user-data PDU of 480 bytes and a per-read turnaround of 30–80 ms over 100 Mbit/s copper, a single packed read tops out around 6–16 kB/s. Fifty 4-byte items packed into one read of 200 bytes yields roughly 2.5–6.7 kB/s effective; fifty separate 4-byte reads, each carrying only 4 bytes of payload, are dominated by protocol overhead and run an order of magnitude slower.
7. STEP 7 Data Block Layout for Bulk Reads
The single largest optimisation on the PLC side is to organise the data the HMI needs into a contiguous block inside a single data block, then read it as one array. Two patterns work:
-
Image block. A DB (e.g.
DB100) reserved for HMI display values. PLC code copies process values intoDB100at a controlled rate. The HMI reads the entire DB as one item, e.g.S7:[S7 connection_1]DB100,BYTE0,400, and parses bytes client-side. - Merker window. Reserve a Merker (M) area and have the PLC code write HMI-bound values into MD/MW/MB cells in a single FC. The HMI reads a contiguous MD range.
The SimaticNet item syntax for a packed DB byte array is:
S7:[S7 connection_1]DB<db_number>,BYTE<byte_offset>,<byte_count>
S7:[S7 connection_1]DB<db_number>,WORD<offset>,<word_count>
S7:[S7 connection_1]DB<db_number>,DWORD<offset>,<dword_count>
S7:[S7 connection_1]M<type><offset>,<count>
For a screen with N values, the goal is one item per screen, not N items. The OPC server then issues one packed PDU per UpdateRate, regardless of N.
8. VB.NET Implementation: Switching to DataChange Events
The following pattern replaces per-tick AsyncRead / Read(OPCDevice) calls with a single subscribed group. It maps each ClientHandle to the start address of its Merker double word, so the callback handler can route the incoming value without a dictionary lookup.
Imports OPCAutomation
Public WithEvents MGroupObj As OPCAutomation.OPCGroup
Private Const PLC As String = "S7:[S7 connection_1]"
Public Sub InitDChangeOPC(ByRef Groups As OPCGroups, _
ByRef Group As OPCGroup, _
ByVal ClientArray() As Integer)
' Clear previous subscriptions on screen change
Groups.RemoveAll()
Group = Groups.Add("HMIScreen")
Group.UpdateRate = 300 ' ms; >= 1.5x OB1 of CPU 317F-2
Group.DeadBand = 0 ' 0 for booleans/dwords; tune for floats
Group.IsSubscribed = True
Group.IsActive = True
For i As Integer = 1 To UBound(ClientArray)
' ItemID example: "S7:[S7 connection_1]MDWORD3000,1"
Group.OPCItems.AddItem(PLC & "MDWORD" & ClientArray(i) & ",1", _
ClientArray(i))
Next
End Sub
Private Sub MGroupObj_DataChange(ByVal TransactionID As Integer, _
ByVal NumItems As Integer, _
ByRef ClientHandles As System.Array, _
ByRef ItemValues As System.Array, _
ByRef Qualities As System.Array, _
ByRef TimeStamps As System.Array) _
Handles MGroupObj.DataChange
Dim i As Integer
For i = 1 To NumItems
' ClientHandles(i) = MD address (e.g. 3000 -> MD3000)
If Qualities(i) = 192 Then ' OPCQualityGood = 0xC0 = 192
MDoub(CInt(ClientHandles(i))) = ItemValues(i)
End If
Next
End Sub
Three points worth highlighting:
-
Groups.RemoveAll()cost. On a CP 343-1 with a steady OPC subscription this is dominated by OPC server-side teardown and is sub-50 ms in observed cases. Removing items from the group withOPCItems.Removeis functionally equivalent and avoids recreating the group object. - Client handle as address. Using the MD address as the client handle eliminates a hash-table lookup in the callback. For screens with more than 200 tags this is the difference between a 1 ms and a 5 ms callback.
-
Quality gating. OPC quality 192 (
OPCQualityGood) is the only value that should drive display. 0 (OPCQualityBad) means the OPC server could not read; 64 (OPCQualityUncertain) typically indicates a warm-restart on the CPU. Failing to check quality causes "stale" displays after a CPU stop/start.
9. Scan Cycle Load Tuning in HW Config
STEP 7 exposes two relevant settings on the CPU properties dialog (HW Config > CPU > Properties > Cycle/Clock Memory):
| Parameter | Default | Range | Recommendation |
|---|---|---|---|
| Scan cycle monitoring time | 6000 ms | 100–6000 ms | Leave default unless OB1 growth is documented. |
| Scan cycle load from communication | 20 % | 5–50 % | Raise to 35–50 % only when OPC throughput is the documented bottleneck and OB1 has headroom. |
| OB85 call on communication errors | per fault | — | Disable for production if logs show communication-error floods. |
The "Scan cycle load from communication" cap is not a connection limit; it is a time-share limiter. Raising it gives the operating system more wall-clock to service S7 communication jobs inside OB1. If the application OB1 has spare time (cycle time well below the monitoring limit), raising the cap from 20 % to 50 % can roughly double the achievable OPC throughput at the cost of longer OB1 worst-case time. The trade-off is documented in the S7-300 CPU manual at support.industry.siemens.com — S7-300 manual.
10. Diagnostics with OPC Scout and STEP 7
SIMATIC NET ships an OPC test client called OPC Scout (also referenced as OPC Scout V10 in newer installs). The diagnostic workflow is:
- Open OPC Scout and connect to
OPC.SimaticNET. - Add the same item list the HMI uses. Confirm the items appear with quality 192.
- Use the built-in cycle display to record actual refresh period versus the configured
UpdateRate. If the actual period is much larger than the configured one, the OPC server is queue-saturated; reduce the item count or raiseUpdateRate. - Cross-reference with STEP 7 PLC > Module Information > Communication on the CPU. Look at the "Communication load" bar and the OB1 cycle histogram.
OPC Scout V10 is part of the SIMATIC NET PC Software installation and is documented alongside the OPC server on the Siemens Industry Online Support portal at SIMATIC NET PC Software — Documentation overview.
11. Troubleshooting Matrix
| Symptom | Likely cause | Verification | Fix |
|---|---|---|---|
| Slow updates on heavy screens, fast on light screens | Too many items per group; CPU comm-job cap | Count items; check CPU comm-job budget vs. items | Pack items into contiguous DB blocks; split across multiple connections |
Lowering UpdateRate makes things slower |
OPC server queue or CP S7 connection saturation | OPC Scout cycle display | Raise UpdateRate to >1.5× OB1; switch to subscription |
| HMI freezes after CPU stop/start | Quality not checked; values stale | Inspect Qualities in DataChange
|
Filter on quality 192; force re-add on quality drop |
| CB 125 CPU goes to STOP with "communication overflow" | Communication job budget exceeded | CPU diagnostic buffer | Raise "Scan cycle load from communication"; reduce item count |
| Reads work, writes are slow | OPC server writes are synchronous and serialised | OPC Scout per-item latency | Coalesce writes; only write on operator action; use transactional AsyncWrite with TransactionID grouping |
| Random OPC disconnects with slow periods | CP 343-1 connection table full; keep-alive lost | CP diagnostics; event log | Reduce concurrent OPC connections; enable S7 connection keep-alive in PC station config |
12. End-to-End Tuning Checklist
- Profile the slow screen in OPC Scout V10. Record actual
UpdateRateachieved with the same item list. - Reorganise PLC data: copy the HMI-bound values into a single contiguous DB block per screen. Eliminate non-contiguous scattered reads.
- Switch the VB.NET client from
AsyncRead/Read(OPCDevice)to a single subscribedOPCGroupwithIsSubscribed = True,IsActive = True, andUpdateRate≈ 300 ms for a CPU 317F-2. - Use the MD address as the
ClientHandleto skip a dictionary lookup inDataChange. - Filter on
Qualities(i) = 192and re-add items on quality drop. - If the OPC Scout measurement still shows actual > 2× configured
UpdateRate, split the items across two or more S7 connections on the CP 343-1 (respecting the CP connection budget). - If the CPU diagnostic buffer logs communication-overflow events, raise "Scan cycle load from communication" from 20 % to 35 % and document the change.
- Document the CP 343-1 connection count in use and the OPC server's group / item totals for the next engineer.
What is the recommended OPC UpdateRate for an S7-300 CPU 317F-2?
Set OPCGroup.UpdateRate to roughly 1.5×–2× the OB1 cycle of the CPU. For a CPU 317F-2 with a 50–150 ms OB1, 300 ms is a safe default. Lower values queue up in the OPC server and on the CP 343-1, paradoxically slowing the HMI.
How many S7 connections can a CP 343-1 Lean handle for OPC traffic?
The CP 343-1 Lean supports a fixed number of S7 connections documented in its device manual. Reserve connections for PG (STEP 7 online), routing, and other HMIs; in practice, keep OPC traffic below roughly two-thirds of the documented maximum to leave headroom for diagnostics and reconnection storms.
Should I use AsyncRead or the DataChange event for HMI animation?
Use the DataChange subscription model with IsSubscribed = True and IsActive = True. AsyncRead and synchronous Read(OPCDevice) force a physical PLC read on each call; the DataChange event is push-based and only fires when a cached value changes at the configured UpdateRate.
Why is "Scan cycle load from communication" important for OPC?
It caps the wall-clock slice of OB1 that the CPU dedicates to S7 communication jobs. If OPC subscription items map to more jobs than the cap allows, jobs queue and the effective update rate falls. Raising it from the default 20 % to 35 % or 50 % can increase OPC throughput, provided the application OB1 has spare time.
How do I verify whether the OPC server or the CPU is the bottleneck?
Open OPC Scout V10 (bundled with SIMATIC NET), add the same item list, and compare the configured UpdateRate to the actual refresh period. If the actual period is far longer than configured, the OPC server / CP path is saturated. Cross-check with STEP 7 PLC > Module Information > Communication; if the communication-load bar is pegged and the CPU diagnostic buffer logs communication-overflow events, the CPU-side budget is the bottleneck.