DATE_AND_TIME mit großen Zeiten aufaddieren

KingHelmer

Level-1
Beiträge
1.076
Reaktionspunkte
139
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich suche nach einer Möglichkeit, eine große Zeit (Anzahl von Zyklen eines Testlaufes (maximal 1 million) ) mit dem Mittelwert aller bisherigen Zyklen (um die 15,5 sekunden) multipliziert, auf eine DATE_AND_TIME Variable aufzuaddieren.

Da diese Zahl aber, in Millisekunden gesehen, um die 15,5 milliarden groß ist, habe ich zwei daraus reslutierenden Probleme:

1. Wie kann ich diese Zahl erfassen? DINT ist zu klein.
2. Wie kann ich die Zahl nacher addieren? DINT_TO_DT(DT_TO_DINT + DINT)? Aber hierfür wären die Zahlen zu groß.
Schlagt ihr eine Schleife vor?

Steht vieleicht gerade auf dem Schlauch.
Vieleicht versteht ihr das Problem auch nicht sofort.

Danke und Grüße,
Flo
 
Je nach Steuerungsystem ist DT ja unterschiedlich definiert bzw. aufgebaut.
Bei Twincat ist es ein Unix-Zeitstempel (Sekunden seit 01.01.1970) - die Millisekunden sind also uninteressant.

Wenn du deine Zeitdifferenz in TIME also in einen DINT wandelst, und durch 1000 teilst bevor du sie multiplizierst, dann sollte das Ergebniss auch wieder in einen DINT passen.
Wenn du dann den DINT-Wert zum DT addierst, dann sollte das richtige heraus kommen.

Evtl. müsstest du mit Pointern arbeiten, da die direkte Verechnung von DINT und DT vermutlich nicht funktioniert.


P.S.
Hab den Post nochmal editiert, da der Post von heute Nachmittag falsch war - hab mich da wohl bei den Millisekunden ein bisschen verrechnet ;)
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Tom,

danke für die Hilfestellung,
den Beitrag hatte ich noch gelesen :D Es werden so um die 180 Tage sein, die der Test läuft, keine 30 Jahre :ROFLMAO:

Hatt einen kleinen Denkhänger bei der Größe des DINT Datentyps. Geht ja bis Trilliarde :rolleyes:

Habe es mal grob probiert und es funktioniert fast.

Also merci schonmal!

Grüße,
Flo
 
So,

habs mal so gemacht, aber leider kommen sehr komische Dinge bei meinen DINTs raus.


Man achte oben auf die DINT-Werte. Rechne ich nach so kommen ganz andere Wert raus. Irgendwas verstehe ich hier noch nicht ganz. Vieleicht sieht einer meiner Fehler ja direkt.Unbenannt.jpg
 
Deine DINT-Variablen laufen über - die Werte sind doch zu gross.

Ein DINT hat einen Wertebereich von -2147483648 bis 2147483647

Bei deiner Rechnung hast du z.B. einen Zwischenwert von 2473594662.
Deshalb werden die Ergebnisse negativ.

Ein UDINT würde von 0 bis 4294967295 gehen.
Mit UDINT funktioniert es aber auch nicht - hab´s selber ausprobiert.
Nach der Division durch 1000 kommen auch wieder negative Werte heraus.

Mach die Berechnung mit REAL, wandle dann das REAL-Ergebniss wieder zum DINT das funktioniert.

P.S.
Hätte vorhin vermutlich mal einen Reset machen sollen.
Gerade nochmal probiert - wenn du die Berechnung mit UDINT machst anstelle DINT, dann funktioniert es auch. :smile:
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hatt einen kleinen Denkhänger bei der Größe des DINT Datentyps. Geht ja bis Trilliarde :rolleyes:
Wenn Du den DINT da mal nicht überschätzt. 2.147.483.647 sind bei mir nur Milliarden. Da hast Du bei der Multiplikation schon einen Überlauf.

Oh, zu spät.
Eine andere Möglichkeit wäre, nur mit Minutenauflösung zu rechnen und erst bei der Rückwandlung in DT die Werte wieder auf Sekunden zu bringen.
 
Zuletzt bearbeitet:
Hallo ihr beiden,

meine letzte Antwort wurde irgendwie nicht gesendet.
Das mit den Trilliarden hatte ich mal eben schnell gegoogelt und war der erste beitrag in einem Forum oder ähnlichem. Du wurde von 64 (bzw. 63) bit bei DINT gesprochen (war mir nicht sicher).
Da es aber 32(31) sind stimmt es natürlich, das die Zahlen zu groß waren.

Ich mach es jetzt so, dass ich die Zahl mit der Multipliziert wird durch 100 teile (dann habe ich z.B. 15456 ms =155) und dann erst mit den "Restzyklen" multipliziere. Dann liegt es auch im Wertebereich.

Das Datum der PLC hab ich dann noch eingestellt und siehe da, alles funst so wie es soll.

Code:
(* Umrechnungswert für ms in Zehntel-Sekunden *)

di_Current_Average_Cycle_Time_ms:= (di_Current_Average_Cycle_Time / 100) + (INT_TO_DINT(global_iTIME_WAIT_BEFORE_NEXT_CYCLE_DOOR1)/100);


dtActual_System_Time:=SysRtcGetTime(TRUE);
diActual_System_Time:= DT_TO_DINT(SysRtcGetTime(TRUE));

di_Remaining_Time_Goal1:= ((di_Ammount_Cycles_Goal1 - di_Current_Ammount_Cycles) * di_Current_Average_Cycle_Time_ms)/10;
dt_Estimated_Time_Goal1:= DINT_TO_DT(diActual_System_Time + di_Remaining_Time_Goal1);


di_Remaining_Time_Goal2:= ((di_Ammount_Cycles_Goal2 - di_Current_Ammount_Cycles) * di_Current_Average_Cycle_Time_ms)/10;
dt_Estimated_Time_Goal2:= DINT_TO_DT(diActual_System_Time + di_Remaining_Time_Goal2);


di_Remaining_Time_Goal3:= ((di_Ammount_Cycles_Goal3 - di_Current_Ammount_Cycles) * di_Current_Average_Cycle_Time_ms)/10;
dt_Estimated_Time_Goal3:= DINT_TO_DT(diActual_System_Time + di_Remaining_Time_Goal3);

Danke euch nochmal!

Grüße,
Flo

PS: Ist ein Dauerzyklustest einer Anlage, die mio Zyklen werden so ungefähr nächstes Jahr im Mai fertig sein ;)
 
Zuletzt bearbeitet:
Zurück
Oben