298 lines
19 KiB
Plaintext
298 lines
19 KiB
Plaintext
(*═══════════════════════════════════════════════════════════════════════════════
|
|
DEMO_WeldCellIntegration.scl
|
|
─────────────────────────────────────────────────────────────────────────────
|
|
Demonstrates FB_CylinderMonitor instances for all 4 sensor configurations
|
|
wired into the FB_WeldSequencer from the welding cell demo.
|
|
|
|
CYLINDERS IN THIS DEMO:
|
|
┌──────┬───────────────────────┬──────────────┬────────────────────────────┐
|
|
│ Inst │ Cylinder │ SensorConfig │ Notes │
|
|
├──────┼───────────────────────┼──────────────┼────────────────────────────┤
|
|
│ DB1 │ Clamp Cylinder │ ONE_FWD (1) │ Only clamp-closed sensor │
|
|
│ DB2 │ Weld Head │ TWO (3) │ Extended + retracted sensor │
|
|
│ DB3 │ Part Ejector │ ONE_BWD (2) │ Only retracted (home) sensor│
|
|
│ DB4 │ Gas Purge Valve │ NONE (0) │ No position sensor, timer │
|
|
└──────┴───────────────────────┴──────────────┴────────────────────────────┘
|
|
|
|
RESPONSE CONFIGURATION:
|
|
Timeout faults → PAUSE machine (operator can clear & resume)
|
|
Conflict faults → STOP machine (requires Reset before restart)
|
|
Lost position → STOP machine (requires Reset before restart)
|
|
|
|
CALL ORDER in OB (important — monitors must execute BEFORE sequencer):
|
|
1. FB_CylinderMonitor instances (DB1..DB4)
|
|
2. FB_CylFaultCollector (DB_CylFaults)
|
|
3. FB_WeldSequencer (DB_WeldSeq)
|
|
═══════════════════════════════════════════════════════════════════════════════*)
|
|
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
// INSTANCE DB DECLARATIONS (create these in TIA Portal project tree)
|
|
//
|
|
// DB_CylClamp : FB_CylinderMonitor
|
|
// DB_CylHead : FB_CylinderMonitor
|
|
// DB_CylEject : FB_CylinderMonitor
|
|
// DB_CylGas : FB_CylinderMonitor
|
|
// DB_CylFaults : FB_CylFaultCollector
|
|
// DB_WeldSeq : FB_WeldSequencer
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// CYLINDER 1 — CLAMP (ONE_FWD: only clamp-closed sensor at FWD end)
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Physical setup:
|
|
// Proximity sensor mounted at closed (extended) jaw position ONLY.
|
|
// No sensor at open position — we assume open if no clamp command active.
|
|
//
|
|
// Error logic:
|
|
// Cmd_Fwd (clamp) active → Sen_Fwd (clamp closed) not confirmed in 2 s
|
|
// → FaultCode 1 (FWD timeout) → machine PAUSE
|
|
// Sen_Fwd unexpectedly active with no command? → Not detected (ONE_FWD limit)
|
|
//
|
|
// Advance in sequencer:
|
|
// Step 2 advance condition: DB_CylClamp.AtFwd
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_CylClamp"(
|
|
CylName := 'Clamp Cylinder',
|
|
SensorConfig := 1, // ONE_FWD
|
|
T_Timeout := T#2S, // 2 second fault timeout
|
|
Cmd_Fwd := "DB_WeldSeq".Act_Clamp, // Sequencer output drives FWD
|
|
Cmd_Bwd := NOT "DB_WeldSeq".Act_Clamp AND NOT "DB_WeldSeq".Seq_Faulted,
|
|
// Bwd inferred: not clamped & not faulted
|
|
Cmd_Reset := "PB_Reset",
|
|
Sen_Fwd := %I0.2, // Sen_ClampClosed hardware input
|
|
Sen_Bwd := FALSE, // No sensor at open position
|
|
Enable := "DB_WeldSeq".Seq_Running OR "DB_WeldSeq".Seq_Paused
|
|
);
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// CYLINDER 2 — WELD HEAD (TWO sensors: extended + retracted)
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Physical setup:
|
|
// Sensor at fully extended (weld position) = Sen_Fwd → %I0.3
|
|
// Sensor at fully retracted (safe position) = Sen_Bwd → %I0.4
|
|
//
|
|
// Error logic:
|
|
// Extend cmd → Sen_Fwd not confirmed in 3 s → FaultCode 1 → PAUSE
|
|
// Retract cmd → Sen_Bwd not confirmed in 3 s → FaultCode 2 → PAUSE
|
|
// Both sensors TRUE simultaneously → FaultCode 3 → STOP
|
|
// Sensors both drop with no command active → FaultCode 4 (lost) → STOP
|
|
//
|
|
// Advance in sequencer:
|
|
// Step 3 advance: DB_CylHead.AtFwd
|
|
// Step 9 advance: DB_CylHead.AtBwd
|
|
//
|
|
// NOTE: Extend and Retract are separate solenoid outputs (bistable valve)
|
|
// CylCmd_FwdSafe → Act_HeadExtend solenoid
|
|
// CylCmd_BwdSafe → Act_HeadRetract solenoid
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_CylHead"(
|
|
CylName := 'Weld Head',
|
|
SensorConfig := 3, // TWO sensors
|
|
T_Timeout := T#3S, // 3 seconds (head travel takes longer)
|
|
Cmd_Fwd := "DB_WeldSeq".Act_HeadExtend,
|
|
Cmd_Bwd := "DB_WeldSeq".Act_HeadRetract,
|
|
Cmd_Reset := "PB_Reset",
|
|
Sen_Fwd := %I0.3, // Sen_HeadAtWeldPos
|
|
Sen_Bwd := %I0.4, // Sen_HeadRetracted
|
|
Enable := "DB_WeldSeq".Seq_Running OR "DB_WeldSeq".Seq_Paused
|
|
OR "DB_WeldSeq".Seq_Stopping
|
|
);
|
|
|
|
// ── Wire safe outputs back to physical DQs ───────────────────────────────
|
|
%Q0.1 := "DB_CylHead".CylCmd_FwdSafe; // Act_HeadExtend (gated)
|
|
%Q0.2 := "DB_CylHead".CylCmd_BwdSafe; // Act_HeadRetract (gated)
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// CYLINDER 3 — PART EJECTOR (ONE_BWD: only home/retracted sensor)
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Physical setup:
|
|
// The ejector fires forward (extends) to push the part out.
|
|
// Sensor only at retracted (home) end — confirms ejector is clear/home.
|
|
// No sensor at extended (ejected) position.
|
|
//
|
|
// Error logic:
|
|
// Retract cmd (home return) → Sen_Bwd not confirmed in 1.5 s
|
|
// → FaultCode 2 (BWD timeout) → PAUSE
|
|
// Eject (FWD) cmd: no FWD sensor, so no timeout — just fires blind.
|
|
// After timer completes in sequencer, retract command issued.
|
|
//
|
|
// Advance in sequencer:
|
|
// Step 10 advance uses Sen_UnclampConf (%I0.7) which is separate.
|
|
// After cycle complete, this FB confirms ejector is home before next cycle.
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_CylEject"(
|
|
CylName := 'Part Ejector',
|
|
SensorConfig := 2, // ONE_BWD
|
|
T_Timeout := T#1500MS,
|
|
Cmd_Fwd := "DB_WeldSeq".Act_PartEject,
|
|
Cmd_Bwd := NOT "DB_WeldSeq".Act_PartEject
|
|
AND "DB_WeldSeq".Seq_Complete,
|
|
Cmd_Reset := "PB_Reset",
|
|
Sen_Fwd := FALSE, // No sensor at ejected position
|
|
Sen_Bwd := %I0.7, // Ejector home sensor (shared / Sen_UnclampConf area)
|
|
Enable := TRUE // Always enabled
|
|
);
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// CYLINDER 4 — GAS PURGE VALVE (NONE: no position sensors)
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Physical setup:
|
|
// Simple solenoid valve — open or closed.
|
|
// No position feedback — valve assumed open when energised.
|
|
// No fault can be generated from position sensors (none exist).
|
|
//
|
|
// Error logic:
|
|
// NONE: the FB passes the command through, reports AT_FWD when commanded
|
|
// On/Off confirmed only by timer in the sequencer (Steps 4, 6, 8).
|
|
//
|
|
// NOTE: A pressure switch or flow sensor could be added here in future.
|
|
// Connect it to Sen_Fwd and change SensorConfig to ONE_FWD.
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_CylGas"(
|
|
CylName := 'Gas Purge Valve',
|
|
SensorConfig := 0, // NONE
|
|
T_Timeout := T#500MS, // Not used with NONE config (no timers start)
|
|
Cmd_Fwd := "DB_WeldSeq".Act_GasValve,
|
|
Cmd_Bwd := FALSE, // Single-acting valve — spring return
|
|
Cmd_Reset := "PB_Reset",
|
|
Sen_Fwd := FALSE,
|
|
Sen_Bwd := FALSE,
|
|
Enable := TRUE
|
|
);
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// FAULT COLLECTOR — Aggregates all 4 cylinder faults
|
|
// Outputs feed directly into the sequencer Cmd_Pause / Cmd_Stop inputs
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_CylFaults"(
|
|
//── Fault bits ───────────────────────────────────────────────────────────
|
|
Cyl1_Fault := "DB_CylClamp".Fault_Active,
|
|
Cyl2_Fault := "DB_CylHead".Fault_Active,
|
|
Cyl3_Fault := "DB_CylEject".Fault_Active,
|
|
Cyl4_Fault := "DB_CylGas".Fault_Active,
|
|
Cyl5_Fault := FALSE,
|
|
Cyl6_Fault := FALSE,
|
|
Cyl7_Fault := FALSE,
|
|
Cyl8_Fault := FALSE,
|
|
|
|
//── Fault codes ───────────────────────────────────────────────────────────
|
|
Cyl1_FaultCode := "DB_CylClamp".FaultCode,
|
|
Cyl2_FaultCode := "DB_CylHead".FaultCode,
|
|
Cyl3_FaultCode := "DB_CylEject".FaultCode,
|
|
Cyl4_FaultCode := "DB_CylGas".FaultCode,
|
|
Cyl5_FaultCode := 0,
|
|
Cyl6_FaultCode := 0,
|
|
Cyl7_FaultCode := 0,
|
|
Cyl8_FaultCode := 0,
|
|
|
|
//── HMI fault texts ───────────────────────────────────────────────────────
|
|
Cyl1_FaultText := "DB_CylClamp".HMI_FaultText,
|
|
Cyl2_FaultText := "DB_CylHead".HMI_FaultText,
|
|
Cyl3_FaultText := "DB_CylEject".HMI_FaultText,
|
|
Cyl4_FaultText := "DB_CylGas".HMI_FaultText,
|
|
|
|
//── Machine response policy ───────────────────────────────────────────────
|
|
// Timeout → PAUSE (1): operator can check & reset, then resume
|
|
// Conflict → STOP (2): two sensors TRUE = hardware fault, needs investigation
|
|
// Lost pos → STOP (2): cylinder moved undetected = mechanical issue
|
|
Response_Timeout := 1,
|
|
Response_Conflict := 2,
|
|
Response_Lost := 2
|
|
);
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// WELDING SEQUENCER — Wired with cylinder feedback and fault injection
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
"DB_WeldSeq"(
|
|
//── Mode & commands ─────────────────────────────────────────────────────
|
|
Mode_Auto := %I2.0,
|
|
Mode_Incr := %I2.1,
|
|
Cmd_Start := %I1.4,
|
|
Cmd_Reset := "PB_Reset",
|
|
|
|
// ── PAUSE: operator button OR cylinder fault requesting pause ──────────
|
|
Cmd_Pause := %I1.5
|
|
OR "DB_CylFaults".Cmd_MachinePause,
|
|
|
|
// ── STOP: operator button OR cylinder fault requesting stop ───────────
|
|
Cmd_Stop := %I1.6
|
|
OR "DB_CylFaults".Cmd_MachineStop,
|
|
|
|
Cmd_EStop := %I1.2,
|
|
Cmd_Incr := %I1.7,
|
|
Cmd_SkipStep := %I2.2,
|
|
StopCategory := %MW10,
|
|
|
|
//── Safety inputs ────────────────────────────────────────────────────────
|
|
Safety_DoorClosed := %I1.1,
|
|
Safety_EStopOK := %I1.0,
|
|
|
|
//── Sensors — using GATED outputs from cylinder monitors where possible ──
|
|
// Sequencer only sees "AtFwd/AtBwd" from healthy, confirmed cylinders.
|
|
// If cylinder monitor is faulted, AtFwd/AtBwd → FALSE → step never
|
|
// advances → watchdog trips → sequencer also faults. Belt & braces.
|
|
|
|
Sen_HomeFwd := %I0.0, // No cylinder monitor (robot)
|
|
Sen_HomeBwd := %I0.1,
|
|
|
|
// Step 2 clamp — uses cylinder monitor's AtFwd (confirmed clamp closed)
|
|
Sen_ClampClosed := "DB_CylClamp".AtFwd, // ← From monitor, not raw DI
|
|
|
|
// Steps 3 & 9 — weld head FWD/BWD (from monitor)
|
|
Sen_HeadAtWeldPos := "DB_CylHead".AtFwd, // ← Confirmed extended
|
|
Sen_HeadRetracted := "DB_CylHead".AtBwd, // ← Confirmed retracted
|
|
|
|
Sen_ArcDetect := %I0.5,
|
|
Sen_ArcOff := %I0.6,
|
|
|
|
// Step 10 unclamp (ejector home or unclamp sensor)
|
|
Sen_UnclampConf := "DB_CylEject".AtBwd, // ← Ejector home confirmed
|
|
|
|
//── Actuator outputs ─────────────────────────────────────────────────────
|
|
// NOTE: Act_HeadExtend and Act_HeadRetract go through the head cylinder
|
|
// monitor's gated outputs (see %Q assignments above).
|
|
// Act_Clamp goes direct here — the monitor checks it on its own scan.
|
|
Act_Clamp => %Q0.0,
|
|
Act_HeadExtend => "DB_CylHead_CmdFwd_Raw", // Internal tag; monitor gates it to %Q0.1
|
|
Act_HeadRetract => "DB_CylHead_CmdBwd_Raw", // Internal tag; monitor gates it to %Q0.2
|
|
Act_GasValve => %Q0.3,
|
|
Act_WeldEnable => %Q0.4,
|
|
Act_Unclamp => %Q0.5,
|
|
Act_PartEject => %Q0.6,
|
|
|
|
//── Status outputs ───────────────────────────────────────────────────────
|
|
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
|
|
);
|
|
|
|
//═════════════════════════════════════════════════════════════════════════════
|
|
// HMI WIRING SUMMARY
|
|
// Wire these tags to your WinCC/Comfort panel for operator guidance:
|
|
//
|
|
// TAG SOURCE HMI ELEMENT
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// DB_WeldSeq.ActiveStep → %MW20 Step indicator (1-10)
|
|
// DB_WeldSeq.SeqState → %MW22 State text list
|
|
// DB_WeldSeq.FaultCode → %MW24 Sequencer alarm
|
|
// DB_CylFaults.FirstFaultText First fault banner text
|
|
// DB_CylFaults.CylFaultWord Cylinder fault bitmask (overview)
|
|
// DB_CylFaults.ActiveFaultCount Number of active faults
|
|
// DB_CylClamp.CylState Clamp position indicator
|
|
// DB_CylClamp.HMI_StatusText Clamp status string
|
|
// DB_CylHead.CylState Head position indicator
|
|
// DB_CylHead.HMI_StatusText Head status string
|
|
// DB_CylEject.CylState Ejector status
|
|
// DB_CylHead.Moving Moving animation trigger
|
|
// DB_CylFaults.Cmd_Warning → %Q1.4 Amber warning lamp
|
|
// DB_WeldSeq.Seq_Faulted → %Q1.2 Red fault lamp
|
|
// DB_WeldSeq.IncrWaiting → %M5.1 "Press INCR" flashing indicator
|
|
//═════════════════════════════════════════════════════════════════════════════
|