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 <= 0CTU - 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
