Program Overview
The six-line STEP 5 STL snippet taken from a working batching plant implements a self-restarting on-delay pulse, an up-counter, a counter-to-flag copy, and a flag-driven counter reset. The construct is the canonical SIMATIC divide-by-N sequencer used to march through recipes, dispense ingredients, advance stage bits, or generate shift-register outputs without a sequencer GRAPH package. This reference decodes each instruction, establishes the difference between German and English timer mnemonics, explains the single-cycle pulse behavior that limits one count per OB1 sweep, walks through the bit-pattern reset at value 8, documents the cold/warm restart retention of C0, and finishes with verified STEP 7 STL and SCL equivalents that run on S7-300, S7-400, ET 200S, and S7-1200/1500 CPUs. Every parameter, format word and edge case below is taken from the official Siemens Programming with STEP 7 manual and the SIMATIC S5 to S7 converter documentation, both available through the Siemens Industry Online Support portal.
Annotated Source Program
The exact S5 STL block excerpt is reproduced below with operand-level commentary. All addresses use the S5-115U/135U/155H model in which timer T127, counter C0, and flag word MW5 share the same OB1 process image.
| Network 1 | Code | Operand | Comment |
| --- | --- | --- | --- |
| 1 | AN | T 127 | Examine T127.Q as NO contact; passes when timer idle |
| 2 | L | S5#250MS| Load 250 ms preset into ACCU1-L |
| 3 | SE | T 127 | Start on-delay timer (German: Setze Einschaltverzögerung)|
| 4 | CU | C0 | Count Up on rising edge of T127.Q |
| 5 | L | C0 | Load counter word |
| 6 | T | MB 5 | Transfer to flag byte 5 (low byte of MW5) |
| 7 | A | M 5.3 | Examine flag bit 5.3 (= value 8) |
| 8 | R | C 0 | Reset counter when M 5.3 = 1 |
The block was lifted from a S5-to-S7 conversion. In STEP 7 STL the same lines translate to either IEC timers/counters (TON, CTU) or to the SIMATIC-native S_ODT/S_CU FBs. The remainder of this article covers both styles.
SE Timer Mnemonic: German vs. English Mnemonics
The SE opcode is the most frequently misread instruction in translated S5 programs because STEP 5 ships two incompatible mnemonics: the German set, which Siemens ships by default on European firmware, and the English/American set, which STEP 7 and the S7 converter expect on PLCs delivered to North America. The official mapping is documented in the Siemens STEP 7 STL/LAD/FBD Programming and Operating Manual and reproduced in the table below.
| STEP 5 German mnemonic | STEP 5 English mnemonic | STEP 7 SIMATIC FB | IEC 61131-3 FB | Behavior |
|---|---|---|---|---|
| SI (Setze Impuls) | SP | S_PULSE | TP | Pulse — output true while input true or while time running |
| SV (Setze Verlängerter Impuls) | SE | S_PEXT | — | |
| SE (Setze Einschaltverzögerung) | SS | S_ODT | TON | On-delay — output true only after time elapses with input still true |
| SS (Speichernde Einschaltverzögerung) | SS (retained) | S_ODTS | TONR | Retentive on-delay |
| SA (Setze Ausschaltverzögerung) | SF | S_OFFDT | TOF | Off-delay |
Within the source listing SE = Setze Einschaltverzögerung, i.e. a non-retentive on-delay equivalent to S_ODT / TON. The discussion thread confirmed this empirically: the digital output of T127 observed on a TRACE is a single-scan TRUE pulse generated each time the timer elapses, exactly matching TON behavior.
SI/SP, SV/SE, SE/SS, SS and SA/SF pairs. A wrong remap gives a true pulse instead of an on-delay and breaks every downstream counter that depends on a single rising edge per cycle.The 250 ms Time Base and the S5T Format Word
The constant S5#250MS is a 16-bit SIMATIC time word laid out as follows. Resolution is fixed at 10 ms for word-oriented S5 timers; the time base is decoded automatically by the CPU from bits 13/14.
| Bit | 15 | 14 | 13 | 12 .. 0 |
|---|---|---|---|---|
| Meaning | 0 (BCD) | Time base 10n s | — | BCD value 0..999 |
Setting bits 14:13 to 00 and value bits to 250 yields the time 25.0 s; setting bits to 01 and value to 025 yields 2.5 s; setting bits to 10 and value to 250 yields 25 s × 10 = 250 s; and setting bits to 11 and value to 002 yields 2 × 100 ms = 200 ms. In practice the value ladder used to configure 250 ms is:
bit 15 = 0 // BCD time
bit 14,13 = 1,0 // 1 s time base, 10 ms resolution
bits 12..0 = 025 H // 25 in BCD
Hex encoding of T127 = 10 00 0001 1111 1001b = W#16#10 50
// OR (depending on BCD): W#16#2050
Working in STEP 7, the equivalent constant is S5T#250MS or T#250ms depending on whether S5TIME or TIME is expected. STEP 7 stores the value in the same 16-bit word but the editor validates the format automatically.
Single-Cycle Pulse Behavior of T127
The combination AN T127 — L S5#250MS — SE T127 is a textbook S5 "generate-one-pulse-on-elapse" pattern. Step-by-step OB1 scan semantics:
-
Scan n, idle state: T127.Q = 0 →
AN T127evaluates TRUE, the SE instruction starts T127 with preset 250 ms. - Scan n + k (after 250 ms wall-clock): T127 internal time ≥ preset → T127.Q latches to 1.
-
Scan n + k + 1:
AN T127now evaluates FALSE (T127.Q = 1), so the SE instruction no longer loads the timer. S5 timers without continuous loading revert to inactive within one additional scan. -
Scan n + k + 2: T127.Q = 0 →
AN T127TRUE again → SE restarts the timer. Cycle repeats.
Net effect: T127.Q is HIGH for exactly one OB1 scan per 250 ms, producing a clean rising edge for CU C0. The period is 250 ms plus one scan time; for OB1 at 10 ms this translates to a counter increment every 260 ms, or roughly 3.85 Hz. The waveform is:
This pulse-on-elapse pattern is the preferred idiom in STEP 5 because S5 has no native one-shot (POS) edge detector. STEP 7 supplies FP (positive edge on RLO) for the same purpose, so the entire 3-line block can be replaced by a single FP against a clock bit if a cyclic OB is available.
CU Counter Instruction and the C0 Word
The CU C0 statement increments the counter only when its RLO transitions from 0 to 1. Because T127.Q is HIGH for exactly one OB1 scan, only one increment occurs per elapse. The C0 word layout is identical to a flag word — 16 bits, BCD-encoded by default in S5, signed integer in STEP 7.
| Bits | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Weight (binary) | — | — | — | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | — | 1 |
Bits 11..0 are the actual count (BCD or INT depending on whether CU is paired with L C0 in BCD or binary mode). Because the source uses L C0 / T MW5, the counter's BCD value is copied to MW5, and the low byte MB5 exposes the binary count. Bits 15..12 always remain at zero for counts below 4096.
Counter-to-MB Transfer Mechanics
The pair L C0 — T MB 5 appears to bypass the word boundary; in fact T MB5 writes the low byte of ACCU1-L into flag byte 5, and leaves ACCU1-L untouched so that ACCU1 still holds C0. The CPU extends the byte write to the word bus automatically; if you wish to mirror MB6 as well, use T MW5 directly.
| MW5 byte map | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|---|
| MB5 (low byte) | M5.7 | M5.6 | M5.5 | M5.4 | M5.3 | M5.2 | M5.1 | M5.0 |
| MB6 (high byte) | M6.7 | M6.6 | M6.5 | M6.4 | M6.3 | M6.2 | M6.1 | M6.0 |
The flag-bit mapping in MB5 follows the standard binary weighting:
M5.0 = 1 (count = 1, 3, 5, 7) <-- 250 ms toggle #1
M5.1 = 2 (count = 2, 3, 6, 7) <-- 500 ms toggle #2
M5.2 = 4 (count = 4, 5, 6, 7) <-- 1 s toggle #3
M5.3 = 8 (count = 8 only) <-- 2 s reset / stage advance
At count 8, MB5 = 0000 1000b; A M 5.3 closes the reset contact and R C 0 clears the counter on the same scan, restoring C0 = 0 and MB5 = 0x00 for the next cycle. The thread author confirmed the original programmer's intent was "to create three 250 ms pulses (M5.0, M5.1, M5.2)". Bit M5.3 was added as the auto-reset detector — a typical S5 trick for substituting a fixed-count sequencer without writing a separate OB.
Bit-Pattern Frequency Divider
The eight-state cascade behaves as a pure divide-by-8 binary ripple counter. Below is the full state table produced as T127 fires eight times:
| CU edge # | C0 / MB5 (binary) | M5.0 | M5.1 | M5.2 | M5.3 | Action |
|---|---|---|---|---|---|---|
| 0 | 0000 0000 | 0 | 0 | 0 | 0 | Initial state — no edges yet |
| 1 | 0000 0001 | 1 | 0 | 0 | 0 | First pulse flag |
| 2 | 0000 0010 | 0 | 1 | 0 | 0 | Second pulse flag |
| 3 | 0000 0011 | 1 | 1 | 0 | 0 | First + second |
| 4 | 0000 0100 | 0 | 0 | 1 | 0 | Third pulse flag |
| 5 | 0000 0101 | 1 | 0 | 1 | 0 | First + third |
| 6 | 0000 0110 | 0 | 1 | 1 | 0 | Second + third |
| 7 | 0000 0111 | 1 | 1 | 1 | 0 | First + second + third |
| 8 | 0000 1000 | 0 | 0 | 0 | 1 | Reset pulse — clears C0 in same scan |
The thermal timing for each pulse is therefore:
- M5.0: 250 ms ON, 1.75 s OFF (50% duty after averaging — actually a binary ripple)
- M5.1: 500 ms period
- M5.2: 1.0 s period
- M5.3: 2.0 s period, 250 ms HIGH — perfect for advancing the next batching stage
Generalizing, the time to count from 0 to N is
T_total = N * T_timer
T_M_b.k = 2^(k+1) * T_timer // period of flag bit M5.k
T_M_b.(n-1) = 2^n * T_timer // reset pulse, where n = reset bit position
In a batching context M5.0, M5.1, M5.2 drive dispense valves for ingredients 1/2/3, and M5.3 resets the cup and increments the batch counter MW6.
Cold/Warm Restart Retention of C0
The thread raised a critical concern: "will Counter not be reset to 0, if CPU is switched off?" The S5 retention model is well defined per the Siemens STEP 7 Programming Manual and the legacy S5 CPU manual set:
- Counter type 1 (CU) retains its word across power-down, restart, and STOP-RUN transitions.
- Counter type 2 resets on power-down but keeps the value across warm restart.
- Counter type 3 resets on every restart.
The counter retention class is configured via the S5 system data block OB100/OB101/OB102 equivalent — in STEP 7 this is the CPU Properties → Retentive Memory → Counter screen. The original S5 program likely left C0 in the default Type 1 (retentive on power-off). Therefore the assumption in the thread — that "Timer T127 will remain ON as long as CPU is not switched off after POWER ON" — is correct only for the timer, not the counter. The counter C0 retains its previously accumulated count, which is why the auto-reset on M5.3 is mandatory: without it C0 would walk over 8 and saturate at 999.
Equivalent STEP 7 STL Using TON and CTU
The canonical S7 conversion replaces the S5 SE timer with an IEC on-delay timer and the CU counter with an IEC up-counter. The MW5 target can be driven from the CV (current value) output of the CTU directly, eliminating the explicit L/T pair.
NETWORK 1 // 250 ms clock pulse
A M 0.0 // optional: clock bit from cyclic OB or memory bit
L S5T#250MS
SD T 1 // German mnemonic SD == SE; English SE on S7
FP _M0.0_Temp // one-shot on T1.Q
= _Pulse_250ms // pulse tag, drives the CTU below
NETWORK 2 // Up-counter + auto-reset at 8
CALL CTU , DB1 // IEC CTU block, instance DB1
CU :=_Pulse_250ms // Count Up on each 250 ms pulse
R :=M5.3 // Reset when MB5 bit 3 (count = 8) closes
PV :=7 // Preset value (7 with R from MB5.bit3 gives /8 div.)
Q :=Q_full // Done bit
CV :=MW5 // Current value transferred automatically to MB5
U M 5.3
R C 0 // belt-and-braces explicit reset (legacy users)
Notes:
- The CTU's
CVoutput is of type INT in STEP 7 V5.5 and S7-1200/1500 (Tia Portal V18+). MW5 therefore reflects the binary count directly, and MB5 = low byte = exact equivalent of the S5 lineT MB 5. - If TIA Portal is the target platform, declare a dedicated Instance DB or use a multi-instance inside a parent FB to keep the IEC counter data persistent.
- Avoid the SIMATIC
S_CUFB for new code; the IECCTUis portable, type-safe, and matches the function-block style used elsewhere on S7-1200/1500. - Set Edge evaluation on the CU input if the upstream pulse is generated by a non-edge flag (e.g.
=instead ofFP), otherwise double-counting will occur.
Equivalent SCL / Structured Text
The same logic in SCL — currently the preferred entry for TIA Portal — is shown below. It removes the need for the FP helper and exploits the IEC CTU instance directly.
FUNCTION_BLOCK FB_BatchSequence
VAR
tPulse : TON; // IEC on-delay
ctUp : CTU; // IEC up-counter
tTick250 : BOOL; // public pulse tag
END_VAR
VAR CONSTANT
CYCLE_MS : TIME := T#250ms;
END_VAR
BEGIN
// 250 ms one-shot
tPulse(IN := NOT tPulse.Q, PT := CYCLE_MS);
tTick250 := tPulse.Q;
// Counter with auto-reset at 8
ctUp(CU := tTick250 AND tPulse.Q, // rising edge only
R := ("MB".5).3 OR ctUp.CV = 8,
PV := 7);
// Mirror CV into flag word for legacy devices
"MW5" := INT_TO_WORD(ctUp.CV);
// Batching outputs (M5.0..M5.2 are pulse flags, M5.3 advances stage)
Valve1 := ("MB".5).0;
Valve2 := ("MB".5).1;
Valve3 := ("MB".5).2;
StageAdv := ("MB".5).3;
END_FUNCTION_BLOCK
The SCL version makes the reset condition explicit (ctUp.CV = 8) rather than relying on a flag-bit read; both implementations run identically, but the explicit CV comparison is faster to scan in code review and immune to unintended writes to M5.3 from elsewhere in the program.
Edge Cases and Common Pitfalls
1. Scan-Time Drift
The S5 single-cycle pulse generator is a function of OB1 scan time. If a longer cyclic interrupt OB (OB35, OB36, …) executes the same network, the count will double. Always execute this block in OB1 only, or migrate to a hardware-timed OB35 tick.
2. Wrong Timer Mnemonic
If the locale is flipped (German ↔ English), SE becomes SV / SP. The result is a continuously-held output, not a one-cycle pulse. C0 increments every OB1 scan and saturates within tens of milliseconds.
3. Counter Retention Loss During Conversion
S5-115U defaults to Retentive = ON for counters and timers in the system data words 0..127. STEP 7 turns this off for CTU/CTD by default. Open HW Config → CPU Properties → Retentive Memory and tick the Counter byte addresses that were retentive in the S5 project. Without this, the batching recipe loses its current step on every power failure.
4. BCD vs. Binary Word
S5 CU C0 stores BCD counts with four-decade range; the IEC CTU stores INT. After migration MW5 can be read directly in INT but not in BCD. Use WORD_TO_INT only if the source word is suspected to be BCD; otherwise the binary reading is correct.
5. Flag-Byte Overlap with Other FB Data
Flag bytes MB0..MB7 are the default scratch area for S5 system software and STEP 7 system blocks (e.g. OB1 step counter, error bits). If another FB writes to M5.3, the counter reset fires prematurely and the divider only counts to 7. Move the workspace to MB20..MB40 or into an instance DB.
6. Two Counters Resetting Each Other
If a different counter C1 sets a bit that is then read by A M 5.3, race conditions may clear C0 before the next OB1 cycle and trap the count at zero. Use a read-only instance data block instead of flag-bit comparison.
7. Cycle Skips in Online Force
Using the S7 debug tools "Force" / "Modify" can hold M5.x in an arbitrary state, breaking the divider. Always release forces after commissioning and watchdog-test the recipe.
Verification and Commissioning Procedure
- Pre-energize: Open the STEP 7 hardware configuration, confirm Retentive Memory → Counter bit for C0 (address 0) is set, save and download to the CPU.
-
Energize with T127 forced TRUE: In OB1 place a
SETthen= T127(force reload) and verify with an online watch table thatT127.Qpulses HIGH once every 250 ms ± scan time. Use STATUS VAR to capture a TRC trace at 100 ms sample rate. -
Counter cycle test: Insert a breakpoint on
R C0and confirm the counter word walks 1, 2, 3, 4, 5, 6, 7, 8, then resets to 0. The MB5 bits should follow the state table above exactly. - Power-loss test: Toggle CPU from RUN to STOP, remove power for 30 s, restore, switch back to RUN. C0 should retain its last value, but if the bit-flag reset already fired it will be 0. If it is not 0, confirm that M5.3 was correctly latched at the moment of power-down (a TRC trace during the test is recommended).
-
Long-run stability: Run the recipe for 24 h and verify that
C0cycles predictably. Calculateexpected_counts = 24*60*60 / (8 * 0.25) = 4320; the downstream batch counter should match within ±0.5 % once drift is accounted for. - Replace flag bytes: Once the recipe proves stable, move the workspace from MB5 to a typed instance DB to remove risk of cross-talk from other FCs.
Reference Parameter Table
| Operand | Symbol | Type | Default value / range | Notes |
|---|---|---|---|---|
| T127 | TimerOneShot | TIMER | 0 s..3 h 16 m, 250 ms target | S5 SE / S7 S_ODT — non-retentive |
| C0 | StageCtr | COUNTER | 0..999 (S5 BCD), 0..32 767 (S7 INT) | Default retentive in S5-115U; configure retentive in STEP 7 |
| MB5 | BitMirror | BYTE | 0x00..0xFF | Low byte of MW5; bit-pattern driven by C0 |
| M5.0 | Valve1Pulse | BOOL | 250 ms period | Dispense actuator 1 |
| M5.1 | Valve2Pulse | BOOL | 500 ms period | Dispense actuator 2 |
| M5.2 | Valve3Pulse | BOOL | 1.0 s period | Dispense actuator 3 |
| M5.3 | StageAdvance | BOOL | 2.0 s period, 250 ms HIGH | Resets C0, advances downstream counter MW6 |
Troubleshooting Matrix
| Symptom | Likely root cause | Verification step | Fix |
|---|---|---|---|
| Counter increments every scan, not every 250 ms | SE/SS mnemonic mismatch in STL source | Toggle locale in STEP 7 editor and rebuild | Convert SE → S_ODT / SS / TON |
| Counter resets immediately to 0 after every increment | Another block writes M5.3 = 1 | Force M5.3 = 0 from watch table | Move divider logic to instance DB |
| Counter never resets, saturates at 999 | Bit M5.3 never reaches 1 — wrong transfer target | Watch MB5 online; expect 0x08 at count 8 | Use T MW5 not T MB5 if counter is INT |
| Counter resets on every CPU restart | Retentive bit not configured | HW Config → CPU → Retentive → Counter | Tick C0 / CTU instance byte |
| Flag bits 5.4..5.7 also toggle | Counter is BCD, T MW5 mirrors decade 1,2 | Set decimal display and confirm | Use INT counter and CTU CV output |
| Pulse period doubles after OB35 added | Same network runs in two OBs | Cross-reference and remove duplicates | Limit execution to OB1 |
FAQ
What does the S5 opcode SE actually do?
SE is the German STEP 5 mnemonic for an on-delay timer (Setze Einschaltverzögerung). It is equivalent to S_ODT in STEP 7 STL and to the IEC TON block. The English STEP 5 mnemonic for the same instruction is SS; the English STEP 5 SE means "Extended Pulse" (Setze Verlängerter Impuls) and behaves like a TP. Confirm the locale before reading the source.
Why does T127 only generate a single-cycle pulse even though it is set to 250 ms?
The combination AN T127 — L S5T#250MS — SE T127 loads the timer only while T127.Q = 0. As soon as the 250 ms elapse and T127.Q latches to 1, the AN T127 contact opens, the SE instruction stops driving the timer, and T127.Q reverts to 0 on the next scan. The pattern therefore produces one 1-cycle HIGH every 250 ms and nothing else.
Is the counter C0 retained across a power-off / power-on cycle?
By default, S5-115U CU counters are retentive; the value is held in the S5 system data area and survives power-down. In STEP 7 the equivalent IEC CTU is non-retentive unless the byte address is enabled in HW Config → CPU Properties → Retentive Memory → Counter. Without this setting, the batch count is lost every restart and the sequencing drifts.
How does the line T MB 5 transfer a 16-bit counter to a byte?
The CPU always operates on a 16-bit accumulator, so L C0 loads the full word into ACCU1-L. T MB 5 writes ACCU1-L-L (the low byte) into flag byte 5; ACCU1 is unaffected and the high byte is also written to MB6. The same line in STEP 7 is most cleanly replaced by driving MW5 := CTU.CV directly, which is type-safe and avoids the implicit byte aliasing.
What is the cleanest STEP 7 replacement for the S5 SE timer + CU counter block?
Use an IEC TON with PT = T#250 ms, then a CTU with PV = 7 and R bound to a flag bit that fires when CV = 8. Declare a single Instance DB for both blocks, and route the CTU's CV output to MW5. This eliminates the manual L/T pair and the legacy FP helper, and the entire divider becomes single-scan, non-blocking, and portable to S7-1200/1500.