In des OSCAT LIB gibt es auch einen Integrator:
https://github.com/simsum/oscat/blob/master/INTEGRATE.EXP
Code:
Code:
FUNCTION_BLOCK INTEGRATE
VAR_INPUT
E : BOOL := TRUE;
X : REAL;
K : REAL := 1.0;
END_VAR
VAR_IN_OUT
Y : REAL;
END_VAR
VAR
X_last : REAL;
init: BOOL;
last: DWORD;
tx: DWORD;
END_VAR
(*read system time *)
tx := T_PLC_MS();
IF NOT init THEN
init := TRUE;
X_last := X;
ELSIF E THEN
Y := (X + X_LAST) * 0.5E-3 * DWORD_TO_REAL(tx-last) * K + Y;
X_last := X;
END_IF;
last := tx;
END_FUNCTION_BLOCK
Die Systemzeit "tx" wird wie folgt wermittelt:
Code:
FUNCTION T_PLC_MS : DWORD
VAR CONSTANT
debug : BOOL := 0;
N : INT := 0;
offset : DWORD := 0;
END_VAR
VAR
tx : TIME;
END_VAR
(*
version 1.2 16. nov 2008
programmer hugo
tested by oscat
T_PLC_MS reads the internal PLC timer and return the time, it has the advantage to be able to set a debug mode
and speed up the counter to test the plc timer overrun which occurs every 50 days respectively 25 days at siemens S7
this routine also allows to correct the behavior of s7 where the internal plc counter will not count all 32 bits.
*)
(* @END_DECLARATION := '0' *)
tx := TIME();
T_PLC_MS := TIME_TO_DWORD(Tx);
(* hier muss die korrektur für step7 stattfinden
plctime muss den vollen wertebereich von time ausnutzen:
wenn bei step7 time -24tage bis plus 24 tage ist dann muss der timer auch beim Überlauf auf -24tage springen
und auf keinen fall auf 0 !!!!
für siemens muss ein weiterer fb im main eingebunden werden der sicherstellt das alle 32 bits durchgezählt werden.
es kann nur ein fb sein den er muss sich das oberste (32te) bit merken.
oder etwa spring s7 bei Überlauf auf -24 tage????? dann wäre keine korrektur nötig.
*)
IF debug THEN
T_PLC_MS := (SHL(T_PLC_MS,N) OR SHL(DWORD#1,N)-1) + OFFSET;
END_IF;
(* revision history
hm 14.9.2007 rev 1.0
original version
hm 12. nov 2007 rev 1.1
added temporaray variable tx because some compilers could not handle time() as an argument
hm 16. nov. 2008 rev 1.2
initialized constants with 0 for compatibility reasons
*)
END_FUNCTION
Erklärung aus dem Manual:
Im Normalbetrieb liest der Baustein mit der Funktion TIME() den internen
Timer der SPS aus und liefert diesen zurück. Der Interne Timer der SPS
nach IEC Norm hat 1 Millisekunde Aufösung.
Eine weitere Eigenschaft von T_PLC_MS ist ein Debug-Modus, der es er-
laubt den Überlauf des SPS internen Timers zu testen und die erstellte
Software entsprechend sicher zu verifzieren. Der interne Timer jeder SPS
hat unabhängig von Hersteller und Art der Implementierung nach einer
festen Zeit einen Überlauf. Das heißt, er läuft gegen FF..FFFF (höchster
Wert der im entsprechenden Typ gespeichert werden kann) und beginnt
dann wieder bei 000..0000. bei Standard SPS Timern beträgt diese Über-
laufzeit 2^32 -1 Millisekunden, was in etwa 49,71 Tagen entspricht. Da es
sich bei diesem Timer um einen in Hardware implementierten Timer han-
delt kann auch sein Anfangswert nicht gesetzt werden, sodass er nach
dem Einschalten der SPS immer bei 0 anfängt und bis zum Maximalwert
hoch läuft. Nach erreichen des Maximalwertes entsteht dann der berüch-
tigte Timer-Überlauf, der fatale Auswirkungen in der Anwendungssoftware
hervor ruft, aber nur extrem schwer getestet werden kann.
T_PLC_MS bietet mehrere Möglichkeiten zum Testen des Überlaufs und
zeitabhängiger Software. Mit der Konstante DEBUG kann der Test-Modus
eingeschaltet werden und dann mittels der Konstanten N und Ofset der
Timer ab einem bestimmten Wert beginnen, damit gezielt der Überlauf ge-
testet werden kann ohne die 49 Tage abzuwarten. Ofset legt hierbei den
Wert fest, der zum internen Timer addiert wird. Mit der Konstanten N wird
festgelegt, um wie viele Bits der interne Timer Wert nach links verschoben
wird und dabei die unteren N Bits mit 1 gefüllt werden. Mit N kann dadurch
die Geschwindigkeit des internen Timers um die Faktoren 2,4,8,16 usw. er-
höht werden.
T_PLC_US bietet also alle Möglichkeiten zum Test zeitabhängiger Software,
sowohl für die Problematik des Überlaufs, als auch für sehr langsame zeit-
abhängige Funktionen.
Die Konstanten DEBUG, N und OFFSET wurden absichtlich nicht als Eingän-
ge der Funktion implementiert um eine versehentliche Fehlbedienung zu
vermeiden.