Überlauf mit einer Subtraktion bei DWORD berechnen

drfunfrock

Level-1
Beiträge
934
Reaktionspunkte
72
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich wollte die Zykluszeit berechnen und dazu mit ich TIME()-timestamp_letzter_zyklus berechnen. Nun sind das quasi 2 unsigned 32bit Werte. Ich könnte die auf LWORD erweitern um den Überlauf abzufangen, daher TIME()<timestamp_letzter_zyklus. Dann wäre das leicht, aber das will ich aus verschiedenen Gründen nicht.

Bei einem Überlauf bekomme ich eine Differenz, die eigentlich negativ wäre, aber nun bei 2^32-differenz landet. Wie bekomme ich das hin, ohne auf einen grösseren Datentyp zu konvertieren?

Meine letzte Idee war

(2^32-1)-differenz+1

PS: Oscat benutzt TIME() ständig, um die Scan-Time zu ermitteln, behandelt aber den Überlauf nicht. Sehr seltsam.
 
Zuletzt bearbeitet:
Hm, irgendwie sehe ich das Problem nicht. Im Extremfall wäre die neue Zeit um 1 kleiner als die alte, die Differenz wäre dann 16#FFFFFFFF. Passt doch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... oder sprechen wir hier nicht von TIME sondern statt dessen von Time_of_Day ... ?
In dem Fall nach der Subtraktion wenn der Wert negativ wird einfach 86400000 (Anzahl der Millisekunden pro Tag) draufaddieren ...

Gruß
Larry
 
TIME() liefert laut Doku die Zahl der Milisekunden seit Systemstart, sonst wäre es einfach den Überlauf zu behandeln.

Szenario ist folgendes :

T0 Jetztzeit
T1 Zeit vor einem Zyklus
Tmax = 2^32 - 1 (ms)

T0 = 2ms
T1=Tmax-4ms

Dann ergibt der Abstand 7 ms. Ich müsste eigentlich wenn T1>T0 ist

t = T0+(Tmax-T1+1ms) rechnen? Die 1ms kommt dazu, weil Tmax 1ms weniger als 2^32 ist. Ja, ich denke, das sollte es sein
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
..PS: Oscat benutzt TIME() ständig, um die Scan-Time zu ermitteln, behandelt aber den Überlauf nicht. Sehr seltsam.
Ist das immer noch so? Darauf hatte ich bereits 2007 hin gewiesen und hatte daraufhin sogar tel. Kontakt zu einem OSCAD-ler. In CoDeSys ist das mit dem TIME-TCK wohl etwas anders. Dort läuft die Zeit nach dem MAX-Wert ins Negative weiter und dadurch wieder zurück auf Null. In Step7 erfolgt nach dem MAX-Wert ein Sprung auf Null. Bei der Umsetzung der OSCAD-LIB auf Step7 ist das nicht beachtet worden, zumindest damals (2007) nicht.

Gruß, Onkel
 
Der S7 Systemtimer ist per Definition immer nur 31Bit.
Dies wurde wahrscheinlich so gewählt damit keine negativen Zeitwerte auftauchen.
Grund dafür ist meiner Ansicht nach, dass es in Step7 keine Vorzeichenlosen Vergleicher gibt.
Der 31 Bit Umstand bereitet aber trotzdem einige Schwierigkeiten

hier ein Beispiel zu korrekten Berechnung einer Zeitdifferenz zwischen 2
Aufrufen mit 31Bit.
Es wird zuerst auf 32Bit erweitert, dann die Subraktion ausgeführt,
das Vorzeichen angepasst (wegen Überlauf). Zum Schluß muss mit
SLD 1 das Ergebnis wieder auf 31Bit halbiert (korrigiert werden)

übrigens OSCAT verwendet mittlerweile auch eine extra Funktion, um
bei Step7 die Timer auf 32 Bit zu erweitern.

--------------------------------------------------------------------
CALL "TIME_TCK"
RET_VAL:=#aktSysTimer

L #aktSysTimer // aktuelle Systemzeit
SLD 1 // auf 32 Bit erweitern
L #memTime
SLD 1 // auf 32 Bit erweitern
-D
SPP save // Differnz muss positiv sein
NEGD
save: SRD 1 // 32 Bit berechnung wier auf 31 korrigieren

T #DiffTime // Zeitdifferenz

L #aktSysTimer // akuelle Systemzeit
T #memTime // als letzte Zeit speichern
--------------------------------------------------------------------

Ergebnis ist die Zeitdifferenz zwischen 2 Aufrufen in ms
 
Zurück
Oben