Beckhoff First — Scan Bit
// Normal cyclic logic here IF initDone AND NOT bSystemReady THEN // Perform post-init checks END_IF The Beckhoff first scan bit ( _FIRSTSCAN ) is a reliable, simple mechanism for one-time PLC initialization in TwinCAT. When combined with careful handling of retentive data and task scheduling, it ensures deterministic startup behavior. Programmers should prefer the built-in system variable over manual constructs for clarity and correctness. Report prepared for: Beckhoff TwinCAT developers Last reviewed: April 2026 Version: 1.0
TwinCAT’s approach is very similar to CODESYS, given their shared roots. 5.1 Homing Routine Trigger IF _FIRSTSCAN THEN bStartHoming := TRUE; END_IF 5.2 Initialize Arrays or Structures IF _FIRSTSCAN THEN FOR i := 0 TO 99 DO TemperatureHistory[i] := 20.0; END_FOR bAlarmReset := FALSE; END_IF 5.3 Safe State Enforcement IF _FIRSTSCAN THEN bEmergencyStop := FALSE; (* clear any leftover estop flag *) bMotorEnable := FALSE; (* motors off until operator starts *) END_IF 6. Behavior Across Different PLC Start Types | Startup Type | _FIRSTSCAN triggered? | |-------------------------|--------------------------| | Cold start (power cycle) | Yes | | Warm start (online reset) | Yes | | Hot start (run→stop→run) | Yes (after stop) | | Login without reset | No (program continues) | Important: After a stop command, variables keep their last values. On resuming run, _FIRSTSCAN will be TRUE again — this can cause double-initialization if not designed correctly. 7. Common Pitfalls & Recommendations 7.1 Using _FIRSTSCAN with Retain Variables If a variable is RETAIN and you reinitialize it on first scan, you lose the retained value. Solution : Only initialize non-retain variables or use conditional checks. 7.2 First Scan Over Multiple Tasks _FIRSTSCAN is global but evaluated per task. A faster task might run multiple times before a slower task sees its first scan. Solution : Use task-local first scan if needed, or synchronize via a global flag. 7.3 Debugging First Scan Logic In online mode, the first scan runs immediately after login. To debug, insert a JMP or use breakpoints carefully, or simulate the condition by forcing _FIRSTSCAN via a watch window (possible only if variable is writable — usually not). 8. Best Practice Example PROGRAM MAIN VAR initDone : BOOL := FALSE; startupTime : TIME; END_VAR IF NOT initDone AND _FIRSTSCAN THEN // One-time init startupTime := T#0S; bSystemReady := FALSE; initDone := TRUE; END_IF beckhoff first scan bit
VAR firstScan : BOOL := TRUE; (* initial value = TRUE *) END_VAR // In main cyclic logic: IF firstScan THEN // Initialization code here firstScan := FALSE; END_IF ⚠️ : This manual method works only if firstScan is declared with RETAIN or PERSISTENT (to survive warm restart), otherwise a cold restart will re-trigger it, which might be intended or not. 4. Comparison with Other PLC Platforms | Platform | First Scan Flag | |------------------|---------------------------------| | Beckhoff TwinCAT | _FIRSTSCAN (system global) | | Siemens S7 | FirstScan in OB100 | | Rockwell ControlLogix | S:FS (First Scan) | | CODESYS | _FirstScan (implicit) | // Normal cyclic logic here IF initDone AND
VAR bFirstScan : BOOL; END_VAR bFirstScan := TwinCAT_SystemInfoVarList._FirstScan; END_VAR bFirstScan := TwinCAT_SystemInfoVarList._FirstScan