Timer 在结构化文本中暂停计时器

Timer 在结构化文本中暂停计时器,timer,plc,st,codesys,structured-text,Timer,Plc,St,Codesys,Structured Text,当计时器不再被要求运行时,我需要能够暂停计时器并保留其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, the

当计时器不再被要求运行时,我需要能够暂停计时器并保留其
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
变为
TRUE
时。只有当
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一样。此外,TON_Pausable通过暂停输入暂停,暂停时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


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

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

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;

另一种方法是在以下情况下调用计时器:如果案例未调用TON,则计时器将暂停,小心处理输入和输出TON当案例和输出TON时这里有一个计时器,可配置为:

  • loop=FALSE和resetWhenOFF=TRUE |运行方式与正常情况类似
  • loop=FALSE和resetWhenOFF=FALSE |关闭时暂停的一吨
  • loop=TRUE和resetWhenOFF=FALSE |达到时间限制时具有上升沿输出的一吨,之后重置并重新开始(循环)
  • loop=TRUE和resetWhenOFF=TRUE |达到时间限制时,一吨具有上升沿输出,之后,它重置并重新开始(循环),关闭时暂停

什么将
实际时间
重置回其原始值?其他一切似乎都是我想要的!谢谢,我刚刚完成调整,以适应我的应用程序,并作出了类似的编辑。我需要它来记住泵何时停止,所以我将触发器更改为在泵关闭而不是打开时发生。但是逻辑是正确的。当你不调用计时器时,ET将保持静止,当你调用它时,它将跳到如果你一直调用它的时间。这是因为,我相信,TON timer在每一步都使用系统时间来计算ET,这意味着如果你停止调用它5分钟,那么一旦你再次调用它,系统时间将改变5分钟,导致ET增加5分钟,而不是一秒钟
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;
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