Hallo Benedikt,
in
CoDeSys nutze ich ausschließllich die Systemfunktion "TIME()" um Zeitstempel zu erzeugen. Diese Zeit läuft nach dem Einschalten der Steuerung automatisch los und bietet tolle Möglichkeiten im Vergleich zu Timern wie TON, TOF, etc.
Bei der S7 geht das auch in SCL. Da habe ich die auch schon verwendet.
Ärgerlich an den TON,.. Bausteinen finde ich, dass das diese per Eingang gestartet werden müssen vor einer erneuten Nutzung muss erst eine neue Flanke erzeugt werden. Das macht die Programmierung fehleranfällig. Mit "TIME()" hast du hier keine Probleme.
Eine Laufzeitüberwachung könntest du elegant in einer Schrittkette umsetzten im ST:
CASE nState OF
0: IF FahreInGS THEN
VentilGS := TRUE;
TimeStamp := TIME();
nState := 10;
END_IF;
10: IF EnschalterGS THEN (* alles paletti Endschalter ist gekommen *)
;(* weitere Aktion einfügen... *)
ELSIF TIME() > TimeStamp + t#1s THEN (* Timeout/Laufzeitüberwachung hat angeschlagen *)
nState := 1000 + nState; (* Sprung zur Fehlerbehandlung usw. *)
END_IF;
1000..1999:
wErrorID := nState - 1000; (* die Fehlerid ist also immer der Schritt in dem der Fehler auftrat. Falls in einem Schritt mehrere Fehler auftreten kannst du auch nState := 1000 + nState + 1 usw. einfügen. Wichtig ist, dass du immer in 10er Schritten alles aufbaust damit der Bezug später bei der Fehlerbehandlung klar ist. *)
; (* Implementiere Fehlerhandling *)
END_CASE;
So setzte ich immer meine Schrittketten um. Falls du viele Laufzeitüberwachungen, also quasi fast jeden Schritt mit einem Timeout überwachen willst würde ich folgendes Konstrukt vorschlagen:
VAR
tTimeOut : TIME;
END_VAR
VAR CONSTANT
tDefaultTimeout : TIME := t#5s;
tDisarmTimeout: TIME := t#0s;
END_VAR
IF nState < 1000 AND tTimeout <> tDisarmTimeout AND TIME() > tTimeout THEN
nState := 1000 + nState + 1; (* 10er Schritt + 1 ist dann immer automatisch ein Timeout *)
END_IF;
CASE nState OF
0: tTimeout := tDisarmTimeout; (* Wenn du auf ein Startsignal wartest muss natürlich die Überwachung deaktiviert werden!*)
IF FahreInGS THEN
VentilGS := TRUE;
tTimeout := TIME() + tDefaultTimeout; (* Überwachung "aufziehen" *)
nState := 10;
END_IF;
10: IF EnschalterGS THEN (* alles paletti Endschalter ist gekommen *)
;(* weitere Aktion einfügen... *)
END_IF;
(* ELSIF Zweig entfällt da nun automatisch außerhalb der Schrittkette ein Schritt überwacht wird und ensprechend in den Bereich > 1000 gesprungen wird *)
1000..1999:
wErrorID := nState - 1000; (* die Fehlerid ist also immer der Schritt in dem der Fehler auftrat. Falls in einem Schritt mehrere Fehler auftreten kannst du auch nState := 1000 + nState + 1 usw. einfügen. Wichtig ist, dass du immer in 10er Schritten alles aufbaust damit der Bezug später bei der Fehlerbehandlung klar ist. *)
; (* Implementiere Fehlerhandling *)
END_CASE;
Gibts hier auch eine "CODE" Funktion? Sieht so ja scheusslich aus!