# Zeitmessung: GetSystemTime Berechnung



## wolfi999 (11 Februar 2011)

Hallo Leute,

Zuerst einmal ein großes Lob an das Forum.

Wenn ich den Baustein GetSystemTime verwende, bekomme ich 2 Werte (timeLoDW und timeHiDW) zurückgeliefert. Wie kann ich jetzt diese beiden Werte zu einer Zahl zusammen bringen, damit ich später diese einfacher in Sekunden umrechnen kann? 
Wieso ich das ganze brauche: Ich würde gerne eine "Stoppuhr" machen, d.h. ich hole mir bei einem Startimpuls den Wert mit GetSystemTime. wenn der Impuls erneut kommt, nehme ich mir die Zeit nochmals per GetSystemTime und bilde die Differenz. Diese würde ich dann gerne in Sekunden ausgeben.
Oder gibt es eventuell eine andere (besser) Möglichkeit dies zu machen?

Verwende einen CX1000. 

Vielen Dank für eure Hilfe
mfg
wolfi


----------



## winnman (11 Februar 2011)

Bau dir selber deinen "Timer":

in Merker oder DB ein INt.
Sekundentakt erhöhst du deinen INT.

Dann hast du gleich INT in Sek, . . .


----------



## wolfi999 (11 Februar 2011)

Hallo Winnmann,

Danke für die Antwort. 
Ich verstehe jedoch nur Bahnhof?

mfg
wolfi


----------



## Itus (11 Februar 2011)

Hallo

Dein Ansatz mit dem GETSYSTEMTIME ist richtig.

Start- und Stopzeiten erfassen, Differenz bilden (bei mir genügt es, wenn ich das timeLoDW auswerte).

Da der Baustein eine 100ns Auflösung hat, musst du nur noch umrechnen....

Wenns mir Recht ist: 10'0000'000 / (Stopzeit-Startzeit) sollte dann Sekunden geben....

Hoffe es hilft...

Gruss 
Itus


----------



## StructuredTrash (11 Februar 2011)

Nimm, je nach benötigtem Wertebereich, eine UINT- oder UDINT-Variable, die Du in jedem Programmzyklus um 1 hochzählst. Bei jeder Low-High-Flanke Deines Signals kopierst Du diesen Zähler in eine zweite Variable und setzt die Zählvariable wieder auf 0.


----------



## wolfi999 (11 Februar 2011)

Danke Leute.

Leider reicht mir die TimeLoDW nicht aus, benötige beide Werte (timeLoDW + timeHiDW). Wie kann ich diese beiden zusammenrechnen??


----------



## StructuredTrash (11 Februar 2011)

Wenn es denn unbedingt GetSystemTime sein muss:

Time:=TimeHiDW*2^32+TimeLoDW

Wobei Time natürlich eine Real-Variable ist. Den nötigen Typumwandlungs-Schnickschnack spare ich mir hier mal.


----------



## wolfi999 (8 August 2011)

Hallo,

Bei meinem letzten Projekt hat es funktioniert nur die timeLoDW zu verwenden. Nun benötige ich jedoch beide Werte (timeHiDW und timeLoDW). Wie kann ich diese beiden Werte zusammenfügen.

Oben wurde es schon kurz erklärt. Kann mir dies jedoch jemand ausführlicher erklären??

Oder gibt es denn keine andere Möglichkeit eine "Stoppuhr" zu programmieren??

Vielen Dank für eure Hilfe.

wolfgang


----------



## StructuredTrash (9 August 2011)

Also nochmal ausführlich:

Time:=UDINT_TO_LREAL(TimeHiDW)*4294967296.0+UDINT_TO_LREAL(TimeLoDW);


----------



## witkatz (9 August 2011)

In der TcUtilities.lib gibt es Funktionen zum Rechnen mit 64-bit Werten. Mit der Funktion UInt64Sub64 kann eine Differenz zweier 64-bit Werte berechnet werden. Mit UINT64_TO_LREAL
kann in LREAL gewandelt werden.


```
VAR
    ActSystemTime1: T_ULARGE_INTEGER ;
    ActSystemTime2: T_ULARGE_INTEGER ;
    UInt64TimeDif: T_ULARGE_INTEGER ;
    TimeDifSec: LREAL;
    bZeitmess: BOOL;
    fStartflanke: R_TRIG;
    fStopflanke: F_TRIG;
END_VAR
fStartflanke(CLK:= bZeitmess);
IF fStartflanke.Q THEN
    fbReadSystemTime(
        timeLoDW=> ActSystemTime1.dwLowPart,
        timeHiDW=> ActSystemTime1.dwHighPart);
END_IF
fStopflanke(CLK:= bZeitmess);
IF fStopflanke.Q THEN
    fbReadSystemTime(
        timeLoDW=> ActSystemTime2.dwLowPart,
        timeHiDW=> ActSystemTime2.dwHighPart);
    UInt64TimeDif:= UInt64Sub64(ActSystemTime2, ActSystemTime1);
    TimeDifSec:= UINT64_TO_LREAL(UInt64TimeDif) / LREAL#10000000;
END_IF
```
Gruß,
witkatz


----------



## assindia (16 Februar 2015)

Hallo Leute, 

ich habe im Forum mal gelesen und benutze auch den Block getsystemtime auf meinem cx9020. 
Ich möchte eine Zeitmessung für das Ansprechverhalten zweier Sensoren messen. 
jedoch habe ich in gewissen abständen ständig einen Rundungsfehler den ich nicht raus bekomme. -.- 
Da ist irgendwie der Wurm drin und ich bekomme ihn nicht heraus.


```
IF GetSysTimeIN2.timeHiDW > GetSysTimeIN1.timeHiDW THEN
        GetSysTimeINcom.timeLoDW := GetSysTimeIN2.timeLoDW - GetSysTimeIN1.timeLoDW;
        GetSysTimeINcom.timeHiDW := GetSysTimeIN2.timeHiDW - GetSysTimeIN1.timeHiDW;
        fTimeIN := (GetSysTimeINcom.timeHiDW*429496.7295) - (GetSysTimeINcom.timeLoDW/10000);        (*    time the sample needs to reach both sensors    *)
        fSpeedIN := SamplingVolumeIN.fGapSensors / fTimeIN;                                            (*    first speed of the sample    *)


    ELSIF GetSysTimeIN2.timeHiDW = GetSysTimeIN1.timeHiDW THEN
        GetSysTimeINcom.timeLoDW := GetSysTimeIN2.timeLoDW - GetSysTimeIN1.timeLoDW;
          fTimeIN := GetSysTimeINcom.timeLoDW/10000;                                                (*    time the sample needs to reach both sensors    *)
        fSpeedIN := SamplingVolumeIN.fGapSensors / fTimeIN;                                            (*    first speed of the sample    *)

    ELSE
            (*    ERROR    *)
        fTimeIN := 0;
        fSpeedIN := SamplingVolumeIN.fGapSensors / fTimeIN;
    END_IF;
```


Bei diesem Code habe ich für fTimeIN werte die um 1000ms liegen und teilweise kommt dann ein Wert mit 429398ms. 
Das Verwunderliche ist das ich diese Messung auch noch an zwei anderen stellen benutze und an einer Stelle tritt der selbe Fehler auf, bei der dritten bekomme ich teilweise werte die mit xxx.7295 enden und in meinem messbereich liegen. Sprich die Rundung von lowDW auf highDW funktioniert. 

kann mir jemand sagen ob dieser code richtig ist oder nicht? Dann muss ich den Fehler im System suchen.


----------



## StructuredTrash (16 Februar 2015)

Ich habe mir den Code nicht detailliert angeschaut, aber angesichts der Zykluszeiten würde eine Auflösung der Systemzeit von 1ms wohl ausreichen. Dazu gab es vor Kurzem einen interessanten Beitrag hier im Forum: TIME ist nicht nur ein Datentyp, sondern auch eine Funktion. TIME() liefert die Systemzeit im Format TIME, also 0..2^32-1 ms.


----------



## PN/DP (16 Februar 2015)

Deine 64-Bit-Subtraktion ist nicht korrekt: bei der Subtraktion der LoDW kann ein Übertrag entstehen, der bei der Subtraktion der HiDW verrechnet werden muß. Schau mal genau den Beitrag vor Deinem Beitrag.

Harald


----------



## assindia (16 Februar 2015)

Bedankt!!

Einfach mal richtig lesen :lol:


----------

