Standard Function Blocks
IEC 61131-3 defines a comprehensive set of standard function blocks that provide essential timing, counting, and logic functions for industrial automation applications.
🚀 Enhance Your Development Experience
Get syntax highlighting, IntelliSense, and debugging support for Structured Text:
Install VS Code Extension →Timer Function Blocks
Timer Function Blocks (TON, TOF, TP)
VAR OnDelayTimer : TON; // Timer On Delay OffDelayTimer : TOF; // Timer Off Delay PulseTimer : TP; // Timer Pulse StartSignal : BOOL := FALSE; StopSignal : BOOL := FALSE; TriggerPulse : BOOL := FALSE; MotorRunning : BOOL; AlarmActive : BOOL; PulseOutput : BOOL; END_VAR // TON - Timer On Delay // Output goes TRUE after input has been TRUE for preset time OnDelayTimer( IN := StartSignal, PT := T#5s ); MotorRunning := OnDelayTimer.Q; // TOF - Timer Off Delay // Output goes FALSE after input has been FALSE for preset time OffDelayTimer( IN := NOT StopSignal, PT := T#3s ); AlarmActive := OffDelayTimer.Q; // TP - Timer Pulse // Output pulse for preset duration when input goes TRUE PulseTimer( IN := TriggerPulse, PT := T#500ms ); PulseOutput := PulseTimer.Q;
TON - Timer On Delay
Members:
- • IN: Start input (BOOL)
- • PT: Preset time (TIME)
- • Q: Timer output (BOOL)
- • ET: Elapsed time (TIME)
Delays the TRUE signal by the preset time.
TOF - Timer Off Delay
Members:
- • IN: Input signal (BOOL)
- • PT: Preset time (TIME)
- • Q: Timer output (BOOL)
- • ET: Elapsed time (TIME)
Delays the FALSE signal by the preset time.
TP - Timer Pulse
Members:
- • IN: Trigger input (BOOL)
- • PT: Pulse duration (TIME)
- • Q: Pulse output (BOOL)
- • ET: Elapsed time (TIME)
Generates a pulse of fixed duration.
Counter Function Blocks
Counter Function Blocks (CTU, CTD, CTUD)
VAR UpCounter : CTU; // Count Up DownCounter : CTD; // Count Down UpDownCounter : CTUD; // Count Up/Down CountPulse : BOOL := FALSE; ResetCounter : BOOL := FALSE; LoadCounter : BOOL := FALSE; CountDownPulse : BOOL := FALSE; PartCount : INT; RemainingParts : INT; TotalParts : INT; BatchComplete : BOOL; BatchEmpty : BOOL; END_VAR // CTU - Counter Up UpCounter( CU := CountPulse, // Count up on rising edge R := ResetCounter, // Reset to 0 PV := 100 // Preset value (limit) ); PartCount := UpCounter.CV; // Current value BatchComplete := UpCounter.Q; // TRUE when CV >= PV // CTD - Counter Down DownCounter( CD := CountDownPulse, // Count down on rising edge LD := LoadCounter, // Load preset value PV := 50 // Preset value (start value) ); RemainingParts := DownCounter.CV; // Current value BatchEmpty := DownCounter.Q; // TRUE when CV <= 0 // CTUD - Counter Up/Down UpDownCounter( CU := CountPulse, // Count up input CD := CountDownPulse, // Count down input R := ResetCounter, // Reset to 0 LD := LoadCounter, // Load preset value PV := 200 // Preset value ); TotalParts := UpDownCounter.CV; // Current value // QU = TRUE when CV >= PV, QD = TRUE when CV <= 0
CTU - Count Up
Members:
- • CU: Count up input (BOOL)
- • R: Reset input (BOOL)
- • PV: Preset value (INT)
- • Q: Output (CV ≥ PV)
- • CV: Current value (INT)
CTD - Count Down
Members:
- • CD: Count down input (BOOL)
- • LD: Load input (BOOL)
- • PV: Preset value (INT)
- • Q: Output (CV ≤ 0)
- • CV: Current value (INT)
CTUD - Count Up/Down
Members:
- • CU: Count up input (BOOL)
- • CD: Count down input (BOOL)
- • R: Reset input (BOOL)
- • LD: Load input (BOOL)
- • PV: Preset value (INT)
- • QU: Up output (CV ≥ PV)
- • QD: Down output (CV ≤ 0)
- • CV: Current value (INT)
Edge Detection Function Blocks
Edge Detection Function Blocks (R_TRIG, F_TRIG)
VAR RisingEdge : R_TRIG; // Rising edge detection FallingEdge : F_TRIG; // Falling edge detection StartButton : BOOL := FALSE; StopButton : BOOL := FALSE; EmergencyStop : BOOL := TRUE; StartPulse : BOOL; StopPulse : BOOL; EmergencyPulse : BOOL; MotorRunning : BOOL := FALSE; // Edge trigger counters for diagnostics StartButtonPresses : INT := 0; EmergencyActivations : INT := 0; END_VAR // R_TRIG - Rising Edge Trigger // Output pulse on FALSE to TRUE transition RisingEdge(CLK := StartButton); StartPulse := RisingEdge.Q; // F_TRIG - Falling Edge Trigger // Output pulse on TRUE to FALSE transition FallingEdge(CLK := EmergencyStop); EmergencyPulse := FallingEdge.Q; // Application logic using edge detection IF StartPulse THEN MotorRunning := TRUE; StartButtonPresses := StartButtonPresses + 1; END_IF; IF StopButton OR EmergencyPulse THEN MotorRunning := FALSE; IF EmergencyPulse THEN EmergencyActivations := EmergencyActivations + 1; END_IF; END_IF;
R_TRIG - Rising Edge
Members:
- • CLK: Input signal (BOOL)
- • Q: Edge output (BOOL)
Q is TRUE for one scan when CLK changes from FALSE to TRUE.
F_TRIG - Falling Edge
Members:
- • CLK: Input signal (BOOL)
- • Q: Edge output (BOOL)
Q is TRUE for one scan when CLK changes from TRUE to FALSE.
Bistable Function Blocks
Bistable Function Blocks (RS, SR)
VAR SetResetLatch : RS; // Set dominant bistable ResetSetLatch : SR; // Reset dominant bistable SetSignal : BOOL := FALSE; ResetSignal : BOOL := FALSE; MotorEnabled : BOOL; AlarmLatch : BOOL; SystemReady : BOOL; MaintenanceMode : BOOL; END_VAR // RS - Set Reset Bistable (Set dominant) // If both S and R1 are TRUE, Q1 = TRUE (Set wins) SetResetLatch( S := SetSignal, // Set input R1 := ResetSignal // Reset input ); MotorEnabled := SetResetLatch.Q1; // SR - Set Reset Bistable (Reset dominant) // If both S1 and R are TRUE, Q1 = FALSE (Reset wins) ResetSetLatch( S1 := SetSignal, // Set input R := ResetSignal // Reset input ); SystemReady := ResetSetLatch.Q1; // Practical alarm latch example VAR AlarmRS : RS; OverTemperature : BOOL; AckButton : BOOL; AlarmAcknowledged : BOOL; END_VAR AlarmRS( S := OverTemperature, // Set on alarm condition R1 := AckButton // Reset when acknowledged ); AlarmLatch := AlarmRS.Q1; // Combined logic AlarmAcknowledged := AckButton AND AlarmLatch;
RS - Set Dominant
Members:
- • S: Set input (BOOL)
- • R1: Reset input (BOOL)
- • Q1: Output (BOOL)
When both S and R1 are TRUE, Q1 = TRUE (Set wins).
SR - Reset Dominant
Members:
- • S1: Set input (BOOL)
- • R: Reset input (BOOL)
- • Q1: Output (BOOL)
When both S1 and R are TRUE, Q1 = FALSE (Reset wins).
Practical Application Example
Complete Conveyor Control Example
PROGRAM ConveyorControl VAR // Inputs StartButton : BOOL; StopButton : BOOL; EmergencyStop : BOOL; PartSensor : BOOL; PhotoEye : BOOL; // Standard function blocks StartButtonEdge : R_TRIG; StopButtonEdge : R_TRIG; EStopEdge : F_TRIG; PartCounterEdge : R_TRIG; StartupTimer : TON; RunTimer : TON; PartCounter : CTU; SystemLatch : SR; // Outputs ConveyorMotor : BOOL; StatusLight : BOOL; AlarmBuzzer : BOOL; // Variables SystemRunning : BOOL; PartCount : INT; OperationTime : TIME; END_VAR // Edge detection for buttons StartButtonEdge(CLK := StartButton); StopButtonEdge(CLK := StopButton); EStopEdge(CLK := EmergencyStop); PartCounterEdge(CLK := PartSensor); // System control latch (Reset dominant for safety) SystemLatch( S1 := StartButtonEdge.Q, R := StopButtonEdge.Q OR EStopEdge.Q ); SystemRunning := SystemLatch.Q1; // Startup delay StartupTimer( IN := SystemRunning, PT := T#3s ); // Run timer for operation tracking RunTimer( IN := StartupTimer.Q, PT := T#999h // Long time for continuous operation ); OperationTime := RunTimer.ET; // Part counting PartCounter( CU := PartCounterEdge.Q, R := NOT SystemRunning, PV := 1000 ); PartCount := PartCounter.CV; // Output control ConveyorMotor := StartupTimer.Q AND NOT EmergencyStop; StatusLight := SystemRunning; AlarmBuzzer := EStopEdge.Q OR PartCounter.Q; END_PROGRAM
🚀 Key Benefits of Standard Function Blocks
- • Standardization: Consistent behavior across different PLC platforms
- • Reliability: Well-tested implementations with predictable timing
- • Efficiency: Optimized performance for real-time control systems
- • Maintainability: Familiar interfaces for all automation engineers
- • Safety: Proven components for safety-critical applications