Resetting Bit Logic in Siemens TIA Portal: Timer Sequence Control

David Krause16 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

Implementing a sequenced on/off light pattern (5 s ON, 2 s OFF, repeating) on a Siemens SIMATIC S7-1200 or S7-1500 controller is a canonical training exercise that surfaces a recurring TIA Portal mistake: wiring a normally-open (NO) bit contact directly to a timer input without a latching element. As long as the start pushbutton is held, the timer re-triggers on every scan, the output never settles, and the lamp either chatters or latches solid. The correct fix is to decouple the start event from the running state by using either an edge detector, a set/reset flip-flop, or a self-driving state machine.

This reference covers three industrial patterns that work on every S7-1200 and S7-1500 firmware combination from STEP 7 V11 (TIA Portal) through TIA Portal V18: the reset-dominant RS flip-flop, the negative-edge start flag, and the lamp-bit driven sequence. Each pattern is shown in Ladder (LAD) and Structured Control Language (SCL), with commissioning checks, parameter tables, and a fault matrix for the most common field issues.

Prerequisites

  • Controller: SIMATIC S7-1200 (e.g. 6ES7214-1AG40-0XB0, CPU 1214C DC/DC/DC, firmware V4.4) or S7-1500 (e.g. 6ES7511-1AK02-0AB0, CPU 1511-1 PN, firmware V2.9). Both families implement the IEC 61131-3 bit-logic and timer instruction set natively.
  • Engineering station: STEP 7 Basic V11 (TIA Portal) or later. TIA Portal V16 or V17 is recommended for current CPU firmware support.
  • Hardware wiring: one 24 V digital input wired to a normally-open pushbutton (e.g. address %I0.0), one 24 V digital output driving the lamp (e.g. %Q0.0).
  • Symbol table containing: Start (Bool, %I0.0), Stop (Bool, %I0.1), Light (Bool, %Q0.0), Sequence_Active (Bool, %M0.0), T_On (IEC_TIMER, %DB1), T_Off (IEC_TIMER, %DB2).
  • Project compiled cleanly and downloaded to the CPU. CPU in STOP for the first download; subsequent edits may use TIA Portal's "Download in RUN" on S7-1500.
Note: The IEC timer instructions (TP, TON, TOF, TONR) are multi-instance capable. On S7-1200 and S7-1500, allocate them in either a global DB (e.g. DB1, DB2) or as multi-instances inside an FB. Avoid the legacy S5-style timers (SE, SS, SI, SA) — they were retired on S7-1200 firmware V4.0 and never existed on S7-1500.

The Core Problem: Why a Bare NO Contact Will Not Self-Reset

A ladder network that reads literally as "if Start then start T_On, and Light follows NOT T_On.Q" will oscillate the moment the pushbutton closes. TIA Portal scans the network every cycle (typically 1 ms to 10 ms depending on the configured cycle time and CPU family). As long as Start remains TRUE:

  1. Cycle N: T_On.IN is TRUE, Light goes TRUE. The timer begins counting.
  2. Cycle N + K: T_On reaches PT = 5 s, T_On.Q flips FALSE, Light goes FALSE.
  3. Cycle N + K + 1: With Start still TRUE, the network re-evaluates. Light is now FALSE, so the timer input is still TRUE, the timer restarts from zero, and Light returns TRUE on the next scan.

The result is a millisecond-scale flicker rather than a 5 s pulse, and the timer never reaches its preset. This is the exact symptom described in the field as "the light will not stop." The fix is to make the timer's input self-sustaining. There are three production-quality ways to do it.

Solution A: Reset-Dominant RS Flip-Flop (Recommended)

The IEC 61131-3 RS instruction is reset-dominant: if both S and R1 are TRUE simultaneously, the output stays FALSE. Place an RS block whose S input is a one-shot from the pushbutton, and whose R1 input is a user-driven stop condition. The output bit Sequence_Active is then used (not Start) to drive the timer, so the timer cannot restart until the operator explicitly resets the sequence.

LAD — Network 1 (start latch with reset-dominant RS):

      Start(NO)---[P]----+----(S)----+
                              RS
      Stop(NO)-------------+---(R1)----+   -> Sequence_Active

The trailing [P] positive-edge detector makes the latch respond only to the press of the button, not to a stuck-high input. Because RS is reset-dominant, the operator's Stop input always wins — even if Start is held.

To produce a continuous blink, the lamp bit must re-arm the sequence. Wire the timer output into a second timer, and the second timer's positive edge into the same S input:

LAD — Network 2 (5 s ON phase) and Network 3 (2 s OFF gap):

Sequence_Active(NO)---+----[TON  T_On, PT := T#5s]---|
                      |                              |---( )--- Light
                      |                              |
T_On.Q(NO)------------+----[TOF  T_Off, PT := T#2s]---|
                                                     |
T_Off.Q(NO)-------------------------------------------[P]---(S) Sequence_Active

Behavior: when Sequence_Active latches, T_On begins timing, the lamp is on. After 5 s T_On.Q rises; the rising edge starts T_Off and Light goes FALSE. After another 2 s, the positive edge of T_Off.Q re-sets Sequence_Active, the cycle restarts. The RS flip-flop and the Stop input give the operator unconditional control.

The RS block is documented under "Bit logic operations > Flip-flop" in the SIMATIC S7-1200 Programmable Controller System Manual — see the manual index on the Siemens S7-1200 product support page.

Solution B: Negative-Edge Start Flag with Latching

Edge detection is the lightest-weight solution. A negative edge (N) detector on the Start input produces a one-cycle TRUE pulse on the falling edge of the pushbutton — i.e. the moment the operator releases the button. That single pulse sets a flag that the timer network can latch onto without further input from the operator.

LAD — Network 1 (edge-detected start):

Start(NO)----[N]----(S) Sequence_Active

Light(NO)-----------(R) Sequence_Active

Because the R coil references the same Light bit that drives the lamp, the flag clears itself the moment the lamp turns off — which is the natural moment to start the OFF timer. Pair this with a classic Start-Stop-Run seal-in around Sequence_Active if you want the sequence to be resettable from a dedicated stop button rather than from the lamp bit.

The negative-edge detector and the positive-edge detector are documented in the TIA Portal help under "Bit logic operations > Edge detection." See the Siemens S7-1500 product support page for the matching system manual and instruction reference.

Solution C: Drive the Sequence from the Light Bit

The cleanest re-trigger is to use the lamp output bit itself rather than the start pushbutton or the timer output. The lamp bit already encapsulates "the cycle is in the ON half," so a falling edge on the lamp is the natural event to re-arm the OFF timer.

LAD — Single-network implementation:

Light(NC)---------[TON  T_On, PT := T#5s]---|
                                              |---(S) Light  (RS, reset-dominant)
T_On.Q(NO)------[TOF  T_Off, PT := T#2s]---(R1) Light

This pattern needs only two timers and one RS block. The lamp bit is the only feedback variable; both timers are pure derivatives of its state. It is the most compact pattern for a fixed 5 s / 2 s blink and is the one to reach for when the duty cycle is hard-coded into the project and the HMI will not change it at runtime.

IEC Timer Selection (TP, TON, TOF, TONR)

S7-1200 and S7-1500 expose four IEC 61131-3 timer types under "Instructions > Timers > IEC Timers." The differences matter for a self-restarting sequence.

Instruction Behavior Edge behavior Typical use
TP — Pulse timer On a rising edge of IN, sets Q TRUE for exactly PT regardless of IN subsequently toggling. Edge-triggered start, level-insensitive run. Fixed-width pulses, e.g. a 1 s flash on every scan-edge of a counter.
TON — On-delay timer Q follows IN with a delay of PT. Q goes FALSE immediately when IN goes FALSE. Level-sensitive. Debounce, delayed turn-on, sequenced start.
TOF — Off-delay timer Q follows IN, then stays TRUE for PT after IN goes FALSE. Level-sensitive. Run-on, minimum-off-time, lamp cool-down.
TONR — Retentive on-delay Accumulates elapsed time across multiple IN := TRUE cycles. Q goes TRUE once accumulated time ≥ PT. Must be explicitly reset with the RT instruction. Edge-accumulating. Total run-time, duty-cycle counters, totalization.

For a 5 s ON / 2 s OFF blink, the cleanest combination is one TON for the ON phase and one TOF for the OFF phase. Using a TP alone is wrong for this application because the TP ignores subsequent IN changes during its pulse — you cannot self-restart it from the lamp bit within the same PT window.

The IEC timer block exposes IN, PT (preset time), Q (output), and ET (elapsed time). The ET resolution is the configured time base of the timer instance — typically 1 ms on S7-1500 and 1 ms / 10 ms selectable on S7-1200, depending on the device configuration. See the SIMATIC S7-1500 System Manual, section "Timer instructions," on the Siemens S7-1500 product support page.

Ladder (LAD) Implementation

The full sequenced-lamp program in LAD, organized as four networks. Tags assume the symbol table mapping shown in Prerequisites.

Network 1 — Start latch with RS flip-flop:

      Start(NO)---[P]----+----(S)----+
                              RS
      Stop(NO)-------------+---(R1)----+   -> Sequence_Active

Network 2 — 5 s ON timer and lamp coil:

Sequence_Active(NO)---+----[TON  T_On, PT := T#5s]---|
                      |                              |---( )--- Light
                      |                              |
T_On.Q(NO)------------+--------------------------------+ (sets Light via RS in NW3)

Network 3 — 2 s OFF gap and re-trigger:

T_On.Q(NO)------------+----[TOF  T_Off, PT := T#2s]---|
                                                      |
T_Off.Q(NO)-------------------------------------------[P]---(S) Sequence_Active

Network 4 — Operator reset (optional explicit stop):

Reset(NO)----[P]----(R1) Sequence_Active   (RS already handles Stop; Reset is for HMI-driven clear)

Behavior: a single press of Start latches Sequence_Active, which starts T_On and turns the lamp on. After 5 s, T_On.Q rises and starts T_Off; the lamp turns off. After another 2 s, the positive edge on T_Off.Q re-sets Sequence_Active, which re-arms T_On, and the cycle repeats. Stop (or Reset) breaks the loop by clearing the flag — the RS block is reset-dominant, so the operator always wins.

SCL Implementation

SCL is the more maintainable option for sequence logic because it eliminates accidental double-coil conflicts and makes the state transitions explicit. The same program in SCL for an S7-1500 (FB FB_LampSequence):

// FB_LampSequence - block interface
// Start : Bool  (input, %I0.0)
// Stop  : Bool  (input, %I0.1)
// Light : Bool  (output, %Q0.0)
// T_On  : IEC_TIMER (static)
// T_Off : IEC_TIMER (static)

IF Stop THEN
    T_On(IN := FALSE, PT := T#5s);
    T_Off(IN := FALSE, PT := T#2s);
    Light := FALSE;
    RETURN;
END_IF;

IF Start AND NOT Light AND NOT T_Off.Q THEN
    T_On(IN := TRUE, PT := T#5s);
ELSE
    T_On(IN := Light, PT := T#5s);
END_IF;
T_On();   // explicit timer call - required in SCL on S7-1200/1500

IF T_On.Q THEN
    T_Off(IN := NOT Light, PT := T#2s);
END_IF;
T_Off();

Light := NOT T_Off.Q AND (T_On.IN OR T_On.Q);

Three implementation notes specific to S7-1500 / TIA Portal V15+:

  1. The IEC timer instances (T_On, T_Off) must be declared in the FB static section, not in the block-local VAR_TEMP area, or the values are lost on every scan.
  2. Call the timer FB with empty parentheses T_On(); on a line by itself to force the update — this is documented in the TIA Portal help under "Calling IEC timers in SCL." Forgetting this line is the most common reason an SCL-implemented timer appears to do nothing in online view.
  3. For S7-1500 firmware V2.0+ the optimized block access is the default and is preferred for performance; the IEC timer instance DB is automatically generated and managed.

Refer to the S7-1500 SCL programming manual on the Siemens S7-1500 product support page.

State-Machine Implementation

For production machines that need a third state (e.g. ON / OFF / INTERLOCK_WAIT) or that change the duty cycle from the HMI, replace the timer-cascade with a CASE block. This pattern is the one Siemens recommends in the S7-1500 GRAPH manual and in the "Sequential control" chapter of the S7-1200 system manual.

CASE #State OF
    0:  // IDLE
        #Light := FALSE;
        IF #Start THEN
            #Light   := TRUE;
            #T_On(IN := TRUE, PT := #TimeOn);
            #State   := 1;
        END_IF;

    1:  // ON
        IF #T_On.Q THEN
            #Light   := FALSE;
            #T_On(IN := FALSE);
            #T_Off(IN := TRUE, PT := #TimeOff);
            #State   := 2;
        END_IF;

    2:  // OFF
        IF #T_Off.Q THEN
            #T_Off(IN := FALSE);
            #Light  := TRUE;
            #T_On(IN := TRUE, PT := #TimeOn);
            #State  := 1;
        END_IF;
ELSE
    #State := 0;
END_CASE;

IF #Stop OR #Reset THEN
    #T_On(IN := FALSE);
    #T_Off(IN := FALSE);
    #Light := FALSE;
    #State := 0;
END_IF;

Make #TimeOn and #TimeOff inputs to the FB (type TIME) so the HMI can change them at runtime without re-loading the PLC. Verify the FB is called in a cyclic OB (OB1) and that its instance DB is set to "Optimized block access" for S7-1500 firmware V2.0+ unless external code needs to read it by absolute address.

Commissioning and Verification

Use this checklist every time you bring a new S7-1200 or S7-1500 lamp-sequence program online.

  1. Project compile. Right-click the PLC in the project tree and choose "Compile > Software (rebuild all)." Zero errors and zero warnings is the only acceptable state for a release build.
  2. Download to CPU. Use "Online > Download to device." Confirm the CPU is in STOP during the first download unless you are doing a RUN-mode download (S7-1500 only, requires "Download in RUN" enabled in the device configuration).
  3. Watch table. Open "Watch & force tables" and add Start, Stop, Sequence_Active, Light, T_On.IN, T_On.Q, T_On.ET, T_Off.IN, T_Off.Q, T_Off.ET. Modify Start to TRUE for one scan only (use "Modify to 1" with a single trigger, not a sticky force).
  4. Trigger the sequence. Verify Sequence_Active latches TRUE; verify Light rises; verify T_On.ET increments toward 5000 ms.
  5. Verify the 5 s timeout. Confirm Light goes FALSE within one scan of T_On.ET reaching 5000 ms.
  6. Verify the 2 s gap. Confirm T_Off.ET starts incrementing on the same scan Light goes FALSE, and that Light returns TRUE within one scan of T_Off.ET reaching 2000 ms.
  7. Verify the auto-retrigger. Confirm that Sequence_Active stays TRUE for the entire blink — it is reset only by Stop or Reset. If it goes FALSE after the first 5 s, the network is using Light as its own reset path; check Network 3 wiring.
  8. Verify the operator stop. Modify Stop to TRUE for one scan. Confirm Light goes FALSE on the next cycle and stays FALSE, and that T_On / T_Off reset their elapsed times to 0.
  9. Check the scan time. In "Online & diagnostics > Cycle time," confirm OB1 cycle time is < 50 ms. The blink period is dominated by the timer PT, not the scan, but a runaway cycle can mask the timer output.
  10. Power-cycle test. Power the CPU off and back on. Confirm the blink does not restart on its own (the IEC timers and flags are non-retentive by default). If you need the sequence to survive a power cycle, mark the relevant tags as "Retain" in the PLC tag table — but be aware that this also means a faulty start condition will persist across power-cycles.

Common Faults and Troubleshooting Matrix

Symptom Likely cause Diagnostic Fix
Lamp flickers at PLC scan rate (1-10 ms), never reaches 5 s. Timer IN is wired directly to the held pushbutton (NO contact), so the timer restarts every scan. Watch table: T_On.ET never exceeds one OB1 cycle. Latch the start with RS or an edge detector. Use Sequence_Active (not Start) to drive the timer IN.
Lamp turns on once, never comes back on. The reset path of the RS flip-flop is the lamp bit itself, so the latch clears after the first 5 s. Watch Sequence_Active: it should stay TRUE; if it goes FALSE after the first 5 s, the sequence is not self-looping. Add a third network that re-sets Sequence_Active on the positive edge of T_Off.Q, as in Network 3 of the LAD section.
Lamp stays solid on after one press, no blink. Reset-dominant RS is being set every cycle by an un-debounced input or by a sticky Force from a previous commissioning session. "Online & diagnostics > Force table": confirm no permanent forces. Check the digital input filter (default 6.4 ms on S7-1200 SM 1223, configurable 0.1-20 ms on S7-1500 DI 16). Remove the force, increase the input filter if the pushbutton bounces, and confirm only the leading edge of Start sets the flag.
Timer ET counts but Q never rises. PT is set to T#0s, or the timer is being called without parentheses in SCL. Watch T_On.PT; confirm > 0 ms. In SCL, confirm T_On(); is on a line by itself. Set PT to a non-zero value, add the explicit timer call.
Sequence restarts on every power-up. Sequence_Active, T_On, or T_Off are flagged as Retain in the tag table or DB. Right-click each tag in the tag table or DB and check the "Retain" column. Clear the retain attribute for non-essential flags and timers; the desired behavior on power-up is IDLE.
SCL compile error: "Instance of multi-instance cannot be used here." IEC timer declared in VAR_TEMP instead of VAR or VAR_STAT. Inspect the FB interface declaration. Move the timer instance to the static section.
Online value of T_On.ET resets to 0 every cycle. The timer is being re-instantiated each scan, typically because it is declared in a function (FC) instead of a function block (FB), or the timer instance is in a global DB that is being overwritten. Look for the timer's parent block: FC vs FB; check the global DB for any "initial values on download" settings. Move the timer into an FB static section, or into a global DB that is not re-initialized.
Lamp blinks but period is wrong by a fixed offset (e.g. 5.1 s instead of 5 s). OB1 cycle time is contributing to the timer resolution, or the timer time base is coarser than expected. "Online & diagnostics > Cycle time." Confirm OB1 is consistently < 1 ms. Confirm the timer instance time base. Reduce OB1 cycle time or switch to a hardware-based timer. The IEC timer is a software construct whose precision is bounded by the cycle time.
Safety note: The patterns above are for indicator lamps and non-safety outputs only. Any sequence that drives a motor contactor, a brake, or a safety-relevant actuator must be implemented behind a certified safety function (e.g. F-CPU in STEP 7 Safety, PROFIsafe to a safety output module) and validated per ISO 13849-1 PL ≥ d / IEC 62061 SIL 2. The patterns in this document are not part of a safety function.

FAQ

Why does my lamp flicker at scan rate instead of blinking at 5 s?

The timer's IN is wired directly to the held pushbutton. The timer restarts on every OB1 cycle and never reaches its preset. Replace the direct NO contact with an RS flip-flop (set on a one-shot from the button, reset by the timer output) or a negative-edge detector plus a latch flag, and use the latch bit — not the button — to drive the timer.

Should I use RS or SR for the start latch?

Use RS (reset-dominant) whenever the operator must always be able to stop the sequence, including from a fault condition. Use SR (set-dominant) only for non-critical latches where a simultaneous set and reset should latch the output. For a lamp sequence RS is the correct choice.

Can I use the legacy S7-300 timers (SE, SS, SI, SA) on an S7-1200?

No. The S5-style timers were removed from S7-1200 firmware V4.0 (released 2013) and never existed on S7-1500. Use the IEC 61131-3 TP, TON, TOF, and TONR instructions, declared as IEC_TIMER instances in an FB static section or in a global DB.

Why is the timer's elapsed time (ET) counting in 10 ms steps on my S7-1200?

The default time base on the S7-1200 IEC timer is 10 ms in most firmware versions; on S7-1500 it is 1 ms. If the on-screen ET appears to step in 10 ms increments, this is the expected time base, not a fault. The Q output is still accurate to within one OB1 cycle.

How do I let an HMI change the ON and OFF times without editing the program?

Declare TimeOn and TimeOff as TIME inputs on the FB and pass them into the timer block's PT parameter on every call. The HMI writes to the corresponding tags in the FB instance DB. For S7-1500 use a UDT for the operator panel's recipe data so the HMI polls the same names.

Back to blog