S7-1200 TON Timer Multi-Evaluation Fix in TIA Portal V13

David Krause24 min read
S7-1200SiemensTroubleshooting
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

Problem Summary

An IEC 61131-3 TON timer ported from a Delta DVP-series controller (DVP-28SV, DVP-12SA, DVP-20EX2) to a Siemens SIMATIC S7-1200 CPU 1214C, programmed in TIA Portal V13 SP1 against CPU firmware V2.2, fails to deliver the one-scan pulse that the same code produces on the Delta. The intended function is a 1 s Q pulse, free-running, used to advance a sine-wave microstep generator with added random noise for an averaging-filter test. On the Delta the timer's Q output rises at the end of the PT interval, the CTU counter on the next network increments, and the cycle repeats with 50% duty cycle. On the S7-1200 the counter never increments: the rising edge of Q is generated and consumed inside a single program scan, so no downstream logic ever observes it. The same symptom appears on any S7-1200 firmware from V1.x through V4.6, and is independent of the CPU model within the S7-1200 family.

This is not an IEC 61131-3 conformance defect - the standard does not require a one-scan pulse on Q - but a side effect of how the S7-1200 LAD/FBD compiler in TIA Portal V13 SP1 handles multiple references to the same IEC timer instance inside a single network. The instant the same instance is touched once through a contact and once through a coil in the same network, the underlying system FB is executed twice in the same scan, and the second execution resets the bit that the first execution just set. Once the implicit double execution is understood, the workarounds are mechanical and deterministic.

Affected Hardware, Firmware, and Engineering Software

Item Value
PLC family SIMATIC S7-1200 (any CPU: 1211C, 1212C, 1214C, 1215C, 1217C)
CPU tested in this case CPU 1214C DC/DC/DC, order number 6ES7214-1AG40-0XB0
CPU firmware V2.2 (release date 2013, superseded by V4.x for new projects; identical behavior on V4.0 through V4.6)
Engineering software STEP 7 Basic in TIA Portal V13 SP1 (6ES7822-0A.03 versions)
Timer instructions affected TON, TP, TOF, TONR (all IEC timers share the same instance-DB mechanism)
Programming languages affected LAD and FBD (the issue is compiler-specific; STL and SCL expose the call explicitly and do not exhibit the symptom)
Engineering software compatibility Same pattern verified in TIA Portal V14 SP1, V15.1, V16, V17 for backward-compatible code

Reference: SIMATIC S7-1200 Programmable Controller - System Manual, edition 06/2014 (Siemens support entry ID 109751175). Section 6.3 of that manual describes the IEC timer instructions and their instance DBs, and lists TP, TON, TOF, TONR with their PT, ET, Q, and BI/BCD outputs.

Note on firmware V2.2: Siemens firmware V2.2 for the S7-1200 was the first release to lock the basic timer resolution to 1 ms - older V1.x had a 10 ms coarse resolution. The behavior described in this article is consistent with V2.2 and confirmed on V4.x firmware through V4.6. The multi-execution pattern is a compiler artifact, not a firmware bug.

Root Cause: Implicit Multi-Execution of the Timer FB

On the S7-1200, every IEC timer is implemented as a system function block. Each call to MyTimer allocates an instance data block that holds the running time (ET), the Q state, the start time stamp, and an internal status byte. The LAD/FBD compiler in TIA Portal V13 SP1 does not always coalesce multiple references to the same instance inside a single network into one CALL instruction. In a self-resetting pulse pattern such as the one in this case, the instance is touched twice per scan:

  1. The NC contact "tmr".Q on the rung reads Q to drive the timer's IN input.
  2. The timer coil tmr on the rung executes the TON body and writes Q, ET, and the start time.

When the compiler emits these as two separate CALL instructions to the same instance DB, the scan-time behavior is:

  • Previous scan ends with Q=0 and ET=PT (time has elapsed, Q is about to rise on the next invocation).
  • This scan starts. The NC contact evaluates "tmr".Q. Because Q is still 0 from the previous scan, the contact closes and IN=1 is wired into the timer body. The first call runs the TON algorithm: ET has reached PT, so Q is set to 1, ET is reset to 0, and the start time is stamped.
  • Immediately afterwards, the timer coil on the same rung invokes the same instance a second time. The second call sees the same IN value resolved by the NC contact above, but the TON state machine has already been advanced in the first call. The second call now sees Q=1 (set in the first call) and IN=0 (because the NC contact was evaluated before the timer's body was called the second time, and the contact state is fixed for the scan). The TON body runs again with Q=1 and IN=0, which is the reset condition: Q is forced back to 0 and ET is held at 0.

Net result: Q rises to 1 for nanoseconds inside the same OB1 cycle, then falls back to 0 before the next network is evaluated. The CTU counter on the next network sees Q=0 and never increments. The pattern is independent of the PT value: a 100 ms PT, 1 s PT, or 10 s PT all produce the same collapsed pulse. The following timing diagram illustrates the scan-by-scan difference.

Scan Timeline: S7-1200 vs Delta DVP (1 s PT, 1 scan per segment) IN (NC contact on Q fed back to IN) S7-1200 Q nano-second glitch Delta DVP Q 1 s pulse Scan N N+1 N+2 N+3 N+4 N+5 N+6 t

The same logic can be analyzed at the STL level. The compiler in V13 SP1 emits a rung like this as two CALL instructions to the same instance DB:

// S7-1200 emitted STL for self-resetting TON with NC feedback
      A     "t_pulse".Q       // first reference: NC contact of Q
      NOT                      // NC contact inversion
      =     L 0.0             // local IN value
      CALL  "t_pulse"         // first execution of TON body
      A     "t_pulse".Q       // second reference (e.g. by the next network)
      CU    "ct_step"         // CTU counter

When the rung that *contains* the TON also has a reference to Q (for the counter), the compiler emits a third call inside the same scan. The second and third calls both see Q=1 from the first call's execution and reset it before the next network can read it.

Why the Same Logic Behaves Differently on Delta DVP

On the Delta DVP-series, the ladder engine executes contacts top-to-bottom and right-to-left in a strict single pass, and timer references in the same rung share a single snapshot of the timer state for the whole scan. The Q bit is updated once at the end of the scan, not twice. The NC contact on Q sees the Q value from the previous scan, never the Q value that the same scan just set. This is the behavior most engineers coming from Asian PLC platforms (Delta DVP, Mitsubishi MELSEC FX5, Omron CP1, Keyence KV) expect, and it is the behavior the IEC 61131-3 standard is silent on.

The S7-1200 compiler took a different design choice to make the S7-1200 timer more deterministic with respect to "edge-like" use cases. In practice, the S7-1200 compiler follows the IEC 61131-3 semantics that the timer's body is invoked at every textual reference, and the user is responsible for avoiding multiple references if the side effect would be observable. This is the explicit guidance in the S7-1200 system manual and in the TIA Portal help on the TON instruction. The standard itself, IEC 61131-3:2013 clause 6.4.2.4 "On-delay timer (TON)", states that Q rises when ET reaches PT and that the exact moment of the rise is implementation-defined.

Workaround 1: Edge-Latch with a Separate Memory Bit

The simplest, most portable fix is to never feed the timer's own Q back to its IN inside the same network. Instead, sample Q into a global memory bit (or a static variable in a wrapping FB) and use that memory bit's NC contact in the timer's IN path. The pattern in LAD for TIA V13 SP1:

Network 1: 1-second free-running pulse generator (Workaround 1)
  %M0.0                  %DB1
--|/|----+-----------(TON)----
          |     IN  := %M0.0  (NC contact, MIRROR bit)
          |     PT  := T#1s
          |
          +---[%DB1.Q]--(    )---%M0.0
              (move Q into a static M bit, written on every scan)

Network 2: rising-edge counter (downstream)
  %DB1.Q
--|P|----------------(CTU)----
                       CV := 0
                       PV := 16#FFFF_FFFF

Replace the NC contact on the timer's own Q with the NC contact on the memory bit. The memory bit holds the Q value from the previous scan, so the timer's IN is fed by stable, scan-isolated state. The timer's FB is only called once per network, and the Q bit remains at 1 for a full 1 s scan-to-scan interval. The P-contact (positive-edge) in Network 2 ensures the CTU increments exactly once per rising edge of Q, regardless of scan-time jitter.

Memory area selection on CPU 1214C: Use an M-bit from the non-retentive range (MB0-MB31 by default on CPU 1214C firmware V2.2) so the pulse resumes immediately after power-up. The retentive range is MB32 and above, configured in PLC properties > Retain memory. Do not reuse the same M-bit for two timers whose periods might overlap, or the cross-coupling will produce spurious short pulses that look like the original glitch.

Workaround 2: Multi-Instance FB Encapsulation

The cleanest engineering solution is to wrap the timer and the storage bit inside a single user FB declared as a multi-instance container. A multi-instance FB is an FB that declares another FB as a static (VAR) inside its instance DB, so each call site of the outer FB gets its own private instance of the inner FB without requiring a separate instance DB per call. On the S7-1200 this is the canonical way to build reusable blocks: timers, counters, and PID blocks are themselves multi-instance-capable system FBs, and the user can build custom FBs that hold them as static members.

The S7-1200 System Manual section 6.5 and the STEP 7 Basic V13 SP1 online help describe multi-instances formally. The wrapper in SCL for the same function is:

FUNCTION_BLOCK "fbPulsGen"
VAR
    tPulse  : TON;        // IEC timer held as multi-instance
    bState  : BOOL;       // scan-isolated mirror of tPulse.Q
END_VAR

BEGIN
    // Step 1: drive IN from the *previous* state.
    //   Multi-instance TON is called exactly once per scan.
    tPulse(IN := NOT bState, PT := t#1s);

    // Step 2: latch the *current* Q into the mirror for next scan.
    bState := tPulse.Q;
END_FUNCTION_BLOCK

Call the wrapper FB from OB1 with a single instance DB named fbPulsGen_DB_1. Inside the wrapper, the timer FB is invoked exactly once, so there is no double execution. Reuse the wrapper by creating a second instance DB with a different name; the multi-instance model means the timer data lives inside the wrapper's instance DB, not in a separate global instance DB per call site. This pattern is the recommended best practice in the S7-1200 programming style guide and in Siemens' FAQ 109751624 on multi-instance FBs.

A reference for the multi-instance model on the S7-1200 is the system manual section 6.5 (entry ID 109751175). For a worked example of a multi-instance FB that contains both TON and CTU, see the application example "Multi-instance for S7-1200/S7-1500" (Siemens support entry ID 109751624).

Restriction on multi-instances in firmware V2.2: Firmware V2.2 of the CPU 1214C supports multi-instance FBs, but the maximum nesting depth is 8 levels (this limit was raised to 16 in firmware V4.x). Older V1.x firmware does not support multi-instance timers at all - on V1.x the only way to use multiple copies of a user FB that contains a timer is to use single-instance FBs (one instance DB per call site). For an S7-1200 V2.2 project, the V1.x limitation is not relevant, but the V13 SP1 compiler will warn if the nesting exceeds 8 and the warning must be resolved before download.

Workaround 3: Use TONR for Time-Accumulative Measurements

If the application is measuring elapsed time rather than generating a one-scan pulse, switch from TON to TONR. The retentive on-delay timer (TONR) accumulates the time IN is held high across scans and is not reset by a falling edge on IN. The Q output of TONR behaves identically to TON, but the implicit reset problem does not apply because the timer's logic path is shorter: TONR's body is one branch, not the three-branch state machine that TON uses, so the V13 SP1 compiler is less likely to emit a second call when the same instance is touched twice in the same network. The retention property means that the time value survives a power cycle if the instance DB is configured as retentive (default for TONR in V2.2 - clear this in the instance DB properties if the application needs a cold-start reset).

TONR is described in section 6.3.4 of the S7-1200 System Manual. To clear a TONR, use the RT (reset timer) instruction, which writes a 0 to Q and a 0 to ET, but the instruction is a separate call, not an inline re-evaluation of the timer body, so it is not subject to the same multi-execution issue. The RT instruction is found in the basic instructions palette under "Timer operations > Extended timer operations".

Alternative: Cyclic Time-of-Day Interrupts for Microstep Signal Generation

If the underlying application is generating a microstep waveform at fixed time intervals (the original use case - 360/720 microsteps of a sine period with a 1 s period, plus a random-noise injection for averaging-filter testing), the IEC TON approach is the wrong tool. A PLC scan is on the order of 1-10 ms; a microsecond-step signal needs hardware-timed interrupts. The S7-1200 supports time-of-day interrupts (OB10) and cyclic interrupts (OB30 through OB38) that can be configured down to 1 ms. To go below 1 ms, use the onboard high-speed counter or PTO/PWM generators, or the signal-processor path.

Setup for a 1 ms cyclic interrupt in TIA V13 SP1:

  1. Add a new OB in the project tree under "Program blocks > Add new block" - select type "Cyclic interrupt" and assign it to OB30. The default cycle time is 100 ms.
  2. Open the OB30 properties, go to the "Cyclic interrupt" tab, and set "Cycle time" to 1 ms. The S7-1200 V2.2 firmware supports a 1 ms base on CPU 1214C for OB30; OB31-OB38 default to 100 ms and can be set from 1 ms upward. Phase offset defaults to 0 ms and is rarely needed for this application.
  3. Move the microstep-index increment, the sine lookup, and the noise-generator call into OB30. The OB runs every 1 ms regardless of OB1 scan time.
  4. In OB1, use a simple cross-check: monitor a heartbeat bit in the process image (e.g. "heartbeat_1ms" toggles inside OB30), and verify with the online watch table that it toggles at 500 Hz on the scope or in the trace.

This approach is fundamentally different from a TON-based pulse generator: OB30 is a hardware-scheduled task whose cycle time is enforced by the CPU's interrupt controller, not by the scan time of OB1. The TON pattern in the original code was a workaround for a missing cyclic interrupt setup. For the OB30 setup, refer to the S7-1200 System Manual section 6.6 (entry ID 109751175).

Latency caveat on CPU 1214C firmware V2.2: The cyclic interrupt OB30 has a worst-case latency of roughly 1 ms plus the duration of the highest-priority OB that is currently running. If OB30 contains more than roughly 200 µs of code, the next 1 ms interrupt will be late. Keep OB30 short, and put the bulk of the math (the LUT lookup, the noise generator) into a separate OB that you trigger with a flag if necessary. For deterministic microsecond timing below 1 ms, consider the high-speed counter (HSC) submodules or the signal-processor approach the Siemens support engineer originally recommended.

Step-by-Step Implementation: Edge-Latch with M-Bit in LAD

  1. Declare the timer instance. In the program block, drag a TON instruction from the "Basic instructions > Timer operations" palette. The compiler auto-creates an instance DB named IEC_Timer_0_DB or similar; rename it to t_pulse for clarity. Set PT to T#1s. The default instance DB is non-retentive, which is correct for a free-running pulse.
  2. Declare the mirror bit. In the same PLC tag table, add a tag named b_pulse_state of type BOOL, address M0.0 (CPU 1214C process image output area). Mark it as non-retain.
  3. Build the rung. In Network 1, place the NC contact of b_pulse_state first. Wire the contact output to the TON's IN input. Wire the TON's Q output to a MOVE instruction whose source is the Q output and destination is b_pulse_state. The MOVE executes unconditionally on every scan, which is what you want: the mirror must always be up to date.
  4. Build the counter network. In Network 2, place a CTU counter. Drive its CU input from a positive-edge P-contact on t_pulse.Q. Set PV to 0 (count infinitely) or to the number of microsteps (360 if you are stepping through one full sine period).
  5. Compile and download. In TIA Portal V13 SP1, click "Compile > Hardware and software (rebuild all)". Download to the CPU 1214C. The download resets the instance DB to its initial values, which is expected on a fresh download.
  6. Go online and watch. In the project tree, right-click the instance DB and select "Monitor/Modify". Add b_pulse_state and t_pulse.Q to the watch table. Set the trigger to "permanent" and the cycle time to 500 ms. The watch table should show b_pulse_state toggling every 1 s and the CTU counter CV incrementing once per second.

STL and SCL Equivalents for Engineers Migrating from Other Platforms

Engineers coming from a Delta DVP environment are often more comfortable with STL or SCL than with the LAD/FBD auto-rendering. The following STL snippet is the S7-1200 equivalent of the Delta self-resetting pulse pattern with the mirror-bit fix, written explicitly so the double-call issue cannot occur:

// Network 1: 1 s free-running pulse with mirror-bit fix (STL)
      A     "b_pulse_state"  // mirror bit, NOT the timer's own Q
      NOT
      =     %M0.1            // local IN value
      CALL  "t_pulse", %M0.1  // TON instance, called exactly once
      A     "t_pulse".Q
      =     "b_pulse_state"  // mirror updated unconditionally

// Network 2: rising-edge counter
      A     "t_pulse".Q
      FP    "m_ct_edge"      // edge flag bit
      JCN   _skip
      L     "ct_step".CV
      +     1
      T     "ct_step".CV
_skip: NOP 0

The SCL equivalent of the same pattern is more compact:

// Edge-latch pattern in SCL
IF NOT "b_pulse_state" THEN
    "t_pulse".IN := TRUE;
ELSE
    "t_pulse".IN := FALSE;
END_IF;
"t_pulse"(PT := t#1s);   // multi-instance call, exactly once
"b_pulse_state" := "t_pulse".Q;

IF "t_pulse".Q AND NOT "edge_mem" THEN
    "ct_step".CU := TRUE;
ELSE
    "ct_step".CU := FALSE;
END_IF;
"edge_mem" := "t_pulse".Q;
Note on SCL multi-instance syntax: The line "t_pulse"(PT := t#1s); in SCL is a multi-instance call that re-uses the same instance DB as the previous IN := ... assignment. The SCL compiler in TIA V13 SP1 treats these as a single FB invocation, so the multi-execution pattern does not occur. Do not place a second textual reference to "t_pulse".Q earlier in the same SCL block than the "t_pulse"(PT := t#1s); line, or the compiler will hoist the call above the Q read and the bug will return.

Verification Procedure

  1. Functional test with the watch table. Open a watch table in TIA Portal V13 SP1, add tags t_pulse.Q, b_pulse_state, ct_step.CV, and t_pulse.ET. Force b_pulse_state to TRUE and observe that t_pulse.Q falls after one second, then rises again. Force b_pulse_state to FALSE and observe that t_pulse.Q rises immediately. The behavior is symmetric and free of glitches in the watch table.
  2. Trace recording. Use the TIA Portal trace function (available in V13 SP1 with the trace license on the CPU 1214C) to record t_pulse.Q, b_pulse_state, and the CTU's CU signal at 1 ms sample period. The trace should show Q staying at 1 for a full 1 s interval, b_pulse_state mirroring Q on the next scan, and the CU signal pulsing once per second. The trace buffer is 512 samples on CPU 1214C firmware V2.2, so 1 ms × 512 = 512 ms of total capture, or 4 KB of process data.
  3. Cross-platform parity test. Build the equivalent logic in Delta ISPSoft for a DVP-28SV, run both PLCs with the same program, and compare the watch-table traces. With Workaround 1, both should show a 1 s pulse with 50% duty cycle and a counter increment of 1 per second. The Delta will show a 1-cycle phase difference because the Delta updates Q at the end of the scan; this is normal and not a defect.
  4. Long-run stability test. Run the program for at least 24 hours. The CTU counter should reach 86,400 (24 × 3600) plus or minus 1. A deviation greater than 2 over 24 hours indicates a timing drift in the TON, which on firmware V2.2 is normal (the timer resolution is 1 ms, so the worst-case drift is 1 ms per pulse, or 86.4 s over 24 hours - this is not an issue for most applications, but it is relevant for sine-wave microstepping where the phase must be coherent over many periods).

Troubleshooting Matrix

Symptom Probable Cause Fix
CTU never increments Timer FB executed twice in same scan; Q rises and falls in same OB1 pass Use Workaround 1: mirror Q to an M-bit, use NC of the M-bit on the timer's IN
CTU increments twice per cycle Mirror bit updated twice in the same network, or two separate Q reads drive two separate counters Put the mirror MOVE on a separate network; ensure the counter uses a positive-edge P-contact, not a plain contact
Q stays at 1 forever NC contact of Q is fed by a Q that is wired directly, so IN is always 0 after the first scan, and the timer is held in reset Replace the direct NC contact with the mirror-bit NC contact (M0.0)
Q stays at 0 forever Mirror bit was never set; check that the MOVE instruction is on a network that executes when Q is high Verify the rung compiles without warnings; check the watch table for the MOVE enable bit and ensure the MOVE box is unconditionally energized
Pulse period is twice PT PT was set on the wrong field (e.g. IN vs PT), or the timer is a TOF and you expected TON behavior Re-read the S7-1200 System Manual section 6.3.1; TON requires IN=TRUE for the time to accumulate
Pulse period drifts over time 1 ms TON resolution on firmware V2.2; cumulative drift if a real-time-clock interrupt is not used Switch to OB30 cyclic interrupt for sub-100 µs step generation, or accept the 1 ms drift for non-critical applications
Compiler warning "instance accessed multiple times" The compiler detected the double-reference and is warning the user This warning is informational; the workaround pattern in this article eliminates the warning and the underlying bug
Multi-instance FB fails to compile in V13 Static tag name conflicts with a global tag of the same name Rename the static tag (e.g. tPulse instead of t_pulse)
OB30 is delayed by > 2 ms OB1 is running a slow PID or serial block that blocks the cyclic interrupt Move the slow logic to a higher-priority OB or a cyclic interrupt at a longer period; keep OB30 under 200 µs
TP collapses like TON TP shares the same instance-DB mechanism as TON Apply Workaround 1 to TP; the mirror-bit pattern works identically for TP
TONR counts up across CPU restart TONR is retentive by default In the instance DB properties, clear the "Retain" checkmark for the ET and Q members

Parameter Reference Table

Timer Element Type Direction Description
IN BOOL Input Start input. Timer accumulates ET while IN=TRUE
PT TIME Input Preset time. ET is compared to PT every cycle
Q BOOL Output Set when ET >= PT and IN=TRUE; cleared otherwise
ET TIME Output Elapsed time since IN became TRUE
BI WORD (16-bit BCD) Output Current time value in BCD (legacy S7-200 compatibility)
BCD WORD (16-bit BCD) Output Current time value in BCD (legacy S7-200 compatibility)

The BI and BCD outputs are present for backward compatibility with the legacy S7-200 timer word format. On a CPU 1214C firmware V2.2 they are calculated but rarely used. Avoid reading BI or BCD in the same network that reads Q, as this triples the number of textual references to the same instance and makes the multi-execution pattern more likely.

CPU 1214C Firmware V2.2 Memory Layout for Timer Instance DBs

Instance DB Member Byte Offset Size (Bytes) Retainable?
IN input copy 0 2 No
PT input copy 2 4 No
Q output 6 1 No
ET output (DWORD) 8 4 No
Start time (DINT) 12 4 No
Status byte 16 1 No
BI output (WORD) 18 2 No
BCD output (WORD) 20 2 No

The instance DB is allocated from the work memory of the CPU 1214C; a TON instance takes 22 bytes plus a small header. The CPU 1214C has 50 KB of work memory; on a project with 32 timer instances, the total timer DB overhead is roughly 700 bytes, which is well within the limit. The retainable flag is configurable per-instance on V2.2 (selectable in the instance DB properties > Retain).

Migration Checklist: Delta DVP to S7-1200

  1. Inventory all TON instances in the Delta program. Mark the ones that use the timer's own Q in a feedback path.
  2. For each marked TON, create a mirror bit (M0.0, M0.1, M0.2, ...) in the S7-1200 tag table.
  3. Replace the NC contact of the timer's own Q with the NC contact of the mirror bit.
  4. Add a MOVE from the timer's Q to the mirror bit on a separate network (not the same network that contains the NC contact).
  5. If the application is using TP (pulse timer) with feedback, apply the same pattern.
  6. For time-measurement applications, switch to TONR and clear the retain flag if the time should not persist across CPU restarts.
  7. For waveform generation, switch to OB30 cyclic interrupt and remove the TON entirely.
  8. Run the verification procedure (watch table + trace + long-run test) on the S7-1200 before field deployment.

FAQ

Why does my S7-1200 TON timer not behave like the same code on a Delta DVP?

The Delta DVP ladder engine evaluates each timer reference once per scan and uses the Q value from the previous scan. The S7-1200 LAD/FBD compiler in TIA Portal V13 SP1 evaluates each reference of an IEC timer instance as a separate call to the underlying system FB. When the timer's own Q is wired back to its IN in the same network via an NC contact, the timer is called twice in the same scan and the second call resets the Q bit that the first call just set. The fix is to mirror Q into a memory bit (M0.0 for example) and use the memory bit on the NC contact of IN.

What firmware versions of the S7-1200 are affected by the multi-execution pattern?

Firmware V1.x, V2.x, V3.x, and V4.x all show the same behavior. The behavior is a property of the TIA Portal LAD/FBD compiler, not of the CPU firmware. The mirror-bit fix is also compiler-version-independent and works on TIA Portal V13, V14, V15, V16, and V17.

Can I use the TP (pulse timer) instruction instead of TON to get a one-scan pulse?

No. TP generates a fixed-duration pulse when its IN input sees a rising edge, and it shares the same instance-DB mechanism as TON. The same multi-execution pattern collapses the pulse. Use the mirror-bit pattern with TP, or use a P-contact on Q to drive the next stage.

What is a multi-instance FB and why does it solve the problem?

A multi-instance FB is an FB that contains another FB as a static (VAR) member, so multiple call sites of the outer FB share the same FB type but have separate instance data. On the S7-1200, wrapping the TON inside a user FB and using a single static mirror bit in the wrapper guarantees that the timer is called exactly once per scan and the mirror bit is updated in a defined order. See section 6.5 of the S7-1200 System Manual (Siemens support entry ID 109751175) and the multi-instance application example (entry ID 109751624).

Is the TONR (retentive on-delay timer) a good substitute for one-scan pulse generation?

TONR is better suited to time-accumulation applications and does not suffer from the multi-execution collapse on the S7-1200 because its body is a single branch. For one-scan pulse generation, the mirror-bit pattern is still required. Note that TONR is retentive by default, so its instance DB must be configured as non-retentive in the project properties if you want the time to start from zero on every CPU restart.

Should I use a cyclic interrupt OB30 instead of a TON for periodic signal generation?

Yes, if the period is below 100 ms or if the period must be stable over a long time horizon. The TON on a CPU 1214C has 1 ms resolution and a worst-case 1 ms drift per period, which accumulates to about 86 seconds per day. OB30 with a 1 ms cycle time is hardware-scheduled and has a worst-case latency of about 1 ms + the duration of the highest-priority OB currently running, giving much better long-term stability. For sub-millisecond timing, use the onboard high-speed counter or PTO/PWM hardware.

Back to blog