Reputation: 731
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 times
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
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
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