Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Working with timer Ton Tof

rtist
2017-06-13
2022-04-20
  • rtist - 2017-06-13

    After getting me nearly crazy and some days of my life lost, i finally found out how to work with timers. So i would like to share this for all of you who have the same trouble.

    First thing that drove me mad was, that after setting the timer to true "tmr(in:=true, pt:=t#5s)" sometimes it would not go on running.
    The reason is, that the timer has to be called constantly for the results to be updated.

    Therefor if you use SFC, you cant set a timer in one step and use the result in another step without calling the timer there.
    It works if you write "tmr();" in the active part of the step you want to use it in.
    so what i did was:
    Step1_entry: tmr(in:=false);
    Step1_active: tmr(in:=true,pt:=t#5s); (Or Step1_Exit if you want to start the timer on your exit transition)

    Step2_active: tmr();
    Transition Step2: tmr.q

    Actually, the timer keeps on running in the background, but as long as you dont call it using tmr(); it will not update the results. So you can set it true in one step, leave the step and call it in a much later step_active, where you need the result for the transition.

    The same problem occures if you set a timer in ST using an IF clause like this:

    IF var THEN tmr(in:=true, pt:=t#5s);
    END_IF

    IF tmr.q THEN do something; END_IF

    Now, as long as var is true, the timer will work, but if you set it to false somewhere else before the time is elapsed, the timer will stop updating because it is not called anymore.

    So, either you leave var:=true, or you can keep calling it like this:

    IF var THEN tmr(in:=true, pt:=t#5s);
    END_IF

    tmr();

    IF tmr.q THEN do something; END_IF

    The other thing that drove me crazy was, that i always have to set the tmr.in := false to reset the timer.

    What finally worked for me in SFC was to set it false on the entry part and to set it true in the active part. Like this i can use the same timer several times in one SFC and i have both commands close together, so i dont loose track of where i put it true and false.

    In ST i solved it this way:

    IF var THEN tmr(in:=true, pt:=t#5s); else tmr(in:=false);
    END_IF

    i hope this will help a bit.

    Now, this said, i would highly appreciate a timer that works like this:

    If you set the timer tmr(in:=true, pt:t#5s); anywhere in ST or SFC, the timer just starts running, no matter if it is called or not.
    Tmr.q is set to false and timer.ET is constantly updated. Also Tmr.in is set back to false by the timer (but the timer keeps on running!)
    Now if the timer reaches the pt, tmr.q is set to true.
    If somwhere in the program i set tmr.in to true again, no matter if time is elapsed or not, tmr.et is set back to 0 and the timer starts all over again.

    Like this i would not always have to set tmr.in to false or to explicitly call it in my program.

     
    • meerbarbe - 2020-03-09

      I have no words. Thank you very much for your time, you've just spared me hours and hours of trial and error.

       
      • dFx

        dFx - 2020-03-10

        In case you missed it, what the thread autor is discovering is the general behavior of any functionblock in automation (from codesys or other provider). To update a function block output, you have to call its instance.

         
        πŸ‘
        1
        • meerbarbe - 2020-03-10

          Since I'm completely new in this field, it shocks me how counterintuitive timers are. Thank you for the appreciation.

           
          • dFx

            dFx - 2020-03-13

            In automation, when you use a variable, you use a value. This value is never updated when you reads it.
            This behavior is due to how the code is executed at runtime. It is executed line by line, from the first one to the last one, and (in general) restart from the first.
            So for a timer (which is a function block updating some values), to get your outputs updated, you need to call the instance writing the outputs.

             
            πŸ‘
            1
  • teichhei - 2017-06-13

    In ST I usually call the timer with its PT somewhere close to where I use it and then just set and reset the input as needed. I don't use SFC because I still don't see the point. Something like

    tmr (pt:=t#500ms);

    if var then
    tmr.in := true;
    else
    tmr.in := false;
    end_if;

    Sent from my SM-G935F using Tapatalk

     
  • Joan M - 2017-06-13

    It's easier if you do this:

    tmr(in := var, PT := t#2s);

    if (tmr.q) ...

    Anyway, if you want to change the way the timer works, the best option you have is to implement it by yourself encapsulating the behavior in a specific home made function block.

    Timers and this kind of function blocks belong to the IEC standard... It doesn't seem they will change them.

    Good luck!

     
  • rtist - 2017-06-16

    I would guess, that your ways of doing this will work fine in ST, but especially the tmr(in:=var, pt:=t#5s) will probably not work in SFC if i change the var in some other step without calling the tmr.
    But in ST... nice, so thanks

    I use SFC because i dont like state machines too much. But after debugging my first SFC program i might get back to ST, as the clicking though steps was also quite annoying.

     
  • rtist - 2017-06-16

    teichhei hat geschrieben:
    In ST I usually call the timer with its PT somewhere close to where I use it and then just set and reset the input as needed. I don't use SFC because I still don't see the point. Something like
    tmr (pt:=t#500ms);
    if var then
    tmr.in := true;
    else
    tmr.in := false;
    end_if;
    Sent from my SM-G935F using Tapatalk

    I guess, the timer will then only start to work in the next cycle when the function is called again, and not right when you set tmr.in:= true; .?

     
  • Joan M - 2017-06-16

    Yes... in your example timer will start counting in the next cycle.

    Enviat des del meu SM-G930F usant Tapatalk

     
  • teichhei - 2017-06-16

    That is true in this case but if the cycle time or output state becomes relevant in the same cycle you can turn it around and do the cyclic call just after you've handled the input.

    Sent from my SM-G935F using Tapatalk

     
  • Anonymous - 2017-06-16

    Originally created by: scott_cunningham

    If you want to timer to always run in any part of an SFC code, put the timer in a separate task and define it as a global variable. The new timer is available anywhere in your project, and the separate task is always called thus updating the ET values.

    The timer is nothing but a piece of code with the small state machine inside. If you do not call the timer function black, the code is not updated.

     
  • hermsen

    hermsen - 2017-06-16

    If cycle-time becomes relevant you should steer away from a standard timer! IN THE near future we can use nifty timers and triggers from the new "Common Behaviour Model Library'. The timers/triggers in that library will definatly help out better!

     

Log in to post a comment.