TIA Alternative zu FC61 "BT_LT" [ERLEDIGT]

Beiträge
36
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Zusammen,
ich habe folgendes Problem:

Ich habe ein Projekt (TIA V13) in dem der FC61 "BT_LT" verwendet wird.
Aktuell läuft das Projekt auf eine 300er Steuerung.
Da diese aber seit langem abgekündigt ist, soll sie gegen eine 1200er oder 1500er ausgetauscht werden.
Ich habe das Projekt bereits migriert und kleinere Fehler ausgemerzt.
Gibt es einen Alternativbaustein für den FB61 "BT_LT" der auf einer 1200er/1500er projektiert werden kann?
Kann mir da jemand weiter helfen?

Gruß Ole
 
Verwenden alle Deine BT_LT-Aufrufe die Uhrzeit der CPU-Uhr als Eingangsparameter BT? Oder werden auch von der aktuellen Uhrzeit unabhängige Zeitpunkte/Zeitstempel konvertiert?
RD_LOC_T und RD_SYS_T lesen generell die CPU-Uhr als Eingangswert, es kann keine Zeit als Eingangsparameter zum Konvertieren angegeben werden. Die Uhr muß in UTC laufen.


Falls Du eine allgemeine Konvertierfunktion für beliebige Eingangszeiten brauchst, dann könntest Du z.B. meinen BT_LT_3_CET als AWL-Vorlage auf SCL umschreiben. Oder aus der OSCAT Basic Lib die Funktion DST verwenden (nicht getestet), um zu ermitteln ob die angegebene UTC-Zeit in der Sommerzeit liegt, und wenn ja dann zu der UTC-Zeit 2 Stunden addieren, sonst 1 Stunde addieren. Oder Du verwendest folgende Formel, um das Umstelldatum zu ermitteln:
wen´s interessiert hier die Formeln für die Berechnungen der genauen Tage im März und im Oktober für Beginn und Ende der Sommerzeit.

Formel zur Berechnung des Beginns der europäischen Sommerzeit

Sonntag (31 - (5*Jahr/4 + 4) mod 7) März um 01.00 Uhr UTC
(Gültig bis 2099).

Formel zur Berechnung des Endes der europäischen Sommerzeit

Sonntag (31 - (5*Jahr/4 + 1) mod 7) Oktober um 01.00 Uhr UTC
(Gültigkeit wie oben).

Das Jahr muß zweistellig eingegeben werden also 08 für 2008.

Harald
 
Aktuell läuft das Projekt auf eine 300er Steuerung.
Da diese aber seit langem abgekündigt ist, soll sie gegen eine 1200er oder 1500er ausgetauscht werden.
Woher hast Du die Info, das die S7-300 "seit langem abgekündigt ist"?

Die S7-300 ist noch nicht abgekündigt. Es gibt lediglich von Siemens den Hinweis, daß die S7-300 Familie nicht vor 2023 abgekündigt wird.
Verfügbarkeit
Die SIMATIC S7-300 / ET 200M-Systemfamilien werden als Teil unseres etablierten Produktprogramms grundsätzlich bis 2023 erhältlich sein.
Mit der Veröffentlichung einer Produktauslauferklärung werden die jeweiligen Produkte für weitere 10 Jahre als Ersatzteil verfügbar sein.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Falls Du eine allgemeine Konvertierfunktion für beliebige Eingangszeiten brauchst, dann könntest Du z.B. meinen BT_LT_3_CET als AWL-Vorlage auf SCL umschreiben. Oder aus der OSCAT Basic Lib die Funktion DST verwenden (nicht getestet), um zu ermitteln ob die angegebene UTC-Zeit in der Sommerzeit liegt, und wenn ja dann zu der UTC-Zeit 2 Stunden addieren, sonst 1 Stunde addieren. Oder Du verwendest folgende Formel, um das Umstelldatum zu ermitteln:

Also bei TIA hab ich jetzt noch nie irgendwelche Oscat-Bausteine für Uhrzeiten vermisst.
Die 1500er hat UTC, Lokalzeit und Zeitzone.
Das Rechnen mit dem Datentyp DT funktioniert auch ohne Verrenkungen.
Kein Vergleich zum Aufwand unter Classic.

Gruß
Dieter
.
 
Aktuell läuft das Projekt auf eine 300er Steuerung.
Da diese aber seit langem abgekündigt ist, soll sie gegen eine 1200er oder 1500er ausgetauscht werden.
Woher hast Du die Info, das die S7-300 "seit langem abgekündigt ist"?
Und selbst wenn, wäre eine vorhandene 300er immer noch viel besser als ne 1200er oder 1500er.
Ich würd da normalerweise erstmal garnix austauschen...🤷‍♂️

Ich weiss auch nicht, wer eigentlich immer dieses Schwachsinn in die Welt setzt:rolleyes:

Und nein, Step7 5.x ist auch nicht abbgekündigt... Ist sogar fürs aktuelle Windows 10 freigegeben...

@PN/DP
Natürlich nicht das komplette 300er Segment, ich meinte damit das aktuell verwendete Modell.
ja und??? Von den 1200ern und 1500ern sind auch schon viele abgekündigt...
 
Das ist eigentliche eine schwache Nummer, daß die TIA-Entwickler anscheinend meinen, daß kaum jemand eine allgemein nutzbare Konvertierfunktion von Zeitstempeln in UTC zu Lokalzeit für die S7-1200/1500 braucht. Für solchen Schnulli wie DWORD in BYTEs zerlegen oder Bits in/aus DWORD zu kopieren (was ein erfahrener Programmierer sich in 10 Minuten selbst programmiert) werden extra Bausteine in der LGF entwickelt, aber für die etwas komplexere Konvertierung UTC zu Lokalzeit gibt es nichts. Nur eine "Konvertierfunktion" die als Eingangszeit fest die CPU-Uhr verwendet: RD_LOC_T. Warum konnte man nicht die Uhr-lesen-Funktion weglassen und stattdessen einen Eingangsparameter für die UTC-Zeit vorsehen? Das wäre viel universeller nutzbar. Da müssten die TIA-Anwender allerdings 2 Anweisungen in der richtigen Reihenfolge hintereinander aufrufen - ist das unzumutbar? ;)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Zerlegen in Bytes hab ich bei TIA eigentlich noch nie gebraucht.
Ich verwende als Datentyp für Datum/Uhrzeit - wo es geht - DTL. Ist eigentlich wie eine Struktur und du kannst z.B. auf die Sekunden direkt zugreifen (Zeit.SECOND).

Wenn ich den Offset zwischen Lokalzeit und UTC brauche, dann subtrahiere ich einfach die Beiden.
 
Ich will eigentlich keinen Zeitstempel zerlegen. Und auch nicht den Offset zwischen Lokalzeit und UTC berechnen.

Wie ermittelst Du, ob ein gegebenes UTC-Datum/Uhrzeit in der Sommerzeit liegt? Das ist die Vorraussetzung, um einen beliebigen Zeitstempel von UTC zu Lokalzeit umzurechnen (Zeitstempel von Logs, oder Datensätzen, oder Baugruppen die Zeitstempel liefern, oder von Kommunikationspartnern, ...). Da gibt es in TIA für S7-1200/1500 leider nichts (nur die Legacy BT_LT für S7-300/400), man muß es selber programmieren (oder Drittanbieter-Libs verwenden). Das Addieren von x Stunden auf ein DTL ist nicht das Problem, aber das Ermitteln ob man 1 oder 2 Stunden addieren muß ist halt etwas aufwändiger. Da wird man von TIA nicht unterstützt, weil die eine Funktion, wo das schon programmiert ist, keinen Eingangsparameter hat, sondern nur die Systemuhr verwenden kann/will.

Harald
 
Oder Du verwendest folgende Formel, um das Umstelldatum zu ermitteln:
wen´s interessiert hier die Formeln für die Berechnungen der genauen Tage im März und im Oktober für Beginn und Ende der Sommerzeit.

Formel zur Berechnung des Beginns der europäischen Sommerzeit

Sonntag (31 - (5*Jahr/4 + 4) mod 7) März um 01.00 Uhr UTC
(Gültig bis 2099).

Formel zur Berechnung des Endes der europäischen Sommerzeit

Sonntag (31 - (5*Jahr/4 + 1) mod 7) Oktober um 01.00 Uhr UTC
(Gültigkeit wie oben).

Das Jahr muß zweistellig eingegeben werden also 08 für 2008.
Die zitierten Formeln sind leider falsch (siehe rot markiert). Richtig muß es heißen:
Formel zur Berechnung des Beginns der europäischen Sommerzeit
Sonntag (31 - (5*Jahr/4 + 5) mod 7) März um 01.00 Uhr UTC

Formel zur Berechnung des Endes der europäischen Sommerzeit
Sonntag (31 - (5*Jahr/4 + 2) mod 7) Oktober um 01.00 Uhr UTC

Das ist auch schon jemand anderes aufgefallen und derjenige hat eine ähnliche funktionierende Formel gefunden.
Hier noch eine interessante Formelsammlung rund um Datums-Berechnungen: http://manfred.wilzeck.de/Datum_berechnen.html

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gibt es einen Alternativbaustein für den FB61 "BT_LT" der auf einer 1200er/1500er projektiert werden kann?
Es gibt von Siemens wohl tatsächlich keinen Baustein oder Anweisungen zum Umrechnen von Zeitstempeln in Systemzeit (UTC) zu Lokalzeit für S7-1200/S7-1500 ähnlich BT_LT für S7-300/S7-400. Ich habe mir eine Function UTC_TO_LOC_T in SCL programmiert. Vielleicht kann die noch jemand gebrauchen. Die SCL-Quelle im Anhang. Zum Verwenden mit TIA die Datei-Endung ".txt" entfernen.
Code:
FUNCTION "UTC_TO_LOC_T" : DTL
TITLE = UTC_TO_LOC_T
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : PN_DP
FAMILY : TIMEFUNC
VERSION : 1.0
//Konvertiert UTC zu einer europäischen Lokalzeit
   VAR_INPUT
      UTC {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // Datum_Uhrzeit in UTC
      TZ : Int;   // Offset Zeitzone in Stunden (UTC+TZ)
      DS : Int;   // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
   END_VAR

   VAR_OUTPUT
      DST : Bool;   // 0=Winterzeit / 1=Sommerzeit
   END_VAR

   VAR_TEMP
      tmpDT {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // lokale Kopie des Input UTC
      tmpDS : Int;            // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
      DiffTime : Time;        // Differenz Zeitzone + ggf. Sommerzeit
      IsSummer : Bool;
      ui5Year4 : UInt;        // Zwischenergebnis 5*Year/4
      uiMDH_BeginDst : UInt;  // Monat&Tag&Stunde Beginn Sommerzeit (dd März 01:00)
      uiMDH_EndDst : UInt;    // Monat&Tag&Stunde Ende Sommerzeit (dd Okt 01:00)
      uiMDH_UTC : UInt;       // Monat&Tag&Stunde des Input UTC
   END_VAR

   VAR CONSTANT
      MULTIPLIER_MONTH : UInt := 32;  // 32 Days per Month
      MULTIPLIER_DAY : UInt := 24;    // 24 Hours per Day
      HOUR_01_00 : UInt := 1;         // 01:00 Uhr
   END_VAR

BEGIN
REGION BLOCK INFO HEADER
//===============================================================================
// Title : UTC_TO_LOC_T
// Author: PN_DP
// Konvertiert Datum_Uhrzeit UTC zu einer europäischen Lokalzeit
// mit angegebener Zeitzone und Sommerzeit-Differenz.
//
// Die Sommerzeit beginnt am letzten Sonntag im März 01:00 UTC
// Die Sommerzeit endet am letzten Sonntag im Oktober 01:00 UTC
// Input DS = 0: die Lokalzeit hat nie Sommerzeit
//
// Function für S7-1200/S7-1500. Erstellt mit TIA V15.1
// Version 01.00 | 14.04.2022
//===============================================================================
END_REGION

// Eingangsparameter für Konsistenz vorsichtshalber zu lokal umkopieren
#tmpDT := #UTC;
#tmpDS := #DS;

#DiffTime := T#1H * #TZ; // zunächst nur Offset Zeitzone

// Ermitteln ob Sommerzeit ist und ggf. Offset
IF #tmpDS = 0 THEN // wenn Sommerzeit wie Winterzeit, dann nur Offset Zeitzone
    #IsSummer := FALSE;
ELSE
    #ui5Year4 := 5 * (#tmpDT.YEAR MOD 100) / 4;
    // Beginn Sommerzeit: Sonntag (31 - (5*Jahr/4 + 5) MOD 7) März 01:00 Uhr
    #uiMDH_BeginDst := ( 3 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 5) MOD 7)) )
                       * #MULTIPLIER_DAY + #HOUR_01_00; //Mar DD 01:00
    // Ende Sommerzeit:   Sonntag (31 - (5*Jahr/4 + 2) MOD 7) Oktober 01:00 Uhr
    #uiMDH_EndDst   := (10 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 2) MOD 7)) )
                       * #MULTIPLIER_DAY + #HOUR_01_00; //Oct DD 01:00
    
    // MMDDHH --> (MM*32 + DD)*24 + HH // (1..12*32 + 1..31)*24 + 0..23 = max 9983
    #uiMDH_UTC := (#tmpDT.MONTH * #MULTIPLIER_MONTH + #tmpDT.DAY)
                  * #MULTIPLIER_DAY + #tmpDT.HOUR;
    
    #IsSummer := #uiMDH_UTC >= #uiMDH_BeginDst AND #uiMDH_UTC < #uiMDH_EndDst;
    IF #IsSummer THEN
        #DiffTime := #DiffTime + T#1H * #tmpDS; // Offset Sommerzeit dazu
    END_IF;
END_IF;

// Ausgangswerte zuweisen
#DST := #IsSummer;
#UTC_TO_LOC_T := #tmpDT + #DiffTime; //Lokalzeit zurückgeben

// no error handling
ENO := TRUE;

END_FUNCTION

Beim Aufruf von UTC_TO_LOC_T an TZ den Zeitzonen-Offset in Anzahl Stunden und an DS die Differenz der Sommerzeit zur Winterzeit in Anzahl Stunden angeben. Falls es in einer Zeitzone keine Sommerzeit (mehr) gibt, dann DS = 0 angeben. Zum Umrechnen von UTC zu CET/CEST den Baustein z.B. so aufrufen:
Code:
                +----------------+
                |  UTC_TO_LOC_T  |
              --|EN       Ret_Val|--"MyDB".DTL_LOC
"MyDB".DTL_UTC--|UTC          DST|--"MyDB".IsSommerzeit
             1--|TZ              |
             1--|DS           ENO|--
                +----------------+


Btw: Beim Test/Simulieren/Vergleichen mit RD_LOC_T ist mir aufgefallen, daß bei meinem TIA V15.1 das RD_LOC_T in der Sommerzeit eine falsche Uhrzeit liefert, wenn in der CPU das Sommerzeitbit nicht korrekt gesetzt ist. Also RD_LOC_T ermittelt die Sommerzeit nicht selbst anhand des Datums, sondern schaut lediglich, ob das Bit in der CPU gesetzt ist... Bei manchen CPU-Firmware-Versionen muß man selber dafür sorgen daß das Bit zur richtigen Zeit gesetzt/gelöscht wird.

Harald
 

Anhänge

Es gibt von Siemens wohl tatsächlich keinen Baustein oder Anweisungen zum Umrechnen von Zeitstempeln in Systemzeit (UTC) zu Lokalzeit für S7-1200/S7-1500 ähnlich BT_LT für S7-300/S7-400. Ich habe mir eine Function UTC_TO_LOC_T in SCL programmiert. Vielleicht kann die noch jemand gebrauchen. Die SCL-Quelle im Anhang. Zum Verwenden mit TIA die Datei-Endung ".txt" entfernen.
Code:
FUNCTION "UTC_TO_LOC_T" : DTL
TITLE = UTC_TO_LOC_T
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : PN_DP
FAMILY : TIMEFUNC
VERSION : 1.0
//Konvertiert UTC zu einer europäischen Lokalzeit
   VAR_INPUT
      UTC {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // Datum_Uhrzeit in UTC
      TZ : Int;   // Offset Zeitzone in Stunden (UTC+TZ)
      DS : Int;   // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
   END_VAR

   VAR_OUTPUT
      DST : Bool;   // 0=Winterzeit / 1=Sommerzeit
   END_VAR

   VAR_TEMP
      tmpDT {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;   // lokale Kopie des Input UTC
      tmpDS : Int;            // Differenz Sommerzeit zu Winterzeit (0 oder 1 Stunden)
      DiffTime : Time;        // Differenz Zeitzone + ggf. Sommerzeit
      IsSummer : Bool;
      ui5Year4 : UInt;        // Zwischenergebnis 5*Year/4
      uiMDH_BeginDst : UInt;  // Monat&Tag&Stunde Beginn Sommerzeit (dd März 01:00)
      uiMDH_EndDst : UInt;    // Monat&Tag&Stunde Ende Sommerzeit (dd Okt 01:00)
      uiMDH_UTC : UInt;       // Monat&Tag&Stunde des Input UTC
   END_VAR

   VAR CONSTANT
      MULTIPLIER_MONTH : UInt := 32;  // 32 Days per Month
      MULTIPLIER_DAY : UInt := 24;    // 24 Hours per Day
      HOUR_01_00 : UInt := 1;         // 01:00 Uhr
   END_VAR

BEGIN
REGION BLOCK INFO HEADER
//===============================================================================
// Title : UTC_TO_LOC_T
// Author: PN_DP
// Konvertiert Datum_Uhrzeit UTC zu einer europäischen Lokalzeit
// mit angegebener Zeitzone und Sommerzeit-Differenz.
//
// Die Sommerzeit beginnt am letzten Sonntag im März 01:00 UTC
// Die Sommerzeit endet am letzten Sonntag im Oktober 01:00 UTC
// Input DS = 0: die Lokalzeit hat nie Sommerzeit
//
// Function für S7-1200/S7-1500. Erstellt mit TIA V15.1
// Version 01.00 | 14.04.2022
//===============================================================================
END_REGION

// Eingangsparameter für Konsistenz vorsichtshalber zu lokal umkopieren
#tmpDT := #UTC;
#tmpDS := #DS;

#DiffTime := T#1H * #TZ; // zunächst nur Offset Zeitzone

// Ermitteln ob Sommerzeit ist und ggf. Offset
IF #tmpDS = 0 THEN // wenn Sommerzeit wie Winterzeit, dann nur Offset Zeitzone
    #IsSummer := FALSE;
ELSE
    #ui5Year4 := 5 * (#tmpDT.YEAR MOD 100) / 4;
    // Beginn Sommerzeit: Sonntag (31 - (5*Jahr/4 + 5) MOD 7) März 01:00 Uhr
    #uiMDH_BeginDst := ( 3 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 5) MOD 7)) )
                       * #MULTIPLIER_DAY + #HOUR_01_00; //Mar DD 01:00
    // Ende Sommerzeit:   Sonntag (31 - (5*Jahr/4 + 2) MOD 7) Oktober 01:00 Uhr
    #uiMDH_EndDst   := (10 * #MULTIPLIER_MONTH + (31 - ((#ui5Year4 + 2) MOD 7)) )
                       * #MULTIPLIER_DAY + #HOUR_01_00; //Oct DD 01:00
   
    // MMDDHH --> (MM*32 + DD)*24 + HH // (1..12*32 + 1..31)*24 + 0..23 = max 9983
    #uiMDH_UTC := (#tmpDT.MONTH * #MULTIPLIER_MONTH + #tmpDT.DAY)
                  * #MULTIPLIER_DAY + #tmpDT.HOUR;
   
    #IsSummer := #uiMDH_UTC >= #uiMDH_BeginDst AND #uiMDH_UTC < #uiMDH_EndDst;
    IF #IsSummer THEN
        #DiffTime := #DiffTime + T#1H * #tmpDS; // Offset Sommerzeit dazu
    END_IF;
END_IF;

// Ausgangswerte zuweisen
#DST := #IsSummer;
#UTC_TO_LOC_T := #tmpDT + #DiffTime; //Lokalzeit zurückgeben

// no error handling
ENO := TRUE;

END_FUNCTION

Beim Aufruf von UTC_TO_LOC_T an TZ den Zeitzonen-Offset in Anzahl Stunden und an DS die Differenz der Sommerzeit zur Winterzeit in Anzahl Stunden angeben. Falls es in einer Zeitzone keine Sommerzeit (mehr) gibt, dann DS = 0 angeben. Zum Umrechnen von UTC zu CET/CEST den Baustein z.B. so aufrufen:
Code:
                +----------------+
                |  UTC_TO_LOC_T  |
              --|EN       Ret_Val|--"MyDB".DTL_LOC
"MyDB".DTL_UTC--|UTC          DST|--"MyDB".IsSommerzeit
             1--|TZ              |
             1--|DS           ENO|--
                +----------------+


Btw: Beim Test/Simulieren/Vergleichen mit RD_LOC_T ist mir aufgefallen, daß bei meinem TIA V15.1 das RD_LOC_T in der Sommerzeit eine falsche Uhrzeit liefert, wenn in der CPU das Sommerzeitbit nicht korrekt gesetzt ist. Also RD_LOC_T ermittelt die Sommerzeit nicht selbst anhand des Datums, sondern schaut lediglich, ob das Bit in der CPU gesetzt ist... Bei manchen CPU-Firmware-Versionen muß man selber dafür sorgen daß das Bit zur richtigen Zeit gesetzt/gelöscht wird.

Harald

Wird dann UTC_LOC_T mit RD_LOC_T verglichen oder verstehe ich falsch..? Bei S7 CPU314 Baustein RD_LOC_T fehlt (nur für S7-1200/1500 CPUs)?
 
S7-300 kennt keine Lokalzeit, nur Systemzeit der Uhr. Die ist in UTC, wenn man per NTP synchronisiert. Deshalb hier der selbstgeschriebene Baustein UTC_TO_LOC_T, den man mit der Uhrzeit der S7-300 füttert
EDIT: der Baustein ist für S7-1200/1500 und wird so sehr wahrscheinlich nicht auf S7-300 funktionieren.
 
Zuletzt bearbeitet:
UTC_TO_LOC_T von Beitrag #15 ist eine SCL-Quelle. Du müsstest den Code in eine SCL-Quelle kopieren oder die am Beitrag angehängte Datei herunterladen und das ".txt" vom Dateiname entfernen, und dann in Deinem TIA als SCL-Quelle importieren. Dann übersetzen und Du erhältst einen FC.
Allerdings: ich habe nun nochmal genau gelesen, der Code der SCL-Quelle ist für S7-1200/1500, weil der erste Fragesteller explizit den BT_LT-Baustein für S7-1200/1500 haben wollte. Das hätte Dir bei genauem Lesen auch auffallen können/müssen. Das Thema hier passt also gar nicht für Dich, falls Du den BT_LT für eine S7-300 suchst. Was genau willst Du machen? Warum hast Du Dich hier an diesen Thread gehängt?

Falls Du mit TIA in einer S7-300 die Uhrzeit lesen willst und in Lokalzeit umrechnen willst, dann müsstest Du die Uhrzeit mit RD_SYS_T lesen und die erhaltene Uhrzeit (Systemzeit) mit dem im Beitrag #6 erwähnten AWL-Baustein BT_LT_3_CET in Lokalzeit umrechnen. Oder Du überarbeitest den SCL-Code des UTC_TO_LOC_T von Beitrag #15 so, daß er auf S7-300 läuft.

Harald
 
Zurück
Oben