asys
asys

Reputation: 731

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.

Upvotes: 2

Views: 91

Answers (2)

asys
asys

Reputation: 731

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;)

Upvotes: 0

Sergey Romanov
Sergey Romanov

Reputation: 3080

Unfortunately, I was not able to understand what you are trying to accomplish exactly. If my answer does not give your ideas, just update your question and explain what you want to do.

TYPE MY_EVENT : STRUCT
        TimeStart : TIME; (* Time when event was started *)
        TimeEnd : TIME; (* Time when event was ended *)
        TimeWorked: TIME; (* Time that event was working *)
        Index: USINT; (* Index in array *)
    END_STRUCT
END_TYPE

PROGRAM PLC_PRG
    VAR
        arEvents: ARARY[1..5] OF MY_EVENTS; (* Last 5 events *)
        xEventStart: BOOL; (* Event started *)
        xEventStartM: BOOL; (* Memmory of event started for edge detection *)
        stEvent: MY_EVENT; (* Current event *)
        usiCount: USINT := 1; (* Current index *)
        usiFor: USINT := 1; (* FOR iterator *)
        stSearchEvent: MY_EVENT; (* Searched event *)
    END_VAR

    (* Raising edge of event. Event starts *)
    IF xEventStart AND NOT xEventStartM THEN
        stEvent.TimeStart := TIME();
    END_IF;
    
    (* Falling edge of event. Event ends *)
    IF NOT xEventStart AND xEventStartM THEN
        (* Finalize event *)
        stEvent.TimeEnd := TIME();
        stEvent.Index := usiCount;
        stEvent.TimeWorked := (stEvent.TimeEnd - stEvent.TimeStart);
        
        (* Save event in array *)
        arEvents[usiCount] := stEvent;

        IF usiCount = 5 THEN
            usiCount := 1;
        ELSE
            usiCount := usiCount + 1;
        END_IF;

        stEvent.TimeEnd    := T#0S;
        stEvent.TimeStart  := T#0S;
        stEvent.TimeWorked := T#0S;
    END_IF;
    xEventStartM := xEventStart;

    (* Current event is longer than 1 minute *)
    IF (TIME() - stEvent.TimeStart) > T#1M THEN
        // Do something
    END_IF;

    (* Get longest event out of last 5 events *)
    stSearchEvent.TimeWorked := T#0S;
    FOR usiFor TO 5 DO
        IF (stSearchEvent.TimeWorked < arEvents[usiFor].TimeWorked) THEN
            stSearchEvent := arEvents[usiFor];
        END_IF;
    END_FOR;
END_PROGRAM

This is an example how to store last 5 events in array and then how to know that current event is too long and how to find longest event in array.

Upvotes: 1

Related Questions