# Systemzeit auslesen



## Steff3de (26 November 2008)

Ich bekomme beim Auslesen der Systemzeit mit Hilfe des FB's NT-GetTime (TwinCat PLC Library: Utilities) die Fehler ID 1861 (timeout elapsed) zurück. Das ganze hat aber bis heute funktioniert. Hat jemand ne Ahnung wie ich den Fehler weiter eingrenzen kann bzw. was das Problem sein könnte?

Es handelt sich bei der SPS um eine TwinCat Version 2.10 (Build 1313) unter Windows XP.

Gruß
Stefan


----------



## Bührer (26 November 2008)

Hast du die Timeout Zeit am FB schon erhöht? 

Gruss
Thomas


----------



## Cerberus (26 November 2008)

Wäre auch mein erster Ansatz gewesen. Einfach mal schauen ob es mit einer höheren TimeOut-Zeit funzt.


----------



## Steff3de (26 November 2008)

Ich hab den Timeout mal von 3s auf 10s erhöht -> hat leider nichts gebracht


----------



## Bührer (26 November 2008)

```
FUNCTION_BLOCK FB_TimeDate
VAR_INPUT
    Enable:BOOL;
END_VAR
VAR_OUTPUT
    MachineTime: DATE_AND_TIME;
END_VAR
VAR
    ntGetTime: NT_GetTime;
    ntTime:TIMESTRUCT;
    GetTimeStart: BOOL;
    fbRTC:RTC;
    TriggerTON: TON;
    TriggerClock: BOOL;
    TimeBusy: BOOL;
    OldTimeBusy: BOOL;
    GetTimeError: BOOL;
    StartUp:BOOL:=TRUE;
    TriggerStart: BOOL;
END_VAR

-------------------------------------------------------------------

IF Enable=TRUE THEN

    TriggerClock:=FALSE;
    IF TimeBusy=FALSE AND OldTimeBusy=TRUE THEN
        TriggerClock:=TRUE;
        StartUp:=FALSE;
    END_IF;
    OldTimeBusy:=TimeBusy;

    TriggerTON(IN:= NOT TriggerClock , PT:= T#5m, Q=> TriggerStart);

    GetTimeStart:=FALSE;
    IF StartUp=TRUE OR TriggerStart=TRUE THEN
        GetTimeStart:=TRUE;
    END_IF;

    ntGetTime(
        NETID:='',
        START:=GetTimeStart,
        TMOUT:=T#10s,
        BUSY=> TimeBusy,
        ERR=> GetTimeError,
        ERRID=>,
        TIMESTR=> ntTime);

    fbRTC(
           EN :=TriggerClock,
            PDT:=SYSTEMTIME_TO_DT(ntTime),
           Q=>,
            CDT=>MachineTime);

END_IF;
```

Funktioniert dieser Code auf deinem System. Kannst du im Windows die Zeit verstellen? Ist der Fehler nur beim Start der PLC vorhanden oder auch später?


----------



## drfunfrock (26 November 2008)

Ich mache das so: 


```
clocktimer(PT:=t#200ms,IN:=NOT clocktimer.Q);

NT_Time(NETID:='',TMOUT:=t#100ms,START:=clocktimer.Q);
```
und dann 


```
timestamp :=  SYSTEMTIME_TO_DT(NT_Time.TIMESTR);
```


----------



## Bührer (26 November 2008)

Hallo drfunfrock

Machst du das auch auf Rechner mit kleiner Rechnungsleistung. Hast du keine Problem mit den Windows Zugriffen im 200ms Takt? Kein Jitter? Wenn du keine Problem hast ist deine Version viel einfach. Muss ich auch mal ausprobieren. 

Gruss
Thomas


----------



## Steff3de (26 November 2008)

Hallo Thomas

Die Systemzeit lässt sich am Rechner manuell nicht ändern, da der angemeldete Benutzer nicht über die entsprechenden Rechte verfügt.

Ich habe das Programm von drfunrock an der Maschine ausprobiert, allerdings habe ich den Trigger mal auf 500ms gesetzt -> Der Timeout-Fehler tritt nicht immer auf, d.h. ca. alle 3-5 Versuche bekomme ich die Systemzeit zurück.


----------



## drfunfrock (26 November 2008)

Bührer schrieb:


> Hallo drfunfrock
> 
> Machst du das auch auf Rechner mit kleiner Rechnungsleistung. Hast du keine Problem mit den Windows Zugriffen im 200ms Takt? Kein Jitter? Wenn du keine Problem hast ist deine Version viel einfach. Muss ich auch mal ausprobieren.
> 
> ...



Es funktioniert einfach. Der PC ist ein 4 Jahre alter, mit Pentium-D Prozessor (1.4GHz) Den Jitter hatte ich nie getestet. Die Zeit stimmt sekundengenau mit der Systemzeit überein.


----------



## drfunfrock (26 November 2008)

Steff3de schrieb:


> Hallo Thomas
> 
> Ich habe das Programm von drfunrock an der Maschine ausprobiert, allerdings habe ich den Trigger mal auf 500ms gesetzt -> Der Timeout-Fehler tritt nicht immer auf, d.h. ca. alle 3-5 Versuche bekomme ich die Systemzeit zurück.



Wie hoch ist die CPU-Auslastung?


----------



## Bührer (26 November 2008)

Hallo drfunfrock

Ok ein 1.4GHz Rechner ist ja schon recht stark. Der Putzt natürlich ziemlich alles weg. Bei mir muss es auch auf einem CX9001 laufen. (ARM 266MHz)

Falls ich mal Zeit habe versuche ich deine Variante auf einem CX9001

Gruss
Thomas


----------



## Steff3de (26 November 2008)

die CPU Auslastung liegt bei 17%


----------



## drfunfrock (26 November 2008)

Bührer schrieb:


> Hallo drfunfrock
> 
> Ok ein 1.4GHz Rechner ist ja schon recht stark. Der Putzt natürlich ziemlich alles weg. Bei mir muss es auch auf einem CX9001 laufen. (ARM 266MHz)



Upss, die Dinger sind ja wirklich nicht sehr leistungsstark. Ich habe die auch im Einsatz, aber mehr als 2 COM-Ports sind kaum drin. Ich vermute mal, dass die Kontextumschaltung zwischen Realtime zu WindowsCE ein Problem macht. Wie wäre es, die Abfrage der Uhrzeit in einen Thread mit der höchsten Priorität auszulagern?


----------



## Bührer (26 November 2008)

Steff3de schrieb:


> Hallo Thomas
> 
> Die Systemzeit lässt sich am Rechner manuell nicht ändern, da der angemeldete Benutzer nicht über die entsprechenden Rechte verfügt.
> 
> Ich habe das Programm von drfunrock an der Maschine ausprobiert, allerdings habe ich den Trigger mal auf 500ms gesetzt -> Der Timeout-Fehler tritt nicht immer auf, d.h. ca. alle 3-5 Versuche bekomme ich die Systemzeit zurück.



Ich hatte schon Probleme mit Beckhoff wären des Aufstarten, aber nicht währen des Betriebs.

Wenn du den TimeOut auf 1s und den Trigger auf 1.2s stellst wird es dann besser (3-5 Versuche) oder bleibt es gleich?


----------



## Bührer (26 November 2008)

Hallo drfunfrock

Mein Funktionblock funktioniert auf dem CX9001. Ich lese die Zeit nur alle 5minuten und gleiche damit die RTC im Twincat ab. Funktioniert gut. Braucht halt mehr Code. Der CX9001 ist nicht so schlecht, man muss halt aufpassen was und wie man programmiert. Bei mir läuft sogar eine Targetvisu, drei serielle Schnittstelle, Incremental Eingang Schrittmotor und mehrere Ein und Ausgänge.


----------



## Bührer (26 November 2008)

Hallo Steff3de

Hast du noch andere zylische aufrufe aufs Windows? Flash zugriffe? Was hast du für eine SPS/Rechner?

Gruss
Thomas


----------



## drfunfrock (26 November 2008)

Bührer schrieb:


> Hallo drfunfrock
> 
> Mein Funktionblock funktioniert auf dem CX9001. Ich lese die Zeit nur alle 5minuten und gleiche damit die RTC im Twincat ab. Funktioniert gut. Braucht halt mehr Code. Der CX9001 ist nicht so schlecht, man muss halt aufpassen was und wie man programmiert. Bei mir läuft sogar eine Targetvisu, drei serielle Schnittstelle, Incremental Eingang Schrittmotor und mehrere Ein und Ausgänge.



Ich habe mit der CX9010 bei 2 COM-Port (per Ethercat->KBus -Umsetzung an KL6001) schon eine Auslastung von 35% ohne den Rest, weil eben die FBs aus der Bibliothek alle 2ms ausgeführt werden müssen. Vielleicht habe ich einen Fehler im Kode?


----------



## Bührer (26 November 2008)

drfunfrock schrieb:


> Ich habe mit der CX9010 bei 2 COM-Port (per Ethercat->KBus -Umsetzung an KL6001) schon eine Auslastung von 35% ohne den Rest, weil eben die FBs aus der Bibliothek alle 2ms ausgeführt werden müssen. Vielleicht habe ich einen Fehler im Kode?



Ich hatte auch schon einen CX9010 aber ich konnte keine Geschwindigkeitsverbesserung zum CX9001 feststellen. Eigentlich sollte er doppelt so schnell sein. Ist er aber auf keinen Fall. Maximal ein paar Prozente. 

Ich habe einen 8ms und einen 16ms Task. Ich verwende nicht die Bibliothek von Beckhoff. Ich habe da eine eigene Lösung. 

ein 2ms Task ist zu viel für einen CX9001 4ms geht schon gut. 

Gruss
Thomas


----------



## drfunfrock (26 November 2008)

Ok, das erklärt einiges.


----------



## Steff3de (26 November 2008)

Die Änderung des Timouts auf 1 s und des Triggers auf 1,2 s brachte keine Veränderung. 

Der einzige Betriebssystemaufruf ist das Abspeichern der Daten in eine csv Datei. In diesem Zusammenhang wird auch die Systemzeit abgefragt und abgespeichert. Das ganze passiert mit jedem neuem Teilemagazin (ca. alle 2 Minuten)

Es handelt sich dabei um eine C6140


----------



## Bührer (26 November 2008)

alle 2min dann kann es keinen Zusammenhang damit haben. Da die Zeit alle 1.2s gelesen wird..

Früher ist es ja gegangen. Hast etwas geupdate? Hast du es schon auf einem anderen Rechner/SPS Probiert?


----------



## drfunfrock (27 November 2008)

Ich tippe mal darauf, dass die Zykluszeiten nicht eingehalten werden. Überprüfe das doch einmal im Systemmanager.


----------



## Steff3de (28 November 2008)

Hallo drfunfrock

Wie kann kann ich im Systemmanager prüfen ob es dabei zu Problemen kommt? (Ich habe die Funktion Auto-Start *nicht* aktiviert)

Gruß
Stefan


----------



## drfunfrock (28 November 2008)

Du musst einfach dein System in den Runmodus bringen und dann im Systemmanager bei geladener Konfiguration auf das SPS-Projekt gehen und dort auf die Task. Unter Online sind die Zeiten zu finden.


----------



## andr_gin (15 Juni 2010)

Ich bin vor kurzem bei TwinCAT auf das selbe Problem gestoßen, dass die Zeit manchmal nicht mehr aktualisiert wird. Im Normalfall sind es 3-5ms (Zykluszeit 1ms), aber manchmal hat es über 2 Sekunden gedauert.
Das ganze war kein Problem mit der Auslastung, sondern es scheint so, als würde ein laufender Timer das NT_Gettime blockieren. Immer wenn ich einen Timer in einem Funktionsblock gestartet habe (z.B. als Timeout), dann ist das busy bei NT_Gettime nicht mehr abgefallen.
Ich habe das jetzt so gelöst, dass ich die Zykluszeit als Konstante definiert habe und jeden Zyklus das Datum/Uhrzeit um eins hochzähle, damit meine Log Dateien wieder eine richtige aufsteigende Zeit haben (inkl. Millisekunden!!!). Das Gettime wird dann einmal in der Minute aufgerufen und die Zeit wird wieder synchronisiert z.B. wenn jemand gerade einen Breakpoint gesetzt hat oder es eine Zykluszeitüberschreitung gegeben hat.
Die Lösung reicht in meinem Fall aus, da es bei den Log Dateien egal ist, wenn die Uhrzeit auch einmal ein paar ms rückwärts zählt. Bei anderen Projekten kann das jedoch zu einem Problem werden.


----------



## Neals (15 Juni 2010)

Ich bevorzuge folgende Variante:

Mit FB_GetTimeZoneInformation die UTC-Zeitverschiebung auslesen.

Mit GETSYSTEMTIME und FILETIME_TO_SYSTEMTIME hole ich mir die aktuelle Zeit und addiere die UTC-Verschiebung drauf.


----------



## klaus1 (18 Dezember 2010)

Ich verwende folgendes auf dem CX9001:


```
VAR
    fbSystemTime     : GETSYSTEMTIME;
    timeAsFileTime    : T_FILETIME;
    _dt_Rtc             : DT;
END_VAR

fbSystemTime( timeLoDW =>timeAsFileTime.dwLowDateTime , timeHiDW =>timeAsFileTime.dwHighDateTime );
_dt_Rtc := FILETIME_TO_DT( timeAsFileTime );
```

Nur leider nimmt das die CPU ziemlich her... mir würde auch genügen alle paar Stunden mal abzugleichen, aber wenn ich GETSYSTEMTIME nicht konstant pro zyklus mache, habe ich nur die Uhrzeit/Datum der letzten abfrage...
Kann mir jemand sagen wie ich das hier lösen kann? Bzw. mit welchen Bausteinen? 
Danke, 
Klaus


----------



## Neals (20 Dezember 2010)

Also ich nutze diese Bausteine. Prüfe dann über den CycleCount, ob ein neuer Zyklus vorhanden ist und aktualisiere ggf. den Wert. Damit habe ich einmal pro Zyklus den Aufruf der Zeit.


----------



## klaus1 (20 Dezember 2010)

ich dachte das würde ohnehin mit meinem code nur 1x pro zyklus aufgerufen werden. Wozu prüfung zyklen? Verursacht bei mir +10% mehr cpu


----------



## Neals (20 Dezember 2010)

+10% durch eine einfache IF-Anweisung??

Da ich eine allgemeine Funktion geschrieben habe, welche mir die aktuelle Zeit als SystemTime liefert. Diese Funktion wird im Programm an vielen hunderten Stellen verwendet. Damit nicht jedes mal wieder der GetSystemTime aufgerufen wird, prüfe ich ob diesen Zyklus bereits die Zeit abgerufen wurde und gebe dann einen zwischengespeicherten Wert zurück. Das Auslesen vom CycleCount geschieht über die Struktur SYSTEMTASKINFOTYPE aus der TcSystem.lib.


----------



## klaus1 (20 Dezember 2010)

hab noch eine zweite stelle gehabt. Mit einer einzigen stelle sinds 4% mehr cpu auslastung.
Wäre es nicht sinnvoller alle stunde mal die zeit zu synchronisieren, da der twincat server ohnehin nur alle paar stunden abfragt am ntp.
Nur wie lasse ich die zeit weiter laufen ? Mit Ton?


----------



## Neals (20 Dezember 2010)

Oder einfacher: Mit TIME();

Achtung: Pseudocode!

```
IF bSync THEN
    tsSystemTime := F_SyncTime();
    tsOutput := tsSystemTime;
    tLastSync := TIME();
ELSE
    tsOutput := tsSystemTime + (TIME() - tLastSync);
END_IF
```


----------



## klaus1 (3 Oktober 2012)

Neals schrieb:


> Ich bevorzuge folgende Variante:
> 
> Mit FB_GetTimeZoneInformation die UTC-Zeitverschiebung auslesen.
> 
> Mit GETSYSTEMTIME und FILETIME_TO_SYSTEMTIME hole ich mir die aktuelle Zeit und addiere die UTC-Verschiebung drauf.


Könntest du mir ein Code snippet schicken?
Danke


----------

