Hallo Leute
Testbedingungen: CPU 314
Software: TIA12
a) warum der Baustein den Überlauf/Divison durch 0 oder sonst was für einen Fehler hat, kann man nach 1 Jahr Betrieb nicht mehr 100%tig rekonstruieren.
b) definitiv stürzt der Baustein bei einem solchen Fehler ab. Das bedeutet der Baustein geht bis in den Nimmerleinstag auf out 16#7FFFFFFF
Nach SEHR vielen Tests und viel Kopfzerbrechen verstehe ich wieso hierzu niemand antwortet:
Den Code "NAN" oder "16#7FFFFFFF" kann man mit herkömmlichen Mitteln nicht abfragen. Es soll zwar irgendwo ("ganz sicher") ein ENO Bit für eine fehlerhafte Berechnung gesetzt werden aber auf das wollte ich mich nicht verlassen (diese Funktion kann man evtl. sogar ein- bzw. ausschalten). Aber das ganze Zeugs mit dem (ENO-Bit, Ok-Bit, OV-Bit und VIELE Kostrukte mehr) funktioniert im TIA anders wie im STEP 7/5.5 und sowieso anders im KOP,AWL,SCL. Für die Abhandlung der Überläufe gibt es für jede Sprache,Software eigene Sonderlösungen
(der Support hat mir da auch nicht wirklich helfen können). ZUMINDEST BEI MIR HAT EIN DERARTIGER FEHLER NOCH NIE ZU EINER FEHLERMELDUNG IN DER SPS GEFÜHRT - "DIAGNOSE" IST SOMIT SINNLOS (ich bin bisher nur zufällig auf diese Fehler gestoßen - aber vielleicht weiß da jemand einen Trick - WÄRE SEHR DANKBAR).
Irgendwann habe ich dann mal erkannt, daß eine IF-Anweisung bei der auf eine solche Zahl abgefragt wird IMMER in den ELSE-Zweig rennt. Und genau hier liegt das Problem des FT-T1. Die Lösung ist ganz simpel:
(* read system time *)
#tx := "T_PLC_US"();
(* startup initialisation *)
IF #init AND #T <> t#0s AND #out<+3.402823e+38 AND #out>-3.402823e+38 THEN
#x1:=DWORD_TO_DINT(#tx) - DWORD_TO_DINT(#last);
#x2:=DINT_TO_REAL(DWORD_TO_DINT(#tx) - DWORD_TO_DINT(#last));
#x3:=(#in * #K - #out);
#x4:=(#in * #K - #out) * DINT_TO_REAL(DWORD_TO_DINT(#tx) - DWORD_TO_DINT(#last));
#x5:=DINT_TO_REAL(TIME_TO_DINT(#T)) * 1.0E-3;
#x6:=(#in * #K - #out) * DINT_TO_REAL(DWORD_TO_DINT(#tx) - DWORD_TO_DINT(#last)) / DINT_TO_REAL(TIME_TO_DINT(#T)) * 1.0E-3;
#out := #out + (#in * #K - #out) * DINT_TO_REAL(DWORD_TO_DINT(#tx) - DWORD_TO_DINT(#last)) / DINT_TO_REAL(TIME_TO_DINT(#T)) * 1.0E-3;
IF ABS(#out) < 1.0E-20 THEN #out := 0.0; END_IF;
ELSE
#init := TRUE;
#out := #K * #in;
END_IF;
#last := #tx;
(
+/- 3.402823e+38ist eigentlich irrelevant. Es reicht irgendeine Abfrage statt AND #out<+3.402823e+38 AND #out>-3.402823e+38 kann man auch richtigerweise AND #out=#out verwenden ... das sieht aber dann sehr suspekt aus!)
Für mich taucht nun noch ein weiteres Problem auf. Ich will natürlich nicht alle Funktionen der SIEMENS OSCAT nach Rekursionen durchschauen. Da werde ich nimmer fertig. Kann man in einem zukünftigen Release diese Problematik bei der S7 vielleicht berücksichtigen.