1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | METHOD PROTECTED BlockTimer VAR tuProtBlock: TU_PROT_BLOCK_INT; uiIdx: UINT; uiOffsetAutoReset: UINT; uiOffsetBlockTimer: UINT; END_VAR VAR_IN_OUT // iterate through all blocks uiOffsetAutoReset := DINT_TO_UINT(c_tsProt.diNBlock); uiOffsetBlockTimer := DINT_TO_UINT(c_tsProt.diNBlock)*2; FOR idx:= 1 TO c_tsProt.diNBlock DO uiIdx := DINT_TO_UINT(idx); // check for edge detection // this will trigger: // - auto reset timer // - occurrence timer IF tsProt.tuBlockEdge.ai[idx]<>0 AND _fbTimerArray.Count(uiIdx := uiIdx) <= c_tsProt.tuBlockProtSetting.ats[idx].uiOccurrence THEN _fbTimerArray.Append(uiIdx := uiIdx,lrData := _lrSysTime); END_IF // check if occurrence period timer's up _lrSysTime > _fbTimerArray.Get(uiIdx := uiIdx, uiPosition := 0) + c_tsProt.tuBlockProtSetting.ats[idx].lrTPeriod THEN _fbTimerArray.RemoveFirst(uiIdx := uiIdx); // B L O C K H A N D L I N G // check if number of occurrences exceeds limit // if so, set block signal IF tsProt.tuResetFaultBlock.ai[idx]=0 AND _fbTimerArray.Count(uiIdx := uiIdx+uiOffsetBlockTimer)<=0 THEN // start block timer by setting time stamp // check if block timer's up or if external reset signal occured // if so, reset block signal IF tsProt.tuResetFaultBlock.ai[idx]=0 AND // no fault (_tuResetBlock.ab[idx] OR // external reset signal _fbTimerArray.Append(uiIdx := uiIdx+uiOffsetAutoReset, lrData := _lrSysTime); // no autoreset when active block and negative definition _fbTimerArray.Count(uiIdx := uiIdx+uiOffsetAutoReset)>0 AND // auto reset count is bigger than 0 and timer's up tsProt.tuResetFaultBlock.ai[idx] := ABS(tsProt.tuResetFaultBlock.ai[idx]) * -1; ELSE o_tuBlockSettings.ai[idx] := UINT_TO_INT(_fbTimerArray.Count(uiIdx := uiIdx)); END_FOR // output block signal o_tsBlock := _tuBlock.ts; |