s7-SCL-scripts/s7-1500/demo-advance-scl-contol.md

675 lines
25 KiB
Markdown
Raw Normal View History

# 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 (06) |
| `%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 29.
```
### 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
2026-02-24 11:34:36 +00:00
);
```
### 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.*