3

ET当不再要求计时器运行时,我需要能够暂停计时器并保留它的值。当接近开关的输入不存在时,计时器会计时,但我只希望它在推进材料的泵运行时计时。泵可能只运行 30 秒,但 prox 开关可能需要 120 秒的泵送时间,因此需要运行 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变为TRUEET应仅在设置Proxy.P1为时重置TRUE

对此有何建议?令我惊讶的是,FB 上不仅有保留选项。

4

5 回答 5

4

这是一个 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;

通过这种方式,逻辑被封装并且可重用。

于 2015-12-11T08:34:43.340 回答
2

要暂停计时器,我将使用以下代码

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;

当您的计时器不再被要求运行时,将经过的时间加载到变量中。然后从您想要重新开始的预设时间中减去。

于 2015-12-10T14:36:01.980 回答
2

另一种方式是在CASE OF中调用定时器,如果CASE没有调用TON,则会暂停,注意在CASE中和CASE外时处理TON的进出

于 2016-05-09T13:31:26.147 回答
0

另一种方法是手动增加/减少计时器变量,在泵启动时在每次扫描时增加/减少扫描时间。此功能可以隐藏在具有必要输入的功能块中。
一个简单的实现如下所示。

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;
于 2015-12-15T21:25:22.727 回答
0

这是一个定时器,可以配置为:

  • 循环 = FALSE 和 resetWhenOFF = TRUE | 像普通 TON 一样运行
  • loop = FALSE 和 resetWhenOFF = FALSE | 关闭时暂停的 TON
  • loop = TRUE 和 resetWhenOFF = FALSE | 达到 timeLimit 时具有上升沿输出的 TON,之后,它重置并重新开始(循环)
  • loop = TRUE 和 resetWhenOFF = TRUE | 达到 timeLimit 时具有上升沿输出的 TON,之后,它重置并重新开始(循环),并在 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
于 2020-06-03T14:11:46.373 回答