der timer unter codesys läuft von 0 - 2 hoch 32 -1 das bedeutet von 0 bis 4,3 mrd sekunden oder 49,71 Tagen.
die funktion time() fragt diesen timer ab und gibt den wert seit start der sps zurück.
nach 49,71 tagen beginnt dieser wert wieder bei 0.
die funktion time() spielt eine wesentliche rolle für alle zeitabhängigen funktionen in der sps programmierung.
die prüfung größer kleiner gegen diesen timer wert sind nicht machbar weil es alle 49 tage uzu einem Überlauf kommt.
es gibt einen eleganten weg um das problem des überlaufs zu umgehen.
die differenz zwischen 2 zeitwerten ist immer richtig egal ob ein überlauf stattghefunden hat oder nicht.
in oscat verwenden wir deshalb immer die form tx := endwert - anfangswert.
dieses ergebnis stimmt immer egal ob überlauf oder nicht.
problematisch ist dieses vorgehen jedoch bei siemens. siemens läst den sps timer nicxht von 0 - 2 hoch 32 -1 laufen wie die iec61131 dies vorschreibt sondern hat folgende unterschiede.
der datentyp time läuft bei siemens von - 2 hoch 31 bis + 2 hoch 31 -1. der interne system timer aber nur von 0 - 2 hoch 31 -1.
dies hat zur folge das bei siemens der interne sps timer nur mit großer achtsamkeit benutzt werden kann.
bei siemens ist eben nicht sichergestellt das die differenz zweier werte stimmt.
es gibt dort eine überlaufthematik die bei codesys nicht besteht.
wir hoffen mit diesem thema etwas zur sicherheit von steuerungen beitragen zu können.
Um dieses Problem bei einer S7 Steuerung zu umgehen kann folgendes gemacht werden
tnow := TIME_TCK(); // Aktuelle Systemzeit lesen
tx := tnow - tlast; // Differenz aktueller und letzter Zyklus
IF tx < T#0ms THEN // Überlauf korrigieren
tx := tx + T#24D_20H_31M_23S_647MS;
END_IF;
tlast := tnow; // Aktuelle Systemzeit sichern = Altwert
oder
VAR_TEMP
// temporäre Variablen
tnow : TIME;
tx : TIME;
attx AT tx : ARRAY[0..31] OF BOOL;
END_VAR
VAR
// statische Variablen
tlast: TIME;
END_VAR
tnow := TIME_TCK(); // Aktuelle Systemzeit lesen
tx := tnow - tlast; // Differenz aktueller und letzter Zyklus
attx[7] := FALSE; // Vorzeichen killen
tlast := tnow; // Aktuelle Systemzeit sichern = Altwert
END_FUNCTION_BLOCK
tx ist somit immer die aktuelle Zykluslänge selbst bei einem Überlauf.
MfG
Daniel
die korrektur ist mir klar, nur muss ich sie in jedes einzelne modul einbauen, ich kann es nicht ausserhalb machen. das ist horrend testaufwand. jedes veränderte modul ein paar stunden und das ist extremer zeitverlust.
mir wird aber sicher noch eine intelligente lösung enfallen.