Timer Ãœberlauf

Begonnen von hugo, 24. Juli 2007, 11:30:53

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 4 Gäste betrachten dieses Thema.

hugo

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.

dalbi

#1
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

hugo

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.