Locating Time-Capture Counters in TIA Portal Programs
When a TIA Portal project accumulates dozens of FB, FC, OB, and DB blocks written across LAD, FBD, SCL, and even VBScript (HMI side), locating the block that owns a single counter, time-capture sequence, or scheduled acquisition becomes a navigation problem rather than a logic problem. This guide gives a deterministic procedure for finding the block that drives a 20-point, 3-second time capture in a cyclic interrupt such as OB30, then for verifying the interval timing and correcting it.
CTU instruction. In PID-driven temperature acquisition it is normally a small state machine: a timer or cyclic interrupt tick increments a tag, a comparator triggers a write into a 20-row array, and a second counter or MOD operator gates the 3-second period. Treat the search as a tag-trace, not as a counter search.1. Problem Definition and Engineering Scope
The reported symptom is twofold:
- The capture logic is hidden inside a long program split across LAD, SCL, and VBScript, in a language the user does not read, so manual network-by-network review is impractical.
- The intended 3-second interval between successive temperature captures is not being honored — successive readings are not 3000 ms apart.
Both symptoms share a root cause area: the cyclic interrupt organization block (OB30) that drives the capture sequence. The capture rate can drift or fail if (a) the OB30 cycle time is misconfigured, (b) the time base feeding the counter is a TON driven by OB1 cycle jitter rather than a hardware timer, or (c) the counter is reset by a condition other than completion of the 20-point window.
2. Prerequisites
- TIA Portal V15.1 or later (V16/V17 recommended for the Watch Table, Trace, and PLC Code Viewer features used below). Refer to the Siemens TIA Portal release notes for the features of your installed version.
- Project source files with write access (so cross-references can be re-generated on recompile).
- Online connection to the PLC for verification (or a PLCSIM instance mirroring the project).
- Operator rights to enable the HMI Runtime if VBScript is involved in the capture sequence.
- For interval measurement: a function-capable multimeter, scope on a DO flag, or the built-in TIA Portal Trace.
3. Navigation Strategy Overview
Use a four-step trace path. Each step is cheaper than the previous one to undo if it leads to a dead end.
- Tag-driven cross-reference — start from the DB that stores the 20-row table; TIA Portal will list every block that reads or writes it.
- Call structure (CFC-style) — from the candidate block, expand the call tree up to OB30 and down to any multi-instance DBs.
-
Search-in-project — sweep the project for the integer constant
3000(ms), the tag named with a_count/_idxsuffix, and the symbolic name of the temperature input. - Trace / watch verification — online, observe the counter increment, the array index advance, and the time delta between writes.
4. Step 1 — Open the Cross-Reference Browser
The cross-reference tool is the fastest path to the capture block because it does not require reading the code; it only requires knowing one tag.
Procedure:
- Identify the data block that contains the 20-row temperature table. The user can usually find it in the HMI tag list (HMI → PLC tags), because the HMI is bound to the array tag, even if the HMI script is written in a foreign language.
- In the project tree, right-click the DB and select Cross-references, or place the cursor on the array element and press Ctrl+Alt+F7.
- TIA Portal opens the Cross-reference window, which lists every block that writes, reads, or accesses the array. Filter by Access type = Write to find the block that fills the table.
- Double-click the entry under Access; TIA Portal jumps directly to the network that performs the write. Even if the block is in SCL, TIA Portal will highlight the line.
Shortcut reference:
| Action | Shortcut |
|---|---|
| Open Cross-references for selected tag | Ctrl + Alt + F7 |
| Go to / jump to usage | Ctrl + left-click on tag |
| Open Call structure | Right-click block → Call structure |
| Find in project (text search) | Ctrl + F |
| Compile project (rebuild cross-references) | Ctrl + B |
5. Step 2 — Identify the Cyclic Interrupt Source (OB30)
The capture sequence is a 20-point loop. The 3-second period almost always originates from a cyclic interrupt. Open the Program info or Call structure to see which OBs call the candidate block.
Procedure:
- Right-click the block found in step 1 → Call structure.
- Expand the tree upward. The capture block is typically called from OB30 (cyclic interrupt), OB35 (100 ms default), or from OB1 (main cycle) — each tells you the time base.
- Select OB30 in the tree → right-click → Properties. Verify the Cycle time and Phase offset. The factory default is 5 000 ms for OB30 on S7-300/400, but a project that uses OB30 for a 3 s capture will normally set the cycle to 3 000 ms (or 100 ms if a software counter inside the block divides the rate).
| OB | Default cycle | Typical use |
|---|---|---|
| OB30 | 5 000 ms (configurable 1 000 – 60 000 ms) | Slow process loops, PID, batch captures |
| OB35 | 100 ms (configurable) | Fast closed loops |
| OB1 | Scan time (variable) | Main; never use as time base for fixed-period capture |
For S7-1200/S7-1500 the cyclic interrupt is configured under PLC → Program blocks → OB30 → Properties → Cyclic interrupt [OB30]. The Siemens S7-1500 OB30 specification states that OB30 is always synchronized to the configured phase offset, so a write occurring once per 3 s is best implemented as a 3 000 ms OB30 calling a single network that increments a 0..19 index.
6. Step 3 — Find the Counter or Index
Inside the candidate block, locate the variable that ticks once per acquisition. The tag name typically contains one of the suffixes below.
| Tag suffix | Meaning | Where to look |
|---|---|---|
_cnt / _count
|
Acquisition counter | Search-in-project (Ctrl+F) for "_cnt" |
_idx / _ptr
|
Array index used in indirect addressing | Look for P# or WORD_TO_BLOCK_DB patterns |
_step |
State in a 2-phase capture | Look for CASE / IF-ELSE branching on 0/1 |
_done / _busy
|
Sequencer flags | Cross-reference any DB bit named "Done" |
Click on the array write line found in step 1. Above the write, TIA Portal will show the read of the counter/index. Common SCL patterns are:
#iCount := #iCount + 1;
IF #iCount >= 20 THEN
#iCount := 0;
END_IF;
"MyArray".Temp[#iCount] := "MyAI".PV;
or, more compactly, the project might use an IEC counter CTU instance DB_Counter. The cross-reference on the instance's CV (current value) tag jumps directly to the network where it is compared against the constant 20.
7. Step 4 — Search the Project for the 3-Second Constant
Open the project-wide search (Ctrl+F) and search for these tokens in order:
-
3000— direct ms constant for a 3 s timer. -
T#3s— IEC time literal (more common in SCL). -
3.0— may be a scaled time constant (seconds × 1000). -
OB30_PERIODor any constant DB entry named with a time suffix.
Match the search across All blocks, not just the current block, by clicking the small arrow at the right of the search box and selecting Search in project. The first match is normally the period source. If the constant is inside a tag (e.g. Config.tPeriodMs := 3000), double-click the constant to jump to the FB that owns the tag and inspect the default value.
TON block with PT = T#3s and the period drifts, the root cause is that TON is updated in OB1 — its period is then TON_Time + OB1_Scan_Time, not exactly 3 s. The fix is to move the increment into OB30 or replace the TON with a counter gated by an OB30 tick.8. Step 5 — Why the 3-Second Interval Is Wrong
After locating the counter, verify these common failure modes against the code. Each is a field-proven cause of interval drift in OB30-driven captures.
| Symptom | Likely cause | Fix |
|---|---|---|
| Interval is 3 s + ε (1–30 ms jitter) | OB30 has no phase offset configured; multiple OBs share the same 1 ms tick | Set OB30 phase offset in PLC properties → Start time |
| Interval is 6 s | Counter is incremented in OB1 while the period is in OB30 (effectively two ticks per 3 s) | Remove the OB1 increment, leave only the OB30 increment |
| Interval is irregular, jumps 1 s, 2 s, 5 s | Counter is reset by a process variable (e.g. PV out-of-range), not by reaching 20 | Add an explicit reset condition; do not couple reset to process alarms |
| First interval is 0, subsequent intervals are 3 s | Counter starts at 0, array index is also 0, so the first write fires on the first OB30 tick of warm restart | Initialize the counter to 0 only in OB100 / startup, never in the cyclic body |
| Interval increases under load | Watchdog or HMI VBScript on every cycle; communication load on the PN interface | Move DB writes out of OB1; reduce HMI polling to a fixed area |
9. Step 6 — Verify with Watch Table and Trace
Online verification is mandatory because the offline cross-reference cannot reveal priority or timing bugs.
- Create a new Watch Table (Watch table_1) and add:
- The counter / index tag
- The OB30 cycle time tag (read from System info)
- The array element the code writes to (e.g.
"MyTable".Temp[0]) - A tag indicating the time of last write (often a
TIMEorTIMESTAMPin the DB)
- Right-click the watch table → Modify if you need to manually reset the counter to 0 to start a clean 20-point run.
- Use the Trace feature (PLC → Traces → New trace) to record the counter at 1 ms resolution. TIA Portal can decode the time delta between successive counter increments and overlay it on the configured OB30 cycle.
Acceptance criterion: the time between counter increments must equal the OB30 configured cycle ± 1 ms. The Siemens S7-1500 Trace configuration guide explains how to set a rising-edge trigger on the counter tag and capture a 60 s window.
10. Common Pitfalls and Field-Notes
-
Two-phase capture in one FB. If the project uses 20 captures in two phases (10 + 10), the second phase is often a separate FC called by an
IF #iPhase = 1 THEN. Use the Call structure to see both phases even if only the first FC is called from OB30. -
VBScript on the HMI side. If the HMI script reads
SmartTags("DB")on a 100 ms schedule, the HMI can advance its own counter and write it back to the PLC, masking the OB30 logic. Check the HMI tag's Acquisition mode in the WinCC tag list. -
Indirect array access. SCL often uses a
WORD_TO_BLOCK_DBpattern with an offset word to write into the array. Search for the literalDW#16#or thePEEK/POKEsymbols. -
Multi-instance DBs. The counter may be a static tag of an FB that is called as a multi-instance; the name on the cross-reference will look like
FB_PID_1.InstanceCounter. Search for the FB name and let the cross-reference descend into the instance DB. -
Rewiring after a
Compile all. After a full compile, TIA Portal re-generates cross-references. If you change the period constant, the next compile is the only confirmation that no other block still uses the old value.
11. Summary Procedure (Cheat-Sheet)
- Right-click the 20-row DB → Cross-references → filter Write.
- Open the Call structure of the writing block; confirm OB30 is the parent.
- Inspect the counter / index tag increment and reset condition.
- Search the project for
3000,T#3s, or the period tag name. - Validate the OB30 cycle and phase offset in the PLC properties.
- Run online: watch the counter, use Trace to record intervals, and verify 3 000 ms ± 1 ms between writes.
What is the fastest way to find a counter in TIA Portal without reading every network?
Use cross-references. Right-click the data block that holds the 20-row temperature table, choose Cross-references (or press Ctrl+Alt+F7), and filter by access type Write. TIA Portal then lists every block that writes the table; double-click the entry to jump directly to the line that performs the write, even if the block is in SCL.
How do I find which organization block (OB) calls my time-capture block?
Right-click the candidate block and select Call structure. The tree shows all OBs that call the block. For a 3-second capture driven by a cyclic interrupt, OB30 is the expected parent; check its Cycle time and Phase offset in the block properties.
My captures are not 3 s apart — what is the most common cause?
The counter is being incremented in OB1 instead of OB30, or the OB30 cycle time is misconfigured. Move the increment into the OB30 body and verify the cycle time is 3 000 ms with no phase offset overlap. Use the TIA Portal Trace to confirm the interval is 3 000 ms ± 1 ms online.
Can I search the project for an integer constant like 3000 to find a 3-second timer?
Yes. Press Ctrl+F to open Find in project, type 3000, and run the search across all blocks. Also search for the IEC time literal T#3s and the tag OB30_PERIOD. The first match is normally the period source.
My project uses VBScript on the HMI — how does that affect the search?
If the HMI also writes to the temperature table, the cross-reference will show both the PLC block and the HMI connection. Check the WinCC tag's Acquisition mode; if the HMI is polling on a 100 ms schedule, it can advance a counter and overwrite the PLC value. Fix the HMI acquisition to read-only and let OB30 own the writes.