Overview
The Siemens S7-1200 programmable logic controller does not expose a discrete "Initialization flag" block comparable to the LOGO! logic relay toolbox, where a dedicated first-cycle marker sits in the constant/connector library. First-cycle detection on S7-1200 must be constructed from one of three native mechanisms: a dedicated startup Organization Block (OB100), the System Memory Byte (SMB) "First cycle" bit, or a user-defined edge-latched pattern that is portable across controller families.
This reference documents each approach with parameter-level detail, the TIA Portal configuration sequence, and a working three-state fan sequencer that demonstrates the practical difference between one-shot startup logic and a continuous first-cycle flag. The methods are valid for the entire S7-1200 CPU range (CPU 1211C / 1212C / 1214C / 1215C / 1217C) running firmware V4.2 or later, with engineering in TIA Portal V16 SP1 through V18.
Prerequisites
| Component | Requirement |
|---|---|
| Engineering software | TIA Portal V16 SP1 or later (V17 / V18 supported) |
| PLC family | Siemens S7-1200 (DC/DC/DC or AC/DC/RLY variants) |
| CPU firmware | V4.2 minimum; V4.4 / V4.5 recommended for current field deployments |
| STEP 7 license | STEP 7 Basic V16+ (bundled with TIA Portal) |
| Required knowledge | OB1 program cycle, tag tables, FB/FC structure, basic FBD/ST/LAD |
Authoritative reference: S7-1200 Programmable Controller System Manual (Siemens Support).
Method Selection Matrix
| Criterion | OB100 | SMB First Cycle Bit | Latched Edge Pattern |
|---|---|---|---|
| Trigger frequency | Every STOP → RUN | Every STOP → RUN | First ever RUN (retentive) or every STOP → RUN (non-retentive) |
| Code location | OB100 only | Any OB / FB / FC | Any OB / FB / FC |
| Cycle-time impact | One startup pass | One OB1 scan window | One OB1 scan window |
| Portability | S7-1200 / S7-1500 | S7-1200 / S7-1500 | All Siemens / AB platforms |
| Configuration overhead | Add OB100 block | Enable SMB in CPU properties | None beyond DB / M tag |
| Recommended use | Hard init, force outputs low | Inline first-scan logic in OB1 | Multi-platform code, RETAIN gating |
Method 1 — OB100 Startup Organization Block
OB100 is the S7-1200 startup Organization Block. It executes exactly once on every STOP → RUN transition, before OB1 begins cycling. This makes it the cleanest location for one-time initialization of variables, force-resetting of sequencer counters, or pre-loading of shift registers. Because OB100 runs before OB1, any tag assigned there is guaranteed to be at its initial value when the first OB1 scan begins.
Execution Sequence on STOP → RUN
- CPU firmware clears all non-retentive memory (M, DB non-retain, outputs).
- Firmware restores retentive memory (DB-retain, M-retain) from backed-up storage.
- Firmware calls OB100 once.
- OB100 completion triggers OB1 cyclic execution; OB1 continues until next STOP or power loss.
If OB100 is missing from the project, the CPU performs default startup behavior without executing user initialization code. Adding OB100 does not change the cold-restart sequence — it inserts a one-shot execution slot the user can program.
Creating OB100 in TIA Portal
- Open the S7-1200 device in the project tree.
- Expand “Program blocks”.
- Double-click “Add new block”.
- Select “Organization block” from the type list.
- Choose OB number 100 from the dropdown. TIA Portal auto-fills the symbolic name “Startup”.
- Confirm the programming language (LAD / FBD / ST) and click OK. The OB100 editor opens.
Initialization Code Pattern
Place initialization logic directly in OB100. Example using Structured Text:
// OB100 — Startup (executed once on STOP → RUN)
"DB_Sequencer".iState := 0; // Reset three-state sequencer
"DB_Sequencer".bFan1 := FALSE; // Force FAN1 output off
"DB_Sequencer".bFan2 := FALSE; // Force FAN2 output off
"DB_Sequencer".iImpulseCount := 0; // Clear impulse counter
"DB_Sequencer".bButtonPrev := FALSE;
Equivalent LAD implementation places a Move block on the left power rail moving the constants 0 and FALSE into the corresponding tags. No enable condition is required — the entire OB100 body runs exactly once.
OB100 Start Information
OB100 exposes a temporary local tag interface populated by the firmware with start information. In TIA Portal the interface can be inspected via “Properties → Interfaces”. The relevant BOOL inputs are:
| Temp Tag | Type | Semantics |
|---|---|---|
| Initial_Call | BOOL | TRUE if this OB100 invocation is the first OB called after startup |
| Remanence_State | BOOL | State of retentive memory: FALSE = cold restart (retain cleared), TRUE = warm restart (retain restored) |
Branching on Remanence_State allows different initialization paths for cold restart (full reset) versus warm restart (preserve process state and only re-initialize transient flags). Most field deployments use the unconditional initialization pattern above; the start info is reserved for applications where preserving a sequence position across a brief power dip is critical.
Limitations of OB100
- OB100 executes only on STOP → RUN. A subsequent STOP → RUN via the mode switch re-triggers initialization; a CPU power cycle behaves identically.
- If OB100 contains a programming error that drives the CPU to STOP, the diagnostic buffer records an OB100 startup error and OB1 does not execute. The system fault LED activates.
- Execution time of OB100 counts against the configured maximum cycle time monitoring. Keep initialization code small (sub-millisecond).
- OB100 cannot be called manually from OB1 — it is firmware-invoked only.
Method 2 — System Memory Byte First Cycle Bit
The S7-1200 System Memory Byte provides standardized status and clock bits the firmware updates every OB1 scan. Bit 0 of the enabled System Memory Byte is the “First cycle” flag: set TRUE for the first execution of OB1 after a STOP → RUN transition and cleared FALSE on all subsequent OB1 cycles until the next STOP → RUN.
System Memory Byte Bit Assignments
Per the S7-1200 System Manual, when a System Memory Byte is enabled the firmware assigns the following semantics to the eight bits:
| Bit | Semantics | Period / Behavior |
|---|---|---|
| Bit 0 | First cycle | TRUE for first OB1 execution after STOP → RUN |
| Bit 1 | Always TRUE | Constant 1 |
| Bit 2 | Always FALSE | Constant 0 |
| Bit 3 | Clock bit 10 Hz | 50 ms high / 50 ms low |
| Bit 4 | Clock bit 5 Hz | 100 ms high / 100 ms low |
| Bit 5 | Clock bit 2.5 Hz | 200 ms high / 200 ms low |
| Bit 6 | Clock bit 2 Hz | 250 ms high / 250 ms low |
| Bit 7 | Clock bit 1 Hz | 500 ms high / 500 ms low |
Enabling the System Memory Byte
- In the project tree, select the S7-1200 CPU device (not a program block).
- Open “Properties” → “System and clock memory”.
- Check “Enable system memory byte”.
- Set the address (default %MB0). This address must not collide with any tag already in use elsewhere in the program.
- Optionally enable “Enable clock memory byte” and set its address (default %MB1).
- Click “OK” and download the hardware configuration to the CPU.
Using the First Cycle Bit
Once enabled, the first-cycle bit is addressable as %M0.0 (assuming the default address %MB0). Use it in OB1 to perform first-scan logic that must execute within the main cyclic program:
// OB1, Network 1 — First-cycle initialization
IF "%M0.0" THEN
"DB_Sequencer".iState := 0;
"DB_Sequencer".bFan1 := FALSE;
"DB_Sequencer".bFan2 := FALSE;
"DB_Sequencer".bFirstScanDone := TRUE;
END_IF;
The advantage over OB100 is that the same logic is accessible from any FB/FC without requiring that block to be called from OB100. The disadvantage is that the first-scan window is exactly one OB1 cycle, so very long cycle times can cause races if the consuming logic runs in a slower OB (e.g., OB35 cyclic interrupt).
Timing Diagram of First-Cycle Pulse
STOP RUN
| |
v v
+-----------+-----------------> Time
| |
| OB100 | OB1 #1 OB1 #2 OB1 #3 ...
| runs |
| v v v
%M0.0 ___________
| |___________________________
| TRUE | FALSE FALSE FALSE
+----------+--------+--------+--------+
^ First cycle pulse
Method 3 — Latched First-Cycle Edge Pattern
A platform-portable alternative is to construct the first-cycle flag manually. The pattern uses edge-detection latching identical in S7-1200, S7-1500, S7-300/400, and Allen-Bradley CompactLogix:
// OB1, Network 1 — Manual first-cycle latch (retentive variant)
IF NOT "DB_Retain".bInitialized THEN
"DB_Sequencer".iState := 0;
"DB_Sequencer".bFan1 := FALSE;
"DB_Sequencer".bFan2 := FALSE;
"DB_Retain".bInitialized := TRUE;
END_IF;
Where DB_Retain.bInitialized is a BOOL declared as RETAIN (retentive). After the first execution, the latch stays TRUE across all subsequent OB1 cycles. On STOP → RUN, the latch is preserved (because it is retentive) — meaning this pattern only initializes on the very first CPU startup or after a memory reset (MRES) that clears retentive data. This behavior differs from Methods 1 and 2, which re-initialize on every STOP → RUN.
For non-retentive latching where STOP → RUN should re-initialize, declare the latch in M-memory or a non-retentive DB:
// Non-retentive variant — re-initializes on every STOP → RUN
IF NOT "M_Flags".bInitialized THEN
"DB_Sequencer".iState := 0;
"DB_Sequencer".bFan1 := FALSE;
"M_Flags".bInitialized := TRUE;
END_IF;
Edge-Detection Variants with R_TRIG / F_TRIG
For applications where the first-cycle signal must trigger multiple FBs in parallel, use an R_TRIG (rising-edge detection) on a one-shot pulse derived from SMB bit 0:
// Generate a single rising-edge pulse on every STOP → RUN
"inst_R_TRIG_DB".CLK := "%M0.0";
"DB_Edges".bFirstScanRising := "inst_R_TRIG_DB".Q;
// Then use "DB_Edges".bFirstScanRising in any FB/FC as a clean pulse
Implementation: Three-State Fan Sequencer
The reference application is a fan sequencer driven by a single push button:
- First impulse: FAN1 ON
- Second impulse: FAN2 ON (FAN1 retained or released per process spec)
- Third impulse: Both OFF, sequence resets
Two implementations follow — a counter/modulo pattern and a shift-register pattern — each initialized on first cycle via the SMB method.
Data Block Definition (DB_Sequencer)
| Tag | Type | Initial Value | Retain |
|---|---|---|---|
| iImpulseCount | INT | 0 | No |
| iState | INT | 0 | No |
| bFan1 | BOOL | FALSE | No |
| bFan2 | BOOL | FALSE | No |
| bButtonPrev | BOOL | FALSE | No |
| tonDebounce | TON_TIME | t#50ms | No |
| bSR_Out0 | BOOL | FALSE | No |
| bSR_Out1 | BOOL | FALSE | No |
| bSR_Out2 | BOOL | FALSE | No |
Sequencer Logic — Counter Variant (Structured Text)
// Network 1 — Button debounce (rising edge with 50 ms filter)
"DB_Sequencer".tonDebounce(IN := %I0.0, PT := T#50ms);
IF "DB_Sequencer".tonDebounce.Q AND NOT "DB_Sequencer".bButtonPrev THEN
"DB_Sequencer".bButtonPrev := TRUE;
"DB_Sequencer".iImpulseCount := ("DB_Sequencer".iImpulseCount + 1) MOD 3;
END_IF;
IF NOT "DB_Sequencer".tonDebounce.Q THEN
"DB_Sequencer".bButtonPrev := FALSE;
END_IF;
// Network 2 — State decode from counter
CASE "DB_Sequencer".iImpulseCount OF
0:
"DB_Sequencer".bFan1 := FALSE;
"DB_Sequencer".bFan2 := FALSE;
1:
"DB_Sequencer".bFan1 := TRUE;
"DB_Sequencer".bFan2 := FALSE;
2:
"DB_Sequencer".bFan1 := TRUE;
"DB_Sequencer".bFan2 := TRUE;
END_CASE;
// Network 3 — Output to physical terminals
%Q0.0 := "DB_Sequencer".bFan1;
%Q0.1 := "DB_Sequencer".bFan2;
Counter Variant State Table
| Impulse | iImpulseCount | FAN1 | FAN2 |
|---|---|---|---|
| Initial | 0 | OFF | OFF |
| 1st | 1 | ON | OFF |
| 2nd | 2 | ON | ON |
| 3rd | 0 (wrap) | OFF | OFF |
| 4th | 1 | ON | OFF |
Sequencer Logic — Shift Register Variant (Structured Text)
// Shift-register based 3-state cycle
IF %I0.0 AND NOT "DB_Sequencer".bButtonPrev THEN
"DB_Sequencer".bSR_Out2 := "DB_Sequencer".bSR_Out1;
"DB_Sequencer".bSR_Out1 := "DB_Sequencer".bSR_Out0;
"DB_Sequencer".bSR_Out0 := NOT "DB_Sequencer".bSR_Out0;
END_IF;
"DB_Sequencer".bButtonPrev := %I0.0;
"DB_Sequencer".bFan1 := "DB_Sequencer".bSR_Out0 OR "DB_Sequencer".bSR_Out1;
"DB_Sequencer".bFan2 := "DB_Sequencer".bSR_Out1;
Shift Register Variant State Table
| Impulse | SR_Out0 | SR_Out1 | SR_Out2 | FAN1 | FAN2 |
|---|---|---|---|---|---|
| Initial | 0 | 0 | 0 | OFF | OFF |
| 1st | 1 | 0 | 0 | ON | OFF |
| 2nd | 0 | 1 | 0 | ON | ON |
| 3rd | 1 | 0 | 1 | ON | OFF |
First-Cycle Initialization for the Sequencer
Add this network to OB1 (Method 2) to force the sequencer into a known state on every STOP → RUN:
// First-cycle reset for sequencer (OB1, Network 0)
IF "%M0.0" THEN
"DB_Sequencer".iImpulseCount := 0;
"DB_Sequencer".iState := 0;
"DB_Sequencer".bFan1 := FALSE;
"DB_Sequencer".bFan2 := FALSE;
"DB_Sequencer".bSR_Out0 := FALSE;
"DB_Sequencer".bSR_Out1 := FALSE;
"DB_Sequencer".bSR_Out2 := FALSE;
END_IF;
Step-by-Step TIA Portal Configuration
- Open or create a TIA Portal project targeting your S7-1200 CPU.
- Add a new device: “Controllers → SIMATIC S7-1200 → CPU → [your model]”.
- Configure the CPU IP address and PROFINET device name if applicable.
- Open the CPU device view and navigate to “Properties → System and clock memory”.
- Enable “System memory byte” and set address %MB0 (default).
- In the project tree, add a new Data Block “DB_Sequencer” with the tags listed above. Set all sequencer tags as non-retentive.
- Open OB1 and write the three networks shown in the sequencer logic section above, preceded by the first-cycle reset network.
- Save and compile the project (right-click the CPU → “Compile → All”).
- Download the hardware and software to the CPU. The CPU will STOP then RUN automatically.
- Open an online watch table on DB_Sequencer and %MB0 to observe the first-cycle pulse.
Verification and Commissioning
After download, verify each method independently before integrating the sequencer:
- Method 1 verification: Place a breakpoint or single-step in OB100. Trigger a STOP → RUN transition via the mode switch or TIA Portal “STOP → RUN” button. Confirm OB100 executes exactly once and the monitored tags reach their initial values.
- Method 2 verification: In an online watch table, force %MB0 to display. Toggle the CPU from RUN → STOP → RUN. Observe %M0.0 rising to TRUE for exactly one OB1 scan, then falling to FALSE on the next scan.
- Method 3 verification: With “DB_Retain”.bInitialized declared RETAIN, perform a STOP → RUN. Confirm initialization does NOT repeat. To re-test, perform a memory reset (MRES) to clear retentive data.
- Sequencer verification: Manually pulse %I0.0 three times. Confirm the FAN1 / FAN2 outputs follow the expected state table. Repeat from cold STOP → RUN to confirm first-cycle reset behavior.
- Watch table sample: Add tags %M0.0, DB_Sequencer.iImpulseCount, DB_Sequencer.bFan1, DB_Sequencer.bFan2, and %I0.0 to a single watch table for live monitoring during commissioning.
Watch Table Layout for Live Commissioning
| Address | Symbolic Name | Display Format | Modify Value |
|---|---|---|---|
| %M0.0 | SMB.FirstCycle | BOOL | monitor only |
| %I0.0 | PB_Impulse | BOOL | force 0 / 1 for test |
| %Q0.0 | FAN1_Output | BOOL | monitor only |
| %Q0.1 | FAN2_Output | BOOL | monitor only |
| DB_Sequencer.iImpulseCount | ImpulseCount | DEC | 0 / 1 / 2 for state test |
| DB_Sequencer.bFan1 | bFan1 | BOOL | monitor only |
| DB_Sequencer.bFan2 | bFan2 | BOOL | monitor only |
Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
| %M0.0 never reads TRUE | System Memory Byte not enabled or address collision | CPU Properties → System and clock memory → Enable; verify %MB0 is unused elsewhere in the program |
| OB100 does not execute | OB100 missing from project, or CPU already in RUN when block was added | Add OB100, save, download; cycle power or STOP → RUN to trigger |
| First-scan logic runs every cycle | Latch variable not RETAIN and re-checks initial state incorrectly each cycle | Use proper edge detection (R_TRIG / F_TRIG) or trust SMB bit directly |
| Sequencer counter overflows beyond 3 | Counter not modulo-3 wrapped | Apply MOD 3 operator after increment, or use case statement on bounded counter |
| FAN outputs stuck ON after STOP → RUN | Outputs are retentive or first-cycle reset missing | Verify output tags are non-retentive; add first-cycle reset network at top of OB1 |
| Button presses register multiple times | Push button debounce insufficient or contact bounce | Increase TON_TIME to 100 ms or 200 ms; verify mechanical switch quality |
| Shift register sequence differs from counter sequence | Different state-machine interpretation of the spec | Confirm with process engineer whether FAN1 turns off when FAN2 turns on |
| OB100 initialization runs on every scan | OB100 incorrectly called from OB1 or FC | OB100 must not be called manually; remove any CALL OB100 in the program |
| Diagnostic buffer shows “OB100 startup error” | Programming fault inside OB100 | Open online → Diagnostics → Buffer; correct the fault and re-download |
Safety and Process Considerations
First-cycle logic frequently sets outputs to a safe state. For fan control, ensure:
- Outputs driving contactors pass through hardwired E-stop circuitry rated to interrupt motor locked-rotor current.
- The first-cycle reset does not energize fans unless the process explicitly requires it; default to OFF.
- If using RETAIN to preserve sequence position across power dips, validate that the mechanical state of the fans matches the retained counter before relying on it.
- For safety-rated applications (SIL 1 / SIL 2 per IEC 61508), first-cycle logic must not be the sole means of de-energizing the load. Use a safety relay or F-CPU safety function.
Cross-Platform Notes
The three methods translate as follows on related Siemens platforms:
| Platform | OB100 Equivalent | SMB Equivalent | Notes |
|---|---|---|---|
| S7-1200 | OB100 (Startup) | System Memory Byte %MBx bit 0 | Single startup OB; SMB optional |
| S7-1500 | OB100 / OB101 / OB102 | System Memory Byte %MBx bit 0 | Multiple startup OBs by restart type |
| S7-300 / S7-400 | OB100 / OB101 / OB102 | Not available; use OB100 + flag | Same pattern as S7-1500 |
| ET 200SP CPU | OB100 (Startup) | System Memory Byte supported | Identical configuration flow |
FAQ
What is the simplest way to detect the first scan in S7-1200?
Enable the System Memory Byte in CPU Properties (default %MB0) and read %M0.0 inside OB1. The bit is TRUE for exactly one OB1 execution after every STOP → RUN transition. See the S7-1200 System Manual for bit assignments.
Does OB100 exist on S7-1200, or only on S7-1500?
OB100 exists on the entire S7-1200 family from firmware V2.0 onward. Create the block via “Add new block → Organization block → Startup (OB100)”. On S7-1500 additional startup OBs (OB101 / OB102) are available for specific restart types; S7-1200 supports only OB100.
Why does my System Memory Byte not update after download?
The System Memory Byte configuration is part of the CPU device configuration, not the program blocks. After changing the setting, perform a full hardware download (not just program download) and verify the configuration in the online CPU properties under “System and clock memory”. Address collisions with existing M-memory tags will also silence the bits.
Can I use the same first-cycle technique on LOGO! and S7-1200?
LOGO! provides a discrete “Initialization flag” block in the toolbox. S7-1200 does not — you must implement the equivalent using OB100, the System Memory Byte first-cycle bit, or a latched edge pattern as documented above. The behavior is equivalent: a one-shot TRUE pulse on STOP → RUN.
What is the difference between the System Memory Byte and the Clock Memory Byte?
The System Memory Byte contains diagnostic and first-cycle bits (bit 0 first-cycle, bits 1-2 constant, bits 3-7 frequency clocks). The Clock Memory Byte contains only frequency bits (10 Hz / 5 Hz / 2.5 Hz / 2 Hz / 1 Hz). Both are independent configuration options on the same CPU properties page. Use System Memory Byte for first-cycle logic; use Clock Memory Byte for periodic blinking or heartbeat tasks.
How do I re-trigger initialization after a STOP → RUN without cycling power?
Use the TIA Portal online “STOP” then “RUN” button sequence, or toggle the CPU mode switch on the physical device. Either path triggers OB100 and resets SMB bit 0 to TRUE for one OB1 scan. The retentive-latch pattern (Method 3) does not re-initialize under STOP → RUN — use MRES to clear retentive memory if needed.