How to use retentive option in timer in codesys v3.5?

arrvvii
2018-08-02
2018-08-06
  • arrvvii - 2018-08-02

    Hi all,
    I've trouble in making timer as retentive. Without retain option, timer value resets during power cycle/failure.

    I tried following methods to make a retentive timer.
    1. Made the boolean input of timer as retain. Timer restarts when the PLC is power cycled.
    2. Made the whole timer block as retain. Timer output turns high when the PLC is power cycled.
    3. Used both boolean input as well as the timer block as retain and checked.
    4. used a blink function and counter block and retained the counter value. It is not matching with real time. There is a significant delay in that timing.

    All the above failed. It is a very critical process so retentive option for timer is very much needed. Kindly help me to solve this.

    Thanks,
    Arvind

     
  • Lo5tNet - 2018-08-02

    Have you looked at the function block RTC. You can save the date and time as a retain and when powered back on it will start counting from where it left off.

     
  • josepmariarams - 2018-08-04

    Create an lreal as retain and increase it every cycle with the task cycletime.

    Sent from my Moto G (5S) Plus using Tapatalk

     
  • sjdebdaly - 2018-08-06

    Hi Arvind,

    I posted a reply on your GetSatisfaction query, but I figured it may be an idea to post my solution here too.

    The idea is to use a Standard.TOF, which is easier to restart part way through than a TON due to it counting down rather than up.

    As mentioned in my initial reply, this code has not been tested.

    FUNCTION_BLOCK RetentiveTimer
    VAR_INPUT
       xIn : BOOL;
       tTarget : TIME;
    END_VAR
    VAR_OUTPUT
       xDone : BOOL;
       tElapsed : TIME;
    END_VAR
    VAR
       _usiState : USINT; (* 0 = Initial/retentive power up, 1 = idle, 2 = running, 3 = done *)
       
       _fbTimer : Standard.TOF;   (* Use count down timer as it's easier to start over mid-way *)
    END_VAR
    VAR RETAIN
       _tElapsed : TIME;
       
       _xInProgress : BOOL;   (* Whether the timer is running *)
    END_VAR
    ============================================================
    (* Initial/retentive power up *)
    IF _usiState = 0 THEN
       
       (* This state should be only on first execution *)
       IF NOT _xInProgress THEN   
          _usiState := 1;
       (* Power interrupted, continue running *)
       ELSE 
          (* Update timer with last value *)
          _fbTimer.PT := _tElapsed;
          
          (* Go to running *)
          _usiState := 2;
       END_IF
    (* Idle state, waiting to start *)
    ELSIF _usiState = 1 THEN
       
       (* User triggered the timer - go *)
       IF xIn THEN
          _fbTimer.PT := tElapsed;
          _fbTimer.IN := TRUE;
          _xInProgress := TRUE;
          
          _usiState := 2;
       END_IF
    (* Running state *)
    ELSIF _usiState = 2 THEN
       
       (* User has cancelled the timer - back to idle *)
       IF NOT xIn THEN
          _fbTimer.IN := FALSE;
          
          _usiState := 1;
       
       (* Timer has completed - go to done *)
       ELSIF _fbTimer.Q THEN
          xDone := TRUE;
          
          _xInProgress := FALSE;
          _usiState := 3;
       END_IF
       
       (* Update retentive elapsed time *)
       _tElapsed := _fbTimer.ET;
    (* Done state *)
    ELSIF _usiState = 3 THEN
       
       (* Reset the timer *)
       _fbTimer.IN := FALSE;
       
       (* User has lowered the xIn pin *)
       IF NOT xIn THEN
          xDone := FALSE;
          
          _usiState := 1;
       END_IF
       
    ELSE
       (* Shouldn't get to this state - go to idle *)
       _usiState := 1;
    END_IF
    (* Execute the timer! *)
    _fbTimer();
    (* Calculate elapsed time as using TOF *)
    tElapsed := tTarget - _fbTimer.ET;
    
     

Log in to post a comment.