在结构化文本中暂停计时器
Pausing Timers In Structured Text
我需要能够暂停计时器并在不再要求计时器 运行 时保留它的 ET
值。当来自接近开关的输入不存在时计时器计时,但我只希望它在 material 上转发的泵为 运行ning 时计时。泵可能只有 运行 30 秒,但 prox 开关可能需要 120 秒的泵送时间,因此在检测到任何 material 之前需要 4 运行 秒的泵.
如果有帮助,我正在使用 Codesys v2.3
到目前为止我有:
IF Motor AND NOT Proxy.P1 THEN (*If the motor is running and the proxy doesn't energise, then start that proxy's timer*)
Proxy.P1_Timer.IN:= TRUE;
ELSE
Proxy.P1_Timer.IN:=FALSE;
END_IF
但是上述情况会导致 ET
值在电机关闭时重置,而不仅仅是当 Proxy.P1
变为 TRUE
时。 ET
应仅在 Proxy.P1
设置为 TRUE
时重置
对此有何建议?我很惊讶 FB 上不仅有保留选项。
要暂停计时器,我会使用以下代码
rEdgeTrig(CLK:=startTimer);
IF rEdgeTrig.Q THEN
actualTime := actualTime - eTime;
END_IF;
(* TON timer *)
timer(IN:=startTimer,PT:=actualTime);
IF startTimer THEN
eTime := timer.ET;
END_IF;
if timer.Q then
acutalTime:=initialTime;
end_if;
当您的计时器不再被要求时 运行 然后将经过的时间加载到一个变量中。然后在你想重新开始的时候从预设时间减去。
这里是TON_Pausable.
TON_Pausable 的行为就像一个普通的 TON。此外 TON_Pausable 通过 PAUSE 输入暂停,暂停时 IN 必须保持为真。
FUNCTION_BLOCK TON_Pausable
VAR_INPUT
IN : BOOL;
PT : TIME;
PAUSE : BOOL;
END_VAR
VAR_OUTPUT
Q : BOOL;
ET : TIME;
END_VAR
VAR
rtPause : R_TRIG;
tTimePaused : TIME;
ton : TON;
END_VAR
IF NOT IN THEN
tTimePaused := T#0s;
END_IF
rtPause(CLK := PAUSE);
IF rtPause.Q THEN
tTimePaused := tTimePaused + ton.ET;
END_IF
ton(IN := IN AND NOT PAUSE, PT := PT - tTimePaused);
Q := ton.Q;
ET := tTimePaused + ton.ET;
这样逻辑就被封装和可重用了。
另一种方法是手动 increment/decrement 定时器变量,adding/subtracting 泵启动时每次扫描的扫描时间。
此功能可以隐藏在具有必要输入的功能块中。
一个简单的实现如下所示。
VAR
tRun: TIME;
bResetTimer: BOOL;
END_VAR
VAR_CONSTANT
T_SCAN := t#10ms;
END_VAR
IF Pump.run AND NOT Proximity.on THEN
tRun := tRun + tScan;
END_IF;
IF tRun >= t#120s THEN
; (* Do something *)
END_IF;
IF bResetTimer THEN
tRun := t#0s;
bResetTimer := FALSE;
END_IF;
另一种方式是在CASE OF中调用定时器,如果Case没有调用TON,会暂停,CASE中和CASE外时注意处理TON的进出
这是一个定时器,可以配置为:
- loop = FALSE 和 resetWhenOFF = TRUE | 像正常 TON 一样运行
- loop = FALSE 和 resetWhenOFF = FALSE | 关闭时暂停的 TON
- loop = TRUE 和 resetWhenOFF = FALSE | 达到timeLimit时带有上升沿输出的TON,之后,它会重置并重新开始(循环)
- loop = TRUE 和 resetWhenOFF = TRUE | 一个TON,当达到timeLimit时有一个上升沿输出,之后,它重置并重新开始(循环),并在OFF
时暂停
FUNCTION_BLOCK TIMER
VAR_INPUT
ON: BOOL;
reset: BOOL;
timeLimit: TIME;
loop: BOOL;
resetWhenOFF: BOOL;
END_VAR
VAR_OUTPUT
finished: BOOL;
elapsedTime: TIME;
remainingTime: TIME;
END_VAR
VAR
_TON_INST: TON;
_lastElapsedTime: TIME;
_onTrigger: F_TRIG;
_resetTrigger: R_TRIG;
_doReset: BOOL;
END_VAR
_onTrigger(CLK := ON);
IF (_onTrigger.Q) THEN
IF (resetWhenOFF) THEN
_lastElapsedTime := T#0MS;
_doReset := TRUE;
ELSE
_lastElapsedTime := _TON_INST.ET + _lastElapsedTime;
END_IF
END_IF
_resetTrigger(CLK := reset);
_TON_INST(IN := ON AND NOT (_resetTrigger.Q OR _doReset), PT := timeLimit - _lastElapsedTime);
finished := _TON_INST.Q;
elapsedTime := _TON_INST.ET + _lastElapsedTime;
remainingTime := _timeLimit - _lastElapsedTime - _TON_INST.ET;
IF (_TON_INST.Q AND _loop) THEN
_lastElapsedTime := T#0MS;
_doReset := TRUE;
END_IF
END_FUNCTION_BLOCK
我需要能够暂停计时器并在不再要求计时器 运行 时保留它的 ET
值。当来自接近开关的输入不存在时计时器计时,但我只希望它在 material 上转发的泵为 运行ning 时计时。泵可能只有 运行 30 秒,但 prox 开关可能需要 120 秒的泵送时间,因此在检测到任何 material 之前需要 4 运行 秒的泵.
如果有帮助,我正在使用 Codesys v2.3
到目前为止我有:
IF Motor AND NOT Proxy.P1 THEN (*If the motor is running and the proxy doesn't energise, then start that proxy's timer*)
Proxy.P1_Timer.IN:= TRUE;
ELSE
Proxy.P1_Timer.IN:=FALSE;
END_IF
但是上述情况会导致 ET
值在电机关闭时重置,而不仅仅是当 Proxy.P1
变为 TRUE
时。 ET
应仅在 Proxy.P1
设置为 TRUE
对此有何建议?我很惊讶 FB 上不仅有保留选项。
要暂停计时器,我会使用以下代码
rEdgeTrig(CLK:=startTimer);
IF rEdgeTrig.Q THEN
actualTime := actualTime - eTime;
END_IF;
(* TON timer *)
timer(IN:=startTimer,PT:=actualTime);
IF startTimer THEN
eTime := timer.ET;
END_IF;
if timer.Q then
acutalTime:=initialTime;
end_if;
当您的计时器不再被要求时 运行 然后将经过的时间加载到一个变量中。然后在你想重新开始的时候从预设时间减去。
这里是TON_Pausable.
TON_Pausable 的行为就像一个普通的 TON。此外 TON_Pausable 通过 PAUSE 输入暂停,暂停时 IN 必须保持为真。
FUNCTION_BLOCK TON_Pausable
VAR_INPUT
IN : BOOL;
PT : TIME;
PAUSE : BOOL;
END_VAR
VAR_OUTPUT
Q : BOOL;
ET : TIME;
END_VAR
VAR
rtPause : R_TRIG;
tTimePaused : TIME;
ton : TON;
END_VAR
IF NOT IN THEN
tTimePaused := T#0s;
END_IF
rtPause(CLK := PAUSE);
IF rtPause.Q THEN
tTimePaused := tTimePaused + ton.ET;
END_IF
ton(IN := IN AND NOT PAUSE, PT := PT - tTimePaused);
Q := ton.Q;
ET := tTimePaused + ton.ET;
这样逻辑就被封装和可重用了。
另一种方法是手动 increment/decrement 定时器变量,adding/subtracting 泵启动时每次扫描的扫描时间。
此功能可以隐藏在具有必要输入的功能块中。
一个简单的实现如下所示。
VAR
tRun: TIME;
bResetTimer: BOOL;
END_VAR
VAR_CONSTANT
T_SCAN := t#10ms;
END_VAR
IF Pump.run AND NOT Proximity.on THEN
tRun := tRun + tScan;
END_IF;
IF tRun >= t#120s THEN
; (* Do something *)
END_IF;
IF bResetTimer THEN
tRun := t#0s;
bResetTimer := FALSE;
END_IF;
另一种方式是在CASE OF中调用定时器,如果Case没有调用TON,会暂停,CASE中和CASE外时注意处理TON的进出
这是一个定时器,可以配置为:
- loop = FALSE 和 resetWhenOFF = TRUE | 像正常 TON 一样运行
- loop = FALSE 和 resetWhenOFF = FALSE | 关闭时暂停的 TON
- loop = TRUE 和 resetWhenOFF = FALSE | 达到timeLimit时带有上升沿输出的TON,之后,它会重置并重新开始(循环)
- loop = TRUE 和 resetWhenOFF = TRUE | 一个TON,当达到timeLimit时有一个上升沿输出,之后,它重置并重新开始(循环),并在OFF 时暂停
FUNCTION_BLOCK TIMER
VAR_INPUT
ON: BOOL;
reset: BOOL;
timeLimit: TIME;
loop: BOOL;
resetWhenOFF: BOOL;
END_VAR
VAR_OUTPUT
finished: BOOL;
elapsedTime: TIME;
remainingTime: TIME;
END_VAR
VAR
_TON_INST: TON;
_lastElapsedTime: TIME;
_onTrigger: F_TRIG;
_resetTrigger: R_TRIG;
_doReset: BOOL;
END_VAR
_onTrigger(CLK := ON);
IF (_onTrigger.Q) THEN
IF (resetWhenOFF) THEN
_lastElapsedTime := T#0MS;
_doReset := TRUE;
ELSE
_lastElapsedTime := _TON_INST.ET + _lastElapsedTime;
END_IF
END_IF
_resetTrigger(CLK := reset);
_TON_INST(IN := ON AND NOT (_resetTrigger.Q OR _doReset), PT := timeLimit - _lastElapsedTime);
finished := _TON_INST.Q;
elapsedTime := _TON_INST.ET + _lastElapsedTime;
remainingTime := _timeLimit - _lastElapsedTime - _TON_INST.ET;
IF (_TON_INST.Q AND _loop) THEN
_lastElapsedTime := T#0MS;
_doReset := TRUE;
END_IF
END_FUNCTION_BLOCK