Search code examples
twincatstiec61131-3

How to determine the maximum nth occurrence of an event at a given duration?


How can it be determined that the time interval of the nth event of an event is not more than a certain period of time? For example, an event can occur up to ‍5 ti‍mes every 10 minutes.

In STL we can use this

VAR
    counter:CTU;
    timer:TON;
    Event:BOOL;
    bMaxEventHappend:BOOL;
    tElapsedTime:TIME;
END_VAR


counter(CU:=Event);
IF counter.CV=1 THEN
    timer(IN:=TRUE);
END_IF
IF counter.CV=5 THEN
    bMaxEventHappend:=TRUE;
    counter(Reset:=TRUE);
END_IF

//resetProcess
IF counter.CV=1 AND timer.et>=T#10M THEN
    timer(IN:=FALSE);
    counter(Reset:=TRUE);
ELSIF counter.CV=2 THEN
    tElapsedTime:=timer.et;
    IF timer.ET-tElapsedTime >=T#10M THEN
       timer(IN:=FALSE);
       counter(Reset:=TRUE);
    END_IF
ELSIF counter.CV=3 THEN
    tElapsedTime:=tElapsedTime+timer.et;
    IF timer.ET-tElapsedTime >=T#10M THEN
       timer(IN:=FALSE);
       counter(Reset:=TRUE);
    END_IF
ELSIF counter.CV=4 THEN
    tElapsedTime:=tElapsedTime+timer.et;
    IF timer.ET-tElapsedTime >=T#10M THEN
       timer(IN:=FALSE);
       counter(Reset:=TRUE);
    END_IF
ELSIF counter.CV=5 THEN
    tElapsedTime:=tElapsedTime+timer.et;
    IF timer.ET-tElapsedTime >=T#10M THEN
       timer(IN:=FALSE);
       counter(Reset:=TRUE);
    END_IF
END_IF

This method does not seem to be optimal for achieving the desired. Is there another optimal method?

Any help would be appreciated.


Solution

  • Finally, I found this method for this problem:

    PROGRAM MAIN
    VAR
        trigger:r_Trig();
        event: BOOL;
        tDuration:TIME:=T#10M;
        tTimeInit: TIME:=TIME()-tDuration;
        aTime:ARRAY[1..5] OF TIME:=[tTimeInit,tTimeInit,tTimeInit,tTimeInit,tTimeInit];
        alarm:BOOL;
        i:INT;
    END_VAR
    
    
    trigger(clk:=event);
    IF trigger.Q THEN
        IF (TIME()-aTime[i+1]<tDuration) THEN
            alarm:=TRUE;
        END_IF
        aTime[i+1]:=TIME();
        i:=(i+1) MOD 5;
    END_IF
    

    and seems it works(have been tested for tDuration:TIME:=T#10s;)