Hallo nochmal,
das DT-Format bei
Codesys bzw. Twincat entspricht
Sekunden seit dem 01.01.1970 und nicht Millisekunden - ich habs jetzt ausgebessert.
Somit entspricht dieses Format der
Unixzeit. Wobei Codesys keine negativen Werte und somit keine Datumsangaben vor dem 01.01.1970 kennt - dafür reichen dann aber die 32-Bit bis zum 06.02.2106 wärend bei der normalen vorzeichenbehafteten 32-Bit Unixzeit am 19.01.2038 Schluss ist -
Jahr 2038 Problem.
Bzgl. der Umwandlung des S7-Zeitstempels (8-Byte) zum 4-Byte Unix-Zeitstempel gibt´s hier im Forum bereits eine Lösungsmöglichkeit
von argv_user
Link. Wenn du diesen, so in Step7 erzeugten Zeitstempel, jetzt einer Beckhoff vorsetzt, dann hast du allerdings derzeit eine Differenz von 2 Stunden, da die Unixzeit von
UTC ausgeht und wir ja derzeit Sommerzeit (UTC+2) haben.
Die Retour-Funktion also Unix-Zeitstempel nach S7-Zeitstempel wandeln funktioniert in Anlehung an den Code von argv_user ähnlich - Rechnung rückwärts.
In der Step7 Variante der Ocat-Lib findest du diesbezgl. im Ordner xxS7 auch die Funktionen FC399 und FC400 (DT_DINT und DINT_DT) - die sollten dir auch weiterhelfen.
Du könntest natürlich auch auf der Beckhoff-Seite den Siemens Date_and_Time Datentyp nachbilden, dann musst du aber jeweils 8-Byte von Beckhoff zu Siemens übertragen. Somit ist es vermutlich effizienter wenn du die 4-Byte DT´s von Beckhoff in die S7 überträgst und dort umrechnest.
Evtl. (kenn mich mit WinCC jetzt nicht so aus) - unterstützt WinCC auch direkt den Unix-Zeitstempel von Beckhoff. WinCCflexible kann es nicht - vielleicht kann es aber das grosse WinCC.
Wenn du dennoch deine Zeitstempel gleich auf der Beckhoff-Seite in S7-kompatible Zeitstempel umwandeln willst, dann hilft dir vielleicht folgender FC weiter:
Code:
FUNCTION F_DT_TO_DT8BSIE : ARRAY [1..8] OF BYTE (*DateTime im 8-Byte Siemens Format*)
VAR_INPUT
DT_In : DT; (*DateTime im Beckhoff-/Codesys Format*)
END_VAR
VAR
stTimeStruct : TIMESTRUCT;
uZehner: BYTE;
uEiner: BYTE;
uJahr : BYTE;
uJahrZehnt : BYTE;
uTemp : WORD;
uHunderter: BYTE;
END_VAR
(*DateTime in Timestruct umwandeln*)
stTimeStruct := DT_TO_SYSTEMTIME(DT_In);
(*DateTime 8-Byte Siemens zusammenstellen*)
(*Jahr*)
uJahrZehnt := WORD_TO_BYTE(stTimeStruct.wYear MOD 100);
uZehner := uJahrZehnt / 10;
uEiner := uJahrZehnt MOD 10;
F_DT_TO_DT8BSIE[1] := (uZehner * 16) + uEiner;
(*Monat*)
uZehner := WORD_TO_BYTE(stTimeStruct.wMonth) / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wMonth) MOD 10;
F_DT_TO_DT8BSIE[2] := (uZehner * 16) + uEiner;
(*Tag*)
uZehner := WORD_TO_BYTE(stTimeStruct.wDay) / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wDay) MOD 10;
F_DT_TO_DT8BSIE[3] := (uZehner * 16) + uEiner;
(*Stunde*)
uZehner := WORD_TO_BYTE(stTimeStruct.wHour) / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wHour) MOD 10;
F_DT_TO_DT8BSIE[4] := (uZehner * 16) + uEiner;
(*Minute*)
uZehner := WORD_TO_BYTE(stTimeStruct.wMinute) / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wMinute) MOD 10;
F_DT_TO_DT8BSIE[5] := (uZehner * 16) + uEiner;
(*Sekunde*)
uZehner := WORD_TO_BYTE(stTimeStruct.wSecond) / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wSecond) MOD 10;
F_DT_TO_DT8BSIE[6] := (uZehner * 16) + uEiner;
(*Millisekunden (Hunderter/Zehner)*)
uTemp := stTimeStruct.wMilliseconds / 10;
uEiner := WORD_TO_BYTE(stTimeStruct.wMilliseconds) MOD 10;
uZehner := WORD_TO_BYTE(uTemp) MOD 10;
uHunderter := WORD_TO_BYTE(uTemp) / 10;
F_DT_TO_DT8BSIE[7] := (uHunderter * 16) + uZehner;
(*Millisekunden (Einer)*)
F_DT_TO_DT8BSIE[8] := SHL(uEiner,4);
(*Wochentag umlegen (Wochentag bei Beckhoff --> 0=Montag - 6=Sonntag) (Wochentag bei Siemens --> 1= Sonntag ... 7=Samstag)*)
CASE stTimeStruct.wDayOfWeek OF
0: (*Montag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 2;
1: (*Dienstag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 3;
2: (*Mittwoch*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 4;
3: (*Donnerstag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 5;
4: (*Freitag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 6;
5: (*Samstag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 7;
6: (*Sonntag*) F_DT_TO_DT8BSIE[8] := F_DT_TO_DT8BSIE[8] + 1;
END_CASE
Ich hab den FC jetzt nicht auf Herz und Nieren geprüft - sollte aber soweit funktionieren. Die verwendete Funktion DT_TO_SYSTEMTIME findest du in der TcUtilities.lib von Beckhoff.
Mfg
uncle_tom