# S7-1500 SCL Sequencer — Advanced 10-Step Welding Cell > **Platform:** Siemens S7-1500 | TIA Portal V18+ | SCL (Structured Control Language) > **Block:** `FB_WeldSequencer` | Optimized Access | IEC 61131-3 compliant A production-ready, feature-complete **10-step sequencer** for a MIG/MAG robotic welding cell demonstrating all advanced sequencer patterns: AUTO/INCREMENT modes, PAUSE vs STOP, IEC Stop Categories (CAT0/CAT1/CAT2), Step Skip, Step Disable, Safety-Locked Steps, sensor-based advance, dual-sensor (FWD/BWD) advance, and pure timer advance. --- ## Table of Contents 1. [Feature Overview](#1-feature-overview) 2. [File Structure](#2-file-structure) 3. [I/O Map](#3-io-map) 4. [Sequencer Modes](#4-sequencer-modes) 5. [State Machine](#5-state-machine) 6. [Stop Categories (IEC 60204-1)](#6-stop-categories-iec-60204-1) 7. [Pause vs Stop](#7-pause-vs-stop) 8. [Step-by-Step Breakdown](#8-step-by-step-breakdown) 9. [Step Advance Types](#9-step-advance-types) 10. [Skip / Disable / Safety-Lock](#10-skip--disable--safety-lock) 11. [Fault Codes](#11-fault-codes) 12. [HMI Integration](#12-hmi-integration) 13. [TIA Portal Setup](#13-tia-portal-setup) 14. [Adapting the Code](#14-adapting-the-code) 15. [Safety Notes](#15-safety-notes) --- ## 1. Feature Overview | Feature | Description | |---|---| | **AUTO mode** | Steps advance immediately when advance condition is met | | **INCREMENT mode** | Condition must be TRUE then operator presses `Cmd_Incr` to advance | | **PAUSE** | Soft hold — all outputs frozen in place; resume resumes same step | | **STOP (CAT2)** | Hard hold — requires `Cmd_Reset` to return to IDLE | | **E-Stop CAT0** | Immediate: all outputs de-energised in the same scan | | **E-Stop CAT1** | Controlled: current step finishes its "safe motion" then stops | | **E-Stop CAT2** | Suspend: outputs frozen until reset (same as STOP) | | **Skip Step** | Operator can force-advance any step NOT safety-locked | | **Disable Step** | Individual steps can be permanently skipped (e.g. bypass unused stations) | | **Safety-Locked Steps** | Steps 1, 5, 7 cannot be skipped — operator `SkipStep` is silently ignored | | **Timer Advance** | Steps 4, 6, 8 advance on IEC timer expiry (no sensor needed) | | **1-Sensor Advance** | Steps 2, 5, 7, 10 advance on single sensor | | **2-Sensor Advance** | Steps 1, 3, 9 use FWD + BWD sensors with conflict detection | | **Step Watchdog** | 30 s watchdog per step — faults if a step takes too long | | **Cycle Counter** | Persistent `CycleCount` DINT increments on every completed cycle | --- ## 2. File Structure ``` 📁 WeldSequencer/ ├── FB_WeldSequencer.scl # Main Function Block — all sequencer logic └── README.md # This file ``` > **Note:** In TIA Portal, create one **Instance DB** for the FB (e.g. `DB_WeldSeq`). The instance DB holds all internal state, timers, and configuration arrays. --- ## 3. I/O Map ### Digital Inputs (DI) | Address | Tag Name | Description | Used in Step(s) | |---|---|---|---| | `%I0.0` | `Sen_HomeFwd` | Fixture at home position | 1 | | `%I0.1` | `Sen_HomeBwd` | Fixture NOT in work zone (redundant) | 1 | | `%I0.2` | `Sen_ClampClosed` | Clamp jaw fully closed | 2 | | `%I0.3` | `Sen_HeadAtWeldPos` | Weld head fully EXTENDED | 3, 9 | | `%I0.4` | `Sen_HeadRetracted` | Weld head fully RETRACTED | 3, 9 | | `%I0.5` | `Sen_ArcDetect` | Arc current detected (welder feedback) | 5 | | `%I0.6` | `Sen_ArcOff` | Arc extinguished (current < threshold) | 7 | | `%I0.7` | `Sen_UnclampConf` | Clamp open / part ejected | 10 | | `%I1.0` | `Safety_EStopOK` | Safety relay: TRUE = E-Stop clear | All | | `%I1.1` | `Safety_DoorClosed` | Safety gate NC contact | All | | `%I1.2` | `Cmd_EStop` | E-Stop command (from safety relay or HMI) | All | | `%I1.3` | `Cmd_Reset` | Reset faults / return to IDLE | All | | `%I1.4` | `Cmd_Start` | Start cycle / Resume after pause | All | | `%I1.5` | `Cmd_Pause` | Pause at current step | All | | `%I1.6` | `Cmd_Stop` | CAT2 Stop | All | | `%I1.7` | `Cmd_Incr` | Increment step (INCREMENT mode only) | All | | `%I2.0` | `Mode_Auto` | Automatic mode selector | All | | `%I2.1` | `Mode_Incr` | Increment mode selector | All | | `%I2.2` | `Cmd_SkipStep` | Skip current step (if not locked) | All | ### Digital Outputs (DQ) | Address | Tag Name | Description | Active in Step(s) | |---|---|---|---| | `%Q0.0` | `Act_Clamp` | Clamp solenoid | 2 → 9 | | `%Q0.1` | `Act_HeadExtend` | Weld head extend solenoid | 3 → 8 | | `%Q0.2` | `Act_HeadRetract` | Weld head retract solenoid | 9 | | `%Q0.3` | `Act_GasValve` | Shielding gas solenoid valve | 4 → 8 | | `%Q0.4` | `Act_WeldEnable` | Welder power enable relay | 5, 6 | | `%Q0.5` | `Act_Unclamp` | Unclamp solenoid | 10 | | `%Q0.6` | `Act_PartEject` | Part ejector cylinder solenoid | 10 | | `%Q1.0` | `Seq_Running` | Sequence running indicator | — | | `%Q1.1` | `Seq_Paused` | Sequence paused indicator | — | | `%Q1.2` | `Seq_Faulted` | Fault active indicator | — | | `%Q1.3` | `Seq_Complete` | Cycle complete indicator | — | ### Memory / HMI Words | Address | Tag Name | Type | Description | |---|---|---|---| | `%MW10` | `StopCategory` | INT | E-Stop category: 0, 1, or 2 | | `%MW20` | `ActiveStep` | INT | Currently executing step | | `%MW22` | `SeqState` | INT | State machine code (0–6) | | `%MW24` | `FaultCode` | INT | Active fault code | | `%M5.0` | `StepAdvanceReady` | BOOL | Advance condition satisfied | | `%M5.1` | `IncrWaiting` | BOOL | Waiting for Incr in INCREMENT mode | | `%MD30` | `CycleCount` | DINT | Completed cycles | --- ## 4. Sequencer Modes ### AUTO Mode (`Mode_Auto = TRUE`) ``` Cmd_Start ──→ Step 1 ──[cond met]──→ Step 2 ──[cond met]──→ ... ──→ Step 10 ──→ COMPLETE ``` The sequence runs end-to-end without any operator input once started. Each step advances the instant its advance condition becomes TRUE. Intended for normal production operation. ### INCREMENT Mode (`Mode_Incr = TRUE`) ``` Cmd_Start ──→ Step 1 ──[cond met + Cmd_Incr]──→ Step 2 ──[cond met + Cmd_Incr]──→ ... ``` The sequencer waits at each step until: 1. The step's advance condition is `TRUE` (sensor or timer) 2. **AND** the operator presses `Cmd_Incr` The `IncrWaiting` output goes `TRUE` when condition is met but waiting for the increment button — useful for an HMI indicator ("Ready to advance — press INCR"). **Use cases:** First article inspection, commissioning, slow-speed prove-out, fault recovery. > **Mode switching:** Change modes between cycles only (while in IDLE or COMPLETE). Switching mid-cycle is accepted by the FB but may cause unexpected step dwell. --- ## 5. State Machine ``` ┌─────────────────────────────────────────────────────┐ │ │ ▼ │ ┌─────────────────┐ Cmd_Start + safe ┌───────────────────┐ │ │ 0 — IDLE │ ─────────────────────▶ │ 1 — RUNNING │ │ └─────────────────┘ └───────────────────┘ │ ▲ │ │ │ │ │ │ Cmd_Reset Cmd_Pause│ │ │ │last step │ (from STOPPED/FAULTED/ ◀────────┘ │ │ ▼ │ COMPLETE) ┌──────────────┐ │ │ ┌──────────────┐ │ │ 2 — PAUSED │ │ │ │ 6 — COMPLETE │─┘ │ └──────────────┘ │ │ └──────────────┘ │ Cmd_Stop▼ │ │ │ ┌──────────────┐ │ E-Stop │ │ 4 — STOPPED │◀───┘ CAT1│ │ └──────────────┘ ▼ │ ┌─────────────────────┐ │ │ 3 — STOPPING_CAT1 │ │ └─────────────────────┘ │ ┌──────────────┐ │ step done or timeout │ ◀────────────────── │ 5 — FAULTED │◀─────────┘ │ Cmd_Reset └──────────────┘ │ + E-Stop clear ▲ │ + door closed │ E-Stop CAT0 / door open └───────────────────────────────────────┘ ``` | State | Code | Outputs | Resume? | Reset? | |---|---|---|---|---| | IDLE | 0 | Weld/gas/motion off | — | — | | RUNNING | 1 | Per active step | — | — | | PAUSED | 2 | **Held** (frozen) | `Cmd_Start` | — | | STOPPING_CAT1 | 3 | Current step active | — | After → STOPPED | | STOPPED | 4 | Safe state | — | `Cmd_Reset` | | FAULTED | 5 | **ALL off** | — | `Cmd_Reset` + clear | | COMPLETE | 6 | Weld/gas off | `Cmd_Start` (new cycle) | `Cmd_Reset` | --- ## 6. Stop Categories (IEC 60204-1) Set `StopCategory` (INT) via HMI or hard-wired selector before triggering `Cmd_EStop`. ### CAT0 — Uncontrolled Stop (Immediate) ``` Cmd_EStop = TRUE, StopCategory = 0 │ └──▶ State → FAULTED ALL outputs := FALSE (same PLC scan) FaultCode := 11 ``` - Power removed from actuators immediately — no "safe" motion completes - Required for: hazardous energy, fire risk, collision imminent - Hardware: typically wired directly to safety relay, not via PLC ### CAT1 — Controlled Stop ``` Cmd_EStop = TRUE, StopCategory = 1 │ └──▶ State → STOPPING_CAT1 Current step continues executing (sensor/timer logic active) CAT1 guard timer starts (10 s) │ ├── Step advance condition met ──▶ State → STOPPED (clean stop) │ └── Timer.Q (timeout) ──▶ State → FAULTED, FaultCode = 20 ``` - Allows servo drives, cylinders, and the weld head to complete their safe end-position before power is removed - Prevents mechanical damage from mid-stroke stops - 10 s `CAT1_TIMEOUT` constant protects against hangs — adjust for your application ### CAT2 — Controlled Stop (Power Maintained) ``` Cmd_EStop = TRUE, StopCategory = 2 (or Cmd_Stop rising edge) │ └──▶ State → STOPPED Outputs frozen at current values Drives/brakes remain energised (position maintained) Cmd_Reset required to return to IDLE ``` - Used for: planned end-of-shift, material change, inspection - Unlike PAUSE, requires explicit Reset rather than Start to resume --- ## 7. Pause vs Stop | | PAUSE (`Cmd_Pause`) | STOP (`Cmd_Stop`) | |---|---|---| | **Activation** | Rising edge `Cmd_Pause` | Rising edge `Cmd_Stop` | | **IEC Category** | — (not a stop category) | CAT2 | | **Outputs** | Held at current state | Held at current state | | **Resume** | `Cmd_Start` → continues same step | `Cmd_Reset` → returns to IDLE | | **Typical use** | Short interruption (fork truck, material feed) | Planned stop, shift change, part change | | **From safety fault?** | Cannot resume if door open | Cannot reset if E-Stop active | | **Step continuity** | Resumes mid-step (timer paused) | Restarts from Step 1 after reset | > **Important:** In PAUSED state, step timers stop counting (their `IN` bit goes FALSE because `_state ≠ STATE_RUNNING`). When resumed, timers restart from zero for the current step. If this is undesirable for your application (e.g. partial gas purge time), modify the timer `IN` condition to also include `STATE_PAUSED`. --- ## 8. Step-by-Step Breakdown ### Step 1 — Home Position Verify 🔒 Safety-Locked ``` Sensors : Sen_HomeFwd (at home) + Sen_HomeBwd (NOT in work zone) Actuators: NONE Advance : Sen_HomeFwd = TRUE AND Sen_HomeBwd = FALSE Lock : Safety-locked — SkipStep ignored Purpose : Confirm fixture/robot is at safe starting co-ordinate before clamping a part. Two-sensor logic eliminates single-sensor failure. ``` ### Step 2 — Clamp Workpiece ``` Sensors : Sen_ClampClosed (1 sensor) Actuators: Act_Clamp ON Advance : Sen_ClampClosed = TRUE Purpose : Engage pneumatic clamp jaw on the workpiece. Act_Clamp remains energised throughout steps 2–9. ``` ### Step 3 — Extend Weld Head ``` Sensors : Sen_HeadAtWeldPos (FWD) + Sen_HeadRetracted (BWD — conflict check) Actuators: Act_HeadExtend ON Advance : Sen_HeadAtWeldPos = TRUE (FWD sensor) Purpose : Drive weld torch to the weld start position. FWD+BWD conflict detection → FaultCode 30 if both TRUE. ``` ### Step 4 — Pre-Purge Gas ⏱ Timer ``` Sensors : NONE Actuators: Act_GasValve ON Advance : Timer T#2S elapsed Purpose : Flow shielding gas (Argon/CO₂ mix) before arc strike to displace atmospheric oxygen from the weld zone. ``` ### Step 5 — Arc Strike 🔒 Safety-Locked ``` Sensors : Sen_ArcDetect (1 sensor) Actuators: Act_WeldEnable ON + Act_GasValve ON Advance : Sen_ArcDetect = TRUE Lock : Safety-locked — arc MUST be confirmed before weld travel begins Purpose : Enable the welder and wait for arc current feedback. Without this lock, a failed arc strike could lead to cold welds. ``` ### Step 6 — Weld Travel ⏱ Timer ``` Sensors : NONE Actuators: Act_WeldEnable ON + Act_GasValve ON Advance : Timer T#4S elapsed Purpose : Robot/axis traverses the weld seam. PLC holds weld outputs stable for the defined weld duration. In real systems, replace timer with a robot "weld complete" handshake DI. ``` ### Step 7 — Arc Off / Weld End 🔒 Safety-Locked ``` Sensors : Sen_ArcOff (1 sensor) Actuators: Act_WeldEnable OFF (commanded off this step) Act_GasValve ON (gas continues for pool protection) Advance : Sen_ArcOff = TRUE Lock : Safety-locked — arc extinction MUST be confirmed before motion Purpose : Confirm the arc is truly off before allowing any mechanical movement. Prevents weld spatter damage to optics/sensors. ``` ### Step 8 — Post-Purge Gas ⏱ Timer ``` Sensors : NONE Actuators: Act_GasValve ON Advance : Timer T#2.5S elapsed Purpose : Continue shielding gas flow after arc off to protect the cooling weld pool from oxidation. ``` ### Step 9 — Retract Weld Head ``` Sensors : Sen_HeadRetracted (BWD) + Sen_HeadAtWeldPos (FWD — conflict check) Actuators: Act_HeadRetract ON, Act_HeadExtend OFF Advance : Sen_HeadRetracted = TRUE AND Sen_HeadAtWeldPos = FALSE (BWD sensor) Purpose : Return weld torch to safe retracted home position before unclamp/eject. Uses the same sensor pair as Step 3. ``` ### Step 10 — Unclamp / Part Eject ``` Sensors : Sen_UnclampConf (1 sensor) Actuators: Act_Clamp OFF, Act_Unclamp ON, Act_PartEject ON Advance : Sen_UnclampConf = TRUE → COMPLETE Purpose : Release the finished weld assembly and fire the ejector cylinder to clear the fixture for the next part. On advance, state → COMPLETE, CycleCount increments. ``` --- ## 9. Step Advance Types Three advance methods are used across the 10 steps: ### Type A — Dual-Sensor (FWD + BWD) Used by: **Steps 1, 3, 9** ```scl // Step 3 example _stepAdvReady := Sen_HeadAtWeldPos; // FWD sensor = advance condition // Sen_HeadRetracted monitored separately for conflict detection ``` The two sensors serve different purposes: - **FWD sensor** → advance trigger (target position reached) - **BWD sensor** → interlock / conflict check (should be opposite state) - Both TRUE simultaneously → **FaultCode 30** (wiring fault or sensor failure) ### Type B — Single Sensor Used by: **Steps 2, 5, 7, 10** ```scl // Step 2 example _stepAdvReady := Sen_ClampClosed; ``` Simplest form. Step activates its actuator(s) and waits for confirmation feedback. ### Type C — Timer Only (no sensor) Used by: **Steps 4, 6, 8** ```scl // Step 4 example — timer resets automatically when step changes _stepTimer[4](IN := (_activeStep = 4 AND _state = STATE_RUNNING), PT := T#2S); _stepAdvReady := _stepTimer[4].Q; ``` The timer `IN` is gated on `(_activeStep = N AND STATE_RUNNING)`. When the step changes, `IN` goes FALSE and the TON resets automatically — no manual reset logic required. --- ## 10. Skip / Disable / Safety-Lock ### Disable a Step (permanent skip every cycle) Set in the instance DB or via HMI write to `_stepEnabled[N]`: ```scl // Example: disable step 6 (weld travel) for a tack-weld-only mode "DB_WeldSeq"._stepEnabled[6] := FALSE; ``` Disabled steps are silently skipped by the `WHILE` loop that finds the next enabled step. The step's actuator outputs are never energised. ### Skip Current Step (operator, one-time) Rising edge on `Cmd_SkipStep`. The FB checks `_stepSafetyLocked[_activeStep]`: ``` Cmd_SkipStep (↑) ──→ Is step safety-locked? YES → Ignore (no action, no feedback) NO → _forceAdvance := TRUE → step advances next scan ``` ### Safety-Locked Steps Set during initialisation: ```scl _stepSafetyLocked[1] := TRUE; // Home verify _stepSafetyLocked[5] := TRUE; // Arc strike _stepSafetyLocked[7] := TRUE; // Arc off ``` **Why lock these steps?** | Step | Risk if skipped | |---|---| | 1 — Home Verify | Clamp closes on robot arm / fixture not in position | | 5 — Arc Strike | Weld travel with no arc = cold weld, undetected failure | | 7 — Arc Off | Moving head while arc still live = flash, fire, damage | To add safety-locking to other steps, set `_stepSafetyLocked[N] := TRUE` in the `IF NOT _initDone` block. --- ## 11. Fault Codes | Code | Name | Cause | Resolution | |---|---|---|---| | 0 | No fault | Normal | — | | 10 | Safety door open | Door opened during RUN or PAUSED | Close door → `Cmd_Reset` | | 11 | E-Stop activated | `Cmd_EStop = TRUE` or `Safety_EStopOK = FALSE` | Clear E-Stop → `Cmd_Reset` | | 20 | CAT1 timeout | Step did not complete within `CAT1_TIMEOUT` (10 s) | Investigate stuck actuator → `Cmd_Reset` | | 30 | Sensor conflict | `Sen_HeadAtWeldPos` AND `Sen_HeadRetracted` both TRUE | Check sensor wiring/target → `Cmd_Reset` | | 40 | Step watchdog | Step active for > `WATCHDOG_TIME` (30 s) | Investigate jammed actuator or missing sensor → `Cmd_Reset` | --- ## 12. HMI Integration ### Recommended HMI Tags | HMI Tag | PLC Address | Notes | |---|---|---| | `SeqState` | `%MW22` | Use value display + state text list | | `ActiveStep` | `%MW20` | Highlight active step on step diagram | | `FaultCode` | `%MW24` | Alarm trigger with code text list | | `CycleCount` | `%MD30` | Production counter display | | `StepAdvanceReady` | `%M5.0` | Green indicator on each step | | `IncrWaiting` | `%M5.1` | Flashing "Press INCR" indicator | | `StopCategory` | `%MW10` | Selector: 0 / 1 / 2 | ### State Text List (for `SeqState` display) ``` 0 = "IDLE — Ready" 1 = "RUNNING" 2 = "PAUSED" 3 = "STOPPING (CAT1)" 4 = "STOPPED" 5 = "FAULTED" 6 = "CYCLE COMPLETE" ``` ### Fault Code Alarm List ``` 10 = "Safety door opened — close door and reset" 11 = "E-Stop activated — clear E-Stop and reset" 20 = "CAT1 stop timeout — check step actuator" 30 = "Head sensor conflict — check I0.3 and I0.4" 40 = "Step watchdog timeout — step did not complete in 30 s" ``` --- ## 13. TIA Portal Setup ### Creating the Instance DB 1. In the project tree, right-click the program folder → **Add new block** 2. Select **Data Block** → name it `DB_WeldSeq` 3. Set the block type to **Instance DB** of `FB_WeldSequencer` 4. Compile ### Calling the FB Add to your cyclic interrupt OB (e.g. `OB30` at 10 ms) or `OB1`: ```scl "DB_WeldSeq"( Mode_Auto := "HMI_ModeAuto", Mode_Incr := "HMI_ModeIncr", Cmd_Start := "PB_Start", Cmd_Pause := "PB_Pause", Cmd_Stop := "PB_Stop", Cmd_EStop := "SafetyRelay_EStop", Cmd_Reset := "PB_Reset", Cmd_Incr := "PB_Incr", Cmd_SkipStep := "PB_SkipStep", StopCategory := "HMI_StopCategory", Safety_DoorClosed := "SafetyGate_Closed", Safety_EStopOK := "SafetyRelay_OK", Sen_HomeFwd := %I0.0, Sen_HomeBwd := %I0.1, Sen_ClampClosed := %I0.2, Sen_HeadAtWeldPos := %I0.3, Sen_HeadRetracted := %I0.4, Sen_ArcDetect := %I0.5, Sen_ArcOff := %I0.6, Sen_UnclampConf := %I0.7, Act_Clamp => %Q0.0, Act_HeadExtend => %Q0.1, Act_HeadRetract => %Q0.2, Act_GasValve => %Q0.3, Act_WeldEnable => %Q0.4, Act_Unclamp => %Q0.5, Act_PartEject => %Q0.6, Seq_Running => %Q1.0, Seq_Paused => %Q1.1, Seq_Faulted => %Q1.2, Seq_Complete => %Q1.3, ActiveStep => %MW20, SeqState => %MW22, FaultCode => %MW24, StepAdvanceReady => %M5.0, IncrWaiting => %M5.1, CycleCount => %MD30 ); ``` ### Adjusting Step Configuration at Runtime Write to the instance DB directly (e.g. from HMI or during commissioning): ```scl // Disable step 6 (bypass weld travel for testing) "DB_WeldSeq"._stepEnabled[6] := FALSE; // Change pre-purge time to 3 seconds "DB_WeldSeq"._stepTimerPreset[4] := T#3S; // Enable step 6 again "DB_WeldSeq"._stepEnabled[6] := TRUE; ``` > **Note:** Timer preset changes take effect on the NEXT activation of that step (TON picks up the new `PT` value when it starts). --- ## 14. Adapting the Code ### Adding More Steps 1. Change array bounds: `Array[1..N]` in all 6 array declarations 2. Update `LAST_STEP` constant 3. Add a new `CASE` branch for each new step 4. Call additional step timers and watchdog timers explicitly ### Replacing Timer Advance with Robot Handshake Step 6 uses a timer for weld travel. In a real system with a robot controller: ```scl // Replace timer advance in Step 6 with robot "weld complete" signal 6: Act_WeldEnable := TRUE; Act_GasValve := TRUE; _stepAdvReady := Robot_WeldComplete; // Add this DI to VAR_INPUT ``` ### Adding More Sensor Types For a step needing **analog threshold advance** (e.g. temperature): ```scl // In step logic: _stepAdvReady := (TempSensor_mV > 4500); // Weld pool temp threshold ``` ### Multiple Sequencer Instances Create multiple instance DBs for parallel lines: ```scl "DB_WeldSeq_Line1"(...); "DB_WeldSeq_Line2"(...); ``` Each instance is completely independent with its own state, timers, and counter. ### Changing CAT1 Timeout ```scl // In VAR CONSTANT section: CAT1_TIMEOUT : Time := T#15S; // Increase for slower machinery ``` Or make it configurable via VAR_INPUT if different cells need different values. --- ## 15. Safety Notes > ⚠️ **This code is a demonstration template. It does NOT constitute a validated safety function and must NOT be used as-is for CE-marked or safety-certified applications without a proper risk assessment and SISTEMA analysis.** ### Minimum Requirements Before Deployment - [ ] Full HAZOP / risk assessment per **ISO 12100** - [ ] E-Stop circuit designed to **ISO 13850** — hardware safety relay, not PLC output - [ ] Safety door interlocks to **ISO 14119** — use safety-rated sensors - [ ] Emergency stop category confirmed per **IEC 60204-1 Section 9.2** - [ ] CAT1 stop implementation validated: actuators must de-energise AFTER safe position confirmed - [ ] Dual-channel safety inputs for CAT3/PLd or higher - [ ] Functional safety assessment if PL ≥ c required (consider SIMATIC S7-1500F / F-FB) - [ ] Factory Acceptance Test (FAT) covering all modes, stop categories, and fault scenarios ### Software Safety Good Practice (Applied in This Code) - All output variables cleared to `FALSE` at the top of every scan before step logic re-energises them — eliminates "stuck on" from removed steps - FAULTED state drives all outputs to FALSE (Section 6 override) - E-Stop and door monitoring execute BEFORE the state machine — highest priority - Safety-locked steps enforce physical interlocks in software as a secondary barrier - Sensor conflict detection for dual-sensor pairs - Per-step watchdog timers catch hung steps before operators notice --- ## Changelog | Version | Date | Notes | |---|---|---| | 0.1 | 2025 | Initial release — 10-step welding cell demo | --- ## License MIT License — free to use and adapt for commercial or personal projects. Attribution appreciated but not required. --- *Generated for S7-1500 / TIA Portal V18+. Tested syntax against SCL compiler rules. Always perform a full offline simulation before deploying to hardware.*