Patterns in PLC Programming: The threshold + timer function – Debounced Threshold
PLC programs are frequently made up of the same sets of functions or patterns of logic. These patterns perform commonly required control routines. Examples include threshold detection for alarm purposes, input/output mapping and scaling functions, to name a few. These combination of functions make up re-usable patterns or function sets that form the building blocks of a PLC program.
Repeated usage of some functions in a PLC programming environment holds true to the universal 80/20 rule ;20% of the functions available in a programming environment( such as timers and logic functions) would probably be used to build 80% of PLC programs.
The debounced alarm/threshold pattern is one of these commonly required PLC programming patterns. This pattern is probably better written in ladder diagram (instead of any of the other 61131-3 languages), for two reasons:
- Maintenance personnel will be able to view the status of the process/monitored variable, associated timer and output all in the same place
- It can be programmed in 2 rungs of ladder compared to more than 10 lines of code.
The ladder diagram version could look something like this:
Note: An Auto/Manual Reset Provision is built into the Alarm Reset Timer rung.
Alarm NOT ACTIVE
The following pattern is the debounce pattern for detecting limit breaches along with a timer, written in Structured Text for the CODESYS environment. As described above, the structured text version takes more space and possibly looks more intimidating specifically to someone who is used to the ladder environment.
The plain text version of the structured text version is attached below:
PROGRAM DeBounced_Limit
VAR
irProcessValue : REAL; (*Process value scaled from analog input signal*)
rProcessLowLimit : REAL; (*User defined process value low limit alarm threshold*)
qxLowLimitAlarm : BOOL;(*Low limit alarm bit*)
LowLimitAlarmTimer : TON; (*Process value low limit alarm trigger debounce timer*)
LowLimitAlarmResetTimer : TON; (*Process value low limit alarm reset debounce timer*)
LowLimitDebounceT : TIME; (*Process value low limit alarm trigger debounce time*)
LowLimitResetDebounceT : TIME; (*Process value low limit alarm reset debounce time*)
xAutoReset : BOOL;(*User enabled alarm auto reset function*)
ixUserReset : BOOL;(*User triggered alarm reset function for manual reset*)
END_VAR
(*If value is lower than low limit, start timer, else reset timer*)
IF irProcessValue < rProcessLowLimit THEN
LowLimitAlarmTimer(in:=TRUE, PT:=LowLimitDebounceT);
ELSE
LowLimitAlarmTimer(in:=FALSE);
END_IF
(*If timer lapses, trigger alarm bit*)
IF LowLimitAlarmTimer.Q THEN
qxLowLimitAlarm:=TRUE;
END_IF
(*If value is higher than low limit, start alarm reset timer, else reset debounce timer*)
IF irProcessValue > rProcessLowLimit THEN
LowLimitAlarmResetTimer(in:=TRUE, PT:=LowLimitResetDebounceT);
ELSE
LowLimitAlarmResetTimer(in:=FALSE);
END_IF
(*If timer lapses, and system permits auto-reset, reset alarm bit*)
(*If the system does not permit auto-reset, add user invoked reset bit here*)
IF LowLimitAlarmResetTimer.Q AND (xAutoReset OR ixUserReset) THEN
qxLowLimitAlarm:=FALSE;
END_IF