如何确定给定持续时间内事件的最大第 n 次发生?
How to determine the maximum nth occurrence of an event at a given duration?
如何判断一个事件的第n次事件的时间间隔不超过一定时间?
例如,一个事件最多可以发生 5 times
every 10 minutes
.
在STL中我们可以使用这个
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
此方法似乎不是实现所需的最佳方法。
还有其他最优方法吗?
如有任何帮助,我们将不胜感激。
很遗憾,我无法准确理解您要完成的任务。如果我的回答没有给出您的想法,请更新您的问题并说明您想要做什么。
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
这是一个示例,如何将最后 5 个事件存储在数组中,然后如何知道当前事件太长以及如何在数组中找到最长的事件。
终于找到了解决这个问题的方法:
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
似乎有效(已针对 tDuration:TIME:=T#10s;
进行测试)
如何判断一个事件的第n次事件的时间间隔不超过一定时间?
例如,一个事件最多可以发生 5 times
every 10 minutes
.
在STL中我们可以使用这个
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
此方法似乎不是实现所需的最佳方法。 还有其他最优方法吗?
如有任何帮助,我们将不胜感激。
很遗憾,我无法准确理解您要完成的任务。如果我的回答没有给出您的想法,请更新您的问题并说明您想要做什么。
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
这是一个示例,如何将最后 5 个事件存储在数组中,然后如何知道当前事件太长以及如何在数组中找到最长的事件。
终于找到了解决这个问题的方法:
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
似乎有效(已针对 tDuration:TIME:=T#10s;
进行测试)