Ho realizzato un blocco funzione che realizza quello di cui hai bisogno. In pratica occorre passare alla FB in ingresso 3 parametri:
Value (REAL): Valore di temperatura acquisito in tempo reale.
Threshold (REAL): Valore di deviazione assoluto oltre al quale si genera l’evento.
ECount (USINT): Numero di errori successivi oltre al quale si genera l’evento.
In uscita la FB ha un parametro:
EventOut (BOOL): Attivo se variazione superiore alla soglia per il numero di errori definito.
Ecco il sorgente del blocco funzione.
FUNCTION_BLOCK Variance
VAR_INPUT
Value : REAL; { DE:”Value to be controlled” }
Threshold : REAL; { DE:”Valore soglia” }
ECount : USINT; { DE:”Event count” }
END_VAR
VAR_OUTPUT
EventOut : BOOL; { DE:”Event out” }
END_VAR
VAR_EXTERNAL
SysDateTime : UDINT; { DE:”System Date/Time” }
END_VAR
VAR
Storage : ARRAY[ 0..23 ] OF REAL; { DE:”Salvataggio valori” }
TimeToDate : SysETimeToDate; { DE:”Time to date conversion” }
SaveHour : USINT; { DE:”Salvataggio ora” }
ECtr : USINT; { DE:”Event counter” }
END_VAR
{ CODE:ST }
TimeToDate(EpochTime:=SysDateTime); (* Calcolo data e ora *)
IF (TimeToDate.Hour > 23) THEN RETURN; END_IF;
IF (TimeToDate.Hour = SaveHour) THEN RETURN; END_IF;
(* Arrivo se variazione ora, eseguo confronti. *)
SaveHour:=TimeToDate.Hour; (* Salvataggio ora *)
(* Controllo se rispetto al valore di 24 ore precedenti c’è variazione. *)
IF (ABS(Storage[TimeToDate.Hour]-Value) <= Threshold) THEN
EventOut:=FALSE; (* Event out *)
ECtr:=0; (* Event counter *)
ELSE
(* Eseguo controllo se valore maggiore per nr confronti. *)
IF NOT(EventOut) THEN
ECtr:=ECtr+1; (* Event counter *)
IF (ECtr > ECount) THEN EventOut:=TRUE; END_IF;
END_IF;
END_IF;
(* Eseguo salvataggio valore attuale in storage. *)
Storage[TimeToDate.Hour]:=Value; (* Salvataggio valori *)
Attenzione! Siccome il blocco funzione salva al suo interno in un array i dati storici delle 24 ore precedenti, và allocato in memoria RETAIN. Allego un programma di esempio.