Auto-Changing Data Block Variables in TIA Portal S7-1200

David Krause13 min read
SiemensTIA PortalTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

Field engineers frequently need to drive values inside a Siemens S7-1200 data block (DB) on a fixed cadence during commissioning, factory acceptance tests (FAT), or network-integration checks when physical sensors are absent. Manually typing new values into a watch table is fine for a one-off check but quickly becomes impractical when the test must repeat every 500 ms, every 2 s, or whenever a pulse train is required. This reference shows four field-proven patterns for auto-changing DB variables in TIA Portal (V15.1 through V18) without any external hardware: a TON + INC ladder pattern, a compact SCL block, the SIM-flag pattern used for sensor substitution, and the built-in PLCSIM sequence generator. Each method is sized to a S7-1200 CPU (firmware V4.2 through V4.6) but the logic is identical on S7-1500 with the appropriate instruction set.

The technique selected depends on three constraints: (1) is the target DB optimized (default in V14+) or non-optimized, (2) is the controller physical or simulated in PLCSIM, and (3) does the test need a single increment, a ramp, a sequence, or a full sensor-replay waveform. The patterns below are written for each of those cases.

Prerequisites

  • TIA Portal V15.1, V16, V17, or V18 with the S7-1200 basic/advanced package installed.
  • STEP 7 Safety / SCL optional package enabled for the SCL snippets (Options → Manage TIA Portal add-ins).
  • CPU firmware ≥ V4.2 if you plan to use the project-view PLCSIM sequence generator (introduced in PLCSIM V15.1).
  • A data block already created in the project tree under Program blocks → Add new block → Data block. See the SIMATIC S7-1200 manual collection — Data block (DB) for the canonical DB concept page.
  • Watch/read access to the DB confirmed via an online watch table before any automatic code is added.
Note: If the DB is created with the Optimized block access checkbox enabled (default since TIA V14), the symbolic name is the only legal access path. Direct absolute addressing such as DB1.DBD8 is rejected by the compiler. The SCL snippets in this article work in both modes; the ladder examples assume symbolic access.

Method Comparison

Method Best for Cycle resolution Hardware required Works in PLCSIM
TON + INC ladder Single-tag periodic increment, FAT tests OB1 scan period None Yes
SCL timer + += Multiple tags, compact code OB1 scan period None Yes
SIM-flag + secondary OB1 Sensor-replay simulation, no code in main OB1 scan period None Yes
PLCSIM project-view sequencer Pure-software I/O replay 1 ms (project view) None (PLCSIM only) Yes (PLCSIM only)

Method 1 — TON Timer plus INC Instruction (LAD)

This is the most common pattern. A TON (Timer ON-delay) generates a 1 Hz (or 0.5 Hz) tick; on each rising edge of Timer.Q the INC instruction adds 1 to a tag inside the DB. One-shot behavior is enforced by briefly disabling the timer so a single pulse never re-triggers within the same scan.

Step-by-step

  1. Open the project in TIA Portal and navigate to Program blocks → Main [OB1].
  2. Add a new network (Network 1) and insert a TON instruction. Set IN = %M0.0 (or any boolean tag) and PT = T#1s for a 1 Hz tick. Tie IN to TRUE through a normally-open contact of a control bit RunTest if you want to enable the test on demand.
  3. Create tag TonTick of type TON_TIME (instance DB auto-generated by the call) or use a multi-instance inside a parent FB.
  4. In Network 2, add an INC instruction. Set IN/OUT to the symbolic name of the target DB tag, for example "MyData".Counter.
  5. Add a normally-open contact of TonTick.Q in series with the INC coil so the increment happens only on the rising edge.
  6. In Network 3, reset the timer so it can re-time the next interval. The cleanest way is to feed Timer.Q back into the IN input through an inverter — when Q goes high the input drops and the timer re-arms on the next scan. The ladder equivalent is a single NC contact of TonTick.Q driving the IN input of the same TON.

Ladder pattern (textual)

Network 1: 1-Hz tick
   |  RunTest   TonTick
   |---| |------(TON)---|       // IN = RunTest, PT = T#1s

Network 2: increment on tick rising edge
   |  TonTick.Q   "MyData".Counter
   |---| |-----------(INC)-------|   // adds 1 every second

Network 3: auto-reset of timer for next cycle
   |  TonTick.Q   TonTick.IN
   |---|/|----------|               // NC contact on Q drops IN
   |---(  )                         // pulse re-arm
Note: The timer reset is a one-shot. The TON must lose its enable input at least one scan to clear its ET accumulator, otherwise the next PT is not evaluated. Driving IN with the inverse of Q is the canonical pattern and survives OB1 restart conditions.

Method 2 — SCL Block with += Operator

When several DB tags must change in lockstep, an SCL block keeps the code small and the scan time predictable. The SCL increment operator += is functionally identical to the LAD INC instruction but is more readable when several tags are stacked.

Step-by-step

  1. Right-click Program blocks → Add new block → Function block. Name it FB_AutoRamp.
  2. Declare the following interface:
FUNCTION_BLOCK "FB_AutoRamp"
VAR_INPUT
    Enable : BOOL;          // TRUE = run ramp, FALSE = freeze
    Period : TIME := T#1s;  // tick interval
END_VAR
VAR
    TimerInst : TON_TIME;   // local multi-instance
    Tick      : BOOL;
END_VAR
VAR_IN_OUT
    Target    : INT;         // IN/OUT reference to any INT DB tag
END_VAR
BEGIN
    TimerInst(IN := Enable, PT := Period);
    Tick := TimerInst.Q;

    IF Tick THEN
        Target += 1;
        TimerInst(IN := FALSE, PT := Period);  // re-arm
    END_IF;
END_FUNCTION_BLOCK
  1. Call the FB from OB1 and connect the Target IN/OUT to the desired DB tag:
// OB1 Network 1
"InstAutoRamp"(Enable := RunTest,
               Period := T#500ms,
               Target := "MyData".Counter);
  1. Compile, download, and observe "MyData".Counter in a watch table. Each 500 ms it should advance by 1.

Why the IN/OUT pin?

Passing the target tag through an IN/OUT pin keeps the call site in control of which variable is driven. The FB itself is reusable across any INT, WORD, or DINT tag without modification. If the FB input pin is open, the compiler raises a Block parameter assignment incomplete error — this is the same behavior referenced in the project notes about FB instance-DB overwrite only being possible when the calling pin is wired.

Method 3 — SIM Flag with Secondary OB1

For tests where the production code must remain untouched (e.g. verifying an IOT2050 gateway that polls DB tags from a sibling PLC), the SIM pattern is the cleanest option. A global tag SIM gates a secondary OB1 that overwrites DB tags with simulated waveforms, leaving the real OB1 cycle undisturbed.

Step-by-step

  1. Add a new cyclic OB (right-click Program blocks → Add new block → Organization block → Cyclic interrupt). Use OB30 with a 100 ms cycle time as the simulator cycle.
  2. Declare a global tag SIM_ENABLE of type BOOL in a global DB or the standard tag table.
  3. First network of OB30:
IF NOT "SIM_ENABLE" THEN
    RETURN;     // simulator inactive, leave real values alone
END_IF;
  1. Subsequent networks drive the simulated tags. Example: a 0–100 sawtooth feeding "MyData".SawValue:
"MyData".SawValue := "MyData".SawValue + 1;
IF "MyData".SawValue > 100 THEN
    "MyData".SawValue := 0;
END_IF;
  1. Compile and download. Toggling SIM_ENABLE from the watch table starts and stops the simulated waveform without recompiling.
Note: A cyclic OB such as OB30 has a higher priority class than OB1. If the simulator code is heavy, monitor OB30.PRIORITY collisions and the OB80 (time error) buffer to make sure you are not starving the main cycle. The default S7-1200 supports OB1 and OB30–OB38; OB30 runs at the configured time slice regardless of OB1 scan time.

Method 4 — PLCSIM Project-View Sequencer

When the entire controller is virtual, PLCSIM V15.1+ exposes a project view with a sequencer that can replay any tag waveform at 1 ms resolution without writing a line of code. This is the fastest path when the goal is to validate the consumer (HMI, gateway, OPC UA client) and not the PLC code.

Step-by-step

  1. Start PLCSIM (Advanced) and load the project. Switch from the compact view (default) to the Project view via the toggle in the upper-right corner.
  2. In the project tree, open Sequencer → New sequence.
  3. Drag the target DB tag (e.g. "MyData".Counter) into the sequence. Add a step that writes a constant or a ramp and set its duration to 500 ms or 1 s.
  4. Add as many steps as the test requires and press Run sequence. The sequencer drives the tag through PLCSIM's internal image table; no PLC code is involved.
  5. Use the SIM table next to the sequencer to add one-shot pulses on boolean DB tags if the test requires a trigger bit as well.
Note: PLCSIM's sequencer writes to the process image, so any code that reads the input peripheral directly (PIO access bypassing the image) will not see the simulated value. The tag must be accessed symbolically through the I/O image or through a normal DB read. This is the same caveat that applies to the SIM-flag pattern when the I/O update is forced to automatic.

Optimized vs Non-Optimized DB Access

Property Optimized DB (default V14+) Non-optimized DB (classic)
Access path Symbolic only Symbolic and absolute
Default for new DBs Yes No (must clear checkbox)
Pointer math in SCL Not allowed Allowed with P#
FB multi-instance Supported Supported (legacy)
Watch table read Online → symbol path Online → address or symbol

If the project is locked to non-optimized blocks (e.g. legacy code imported from STEP 7 V5), the increment in SCL becomes:

DB1.Counter := DB1.Counter + 1;        // non-optimized, address-based

For optimized blocks, only the symbolic form is legal:

"MyData".Counter := "MyData".Counter + 1;
"MyData".Counter += 1;                // equivalent, single scan

Cycle-Time and Scan-Order Considerations

The S7-1200 OB1 runs as a free cycle. With a typical 1 ms scan on a 1214C and a TON period of 1 s, the timing resolution is well below 1% and the increment is rock solid. The pitfalls appear at sub-100 ms periods:

  • OB1 scan > TON period. If PT < OB1 scan time the timer expires between scans and the INC is missed. Either increase the period, lower the program size, or move the simulator into a cyclic OB such as OB30 with a fixed 1 ms or 10 ms time slice.
  • Two increments in one scan. The NC-reset pattern guarantees one increment per period. If the reset is missing, the TON holds Q high and the INC fires every scan for the duration of the overlap.
  • Integer wrap-around. INT ranges from -32768 to 32767. If the test must exceed this range, declare the target as DINT and replace INC with Target += 1; in SCL or with the ladder DINT increment.
  • Retain behavior. A DB declared with the Set Retain attribute keeps the simulated value through a power cycle. This is usually wrong for a simulator. Open the DB properties and clear the retain attribute for the simulator tags.

Verification

  1. Open a watch table, add "MyData".Counter, and click Monitor all. The value should advance at the configured period.
  2. Toggle RunTest off and confirm the value freezes. Toggle it on and confirm the ramp resumes.
  3. Force a STOP/RUN transition (online → restart) and verify the value resumes from the last written value, not from 0, unless the retain attribute was cleared (in which case it should reset to 0).
  4. For the SIM-flag pattern, observe SIM_ENABLE going true and the simulated tags overriding the real ones within one OB30 cycle.
  5. For PLCSIM, export the sequence to a CSV using Sequencer → Export and re-import it on the next test to confirm repeatability.

Troubleshooting Matrix

Symptom Likely cause Fix
Value never changes TonTick.Q never goes high Check the IN line of the TON; verify RunTest is TRUE
Value increments every scan Timer reset NC missing Insert the NC contact of Q on the IN line
Compiler error “Unknown identifier” on DB tag DB is optimized and absolute address used Switch to symbolic name or clear Optimized block access
Simulated value ignored by HMI HMI polls the input peripheral directly, not the DB Change HMI tag source to the symbolic DB tag
OB30 stops running after download Cyclic OB configured with unsupported time slice Use a supported multiple of 1 ms (1, 2, 5, 10, 20, 50, 100, 200, 500, 1000) on the S7-1200
Watch table shows red “Invalid value” FB instance DB overwritten while pin is open Wire all input pins in the calling block or use IN_OUT for the target
PLCSIM sequence runs but production code overwrites the tag OB1 writes to the same tag every cycle Disable the production code via a SIM enable, or move the test to a separate DB the production code does not touch

Edge Cases and Field Notes

  • External gateway scenario. When the data block lives on a sibling PLC that the local project only knows by IP, the SIM-flag pattern is the only safe option. The local PLC never touches the remote DB; the remote PLC's own OB30 drives the simulated values and the IOT2050 gateway (or any OPC UA client) reads them transparently.
  • Concurrent engineering. Adding a cyclic OB during a live commissioning can shift OB1 priority scheduling. Always download to STOP first, then to RUN, and clear the diagnostic buffer immediately after.
  • Security. Knowledge of the protection level (read-only vs full access) is required to overwrite DB tags. The CPU's Properties → Protection → Access level must be set to Full access (no protection) for the test user, or the corresponding password must be entered when going online.
  • Firmware dependency. The TON reset pattern works on every S7-1200 firmware. The SCL += operator requires the SCL optional package and a CPU firmware ≥ V4.0. PLCSIM's project view is V15.1+ only.

How do I auto-increment an INT inside an S7-1200 data block every 500 ms?

Add a TON with PT = T#500ms driven by a control bit, place an INC on the symbolic DB tag in the next network with a NO contact of Timer.Q, and add an NC contact of Timer.Q on the timer's IN line to re-arm it. Download to RUN and monitor the value in a watch table; it should advance by 1 every 500 ms.

Can I change a DB variable every scan instead of every 500 ms?

Yes. Drop the TON entirely and wire the INC directly to a constant TRUE contact. The tag will increment on every OB1 scan, giving the fastest possible rate, typically 1–3 ms on an S7-1214C. Watch the integer overflow after 32767 cycles or switch the tag to DINT.

Why does my FB instance DB refuse to accept external writes?

An instance DB cannot be overwritten from outside the FB unless the corresponding input pin of the calling block is wired. To accept external simulation, expose the target tag as a VAR_IN_OUT in the FB and connect it at the call site; otherwise the compiler will raise Block parameter assignment incomplete at download time.

Does the PLCSIM sequencer work without writing any PLC code?

Yes. Open PLCSIM in project view (not miniature view), create a new sequence, drag the target DB tag into the sequence, add steps with the desired values and durations, and press Run. The sequencer drives the tag through the process image at 1 ms resolution and no user program is required.

What is the safest pattern when a gateway like the IOT2050 polls the DB?

Use a SIM flag plus a secondary cyclic OB (OB30). The flag gates the simulator; the simulator writes to the DB only while the flag is true. This way the production code is untouched, the gateway reads the simulated value transparently, and toggling the flag returns the system to live values without recompiling or downloading.

Back to blog