Date in 3 mal Integer wandeln

steffen21m

Level-1
Beiträge
71
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute ! :)
Ich habe eine Simatic S7 - 314 CPU, die mit einem Lauer PCS Bedienpanel über ein PCS 812 gekoppelt ist.
Ich möchte auf dem Bedienpanel das aktuelle Datum anzeigen und eventuell das Datum verändern können.
Dazu lese ich die interne Uhr (Read Clock) aus und wandle das Date_And_Time Format über den FC6 in Date um.
1. Nur wie wandle ich Date in Tag (INT), Monat (INT) und Jahr (INT)
(also in 3 Integer Variablen, die das Panel anzeigt).
2. Wie kann ich das ganze umgekehrt machen und das Datum über 3
Variablen stellen ?

Bin für jeden Tipp dankbar

Noch ein schönes Wochenende

Gruß Steffen
 
Hallo!

Du musst den Datentyp aufteilen.
Ich habs jetzt einfach nur mal mit dem Date and Time Datentypen vom Ob1 (wenn ob1 aufgerufen wird) gemacht. Wie die einzelnen Datentypen aufgebaut sind dazu siehe die Hilfe.

Code:
ORGANIZATION_BLOCK "Organisationsbaustein 1"
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1
 
VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ; //Reserved for system
  OB1_RESERVED_2 : BYTE ; //Reserved for system
  OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 started
  Jahr : BYTE ; 
  Monat : BYTE ; 
  Tag : BYTE ; 
  Stunde : BYTE ; 
  Minute : BYTE ; 
  Sekunde : BYTE ; 
END_VAR
BEGIN
NETWORK
TITLE =
 
      L     P##OB1_DATE_TIME; 
      LAR1  ; 
      L     LB [AR1,P#0.0]; 
      T     #Jahr; 
      L     LB [AR1,P#1.0]; 
      T     #Monat; 
      L     LB [AR1,P#2.0]; 
      T     #Tag; 
      L     LB [AR1,P#3.0]; 
      T     #Stunde; 
      L     LB [AR1,P#4.0]; 
      T     #Minute; 
      L     LB [AR1,P#5.0]; 
      T     #Sekunde; 
 
END_ORGANIZATION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du brauchst fast nix wandeln

Der FC der die Uhr liest liefert als Datentyp DATE_TIME zurück
wenn diese Variable z.B in DB1 ab DBB0 beginnt:

DBB0 -> Jahr
DBB1 -> Monat
DBB2 -> Tag
DBB3 -> Stunden
DBB4 -> Minuten
DBB5 -> Sekunden

Diese Werte liegen allerdings in BCD Format vor d.h. bei jedem Wert
z.B. für das Jahr
L DB1.DBB0
BTI (in Integer wandeln)
T ZielInteger

Beim Setzen der Uhr genau anders rum aber vorher mit ITB von Int nach BCD wandeln

Wenn du nicht klarkommst kann ich dir meine Bausteine schicken, incl. aller Variablen für das OP zum anzeigen / setzen der Uhrzeit. Hab aber atm keine Lust den Firmenschlaptop rauszukramen ;-)
 
Danke für die schnelle Antwort !
Ich bin ab Mittwoch wieder "am Gerät" und probiere alles mal aus.
Mit euren Antworten müsste es so weit funzen.

Werde euch auf jeden Fall dann auf dem Laufenden halten....

Gruß Steffen
 
So ... heute war ich dran und habe alles ausprobiert.
Leider hat es nicht geklappt.
Wenn ich statt OB1_Date_And_Time die Date_And_Time vom SFC der die interne Uhr liest nehme und in die temporären Variablen Jahr, Tag, Monat und Stunde schaue, erhalte ich nicht das gewünschte Ergebnis:
Tag und Monat sind leer und Jahr zeigt eine Hausnummer an.

Wegen der Möglichkeit das Datum per Bedienpanel zu stellen wäre vielleicht Lösung 2 von Andreas für mich einfacher.
Leider weiß ich nicht wie ich Date_And_Time in den DB1 transferieren kann. Die Variable ist länger als ein Doppelwort und kann weder per Move Baustein, noch geladen und in ein Doppelwort oder Datenbaustein transferiert werden.

Ich bräuchte deswegen noch mal eure Hilfe, weil ich es einfach nicht peile ...


Gruß Steffen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mach' im OB1 folgendes:

L LB 12
T DB1.jahr //jahr
L LB 13
T DB1.monat //monat
L LB 14
T DB1.tag //tag
L LB 15
T DB1.stunde //stunde
L LB 16
T DB1.minute //minute
L LB 17
T DB1.sekunde //sekunde

GGf. musst du zwischen die Lade- und Transferbefehle noch ein BTI einfügen, damit die Zeit richtig angezeigt wird.

So jetzt wird es etwas kompliziert, da ich die Zeit mehrmals verwende, muss ich diese nochmals von einem DB in einen anderen verschieben.

Der DB in den die Daten jetzt geschoben werden ist als Bereichszeiger für die Uhrzeit angegeben.
(DB160.DBW0)

L DB1.stunde //stunden
T DB160.DBB 3
L DB1.minute //minuten
T DB160.DBB 4
L DB1.sekunde //sekunden
T DB160.DBB 5
L B#16#1 //Wochentag
T DB160.DBB 6
L DB1.tag //Tag
T DB160.DBB 2
L DB1.monat //Monat
T DB160.DBB 1
L DB1.jahr //Jahr
T DB160.DBB 0

Der DB160, welcher als Bereichszeiger angegeben wird muss folgende Struktur haben.

Im DB eine Unterstruktur anlegen (an erster Stelle ab Byte 0, sonst müssen die Adressen gändert werden)
In der Unterstruktur eine Variable des Typs "DATE_AND_TIME" anlegen.
Danach 2 Variablen des Typs WORD für das System in die Struktur einfügen.

Jetzt sollte die Zeit der S7 an das Panel übergeben werden.
 
Hallo,
ich schreibe mal auf dieses Thema, weil der Lösungsweg für mein Problem dem oben ähnlich sein sollte. Also folgendes; ich habe 3 Integer-Variablen ( Sekunden, Minuten, Stunden ) und möchte diese in dem Format "TIME"
zusammenfassen.
DB150.DBW12 INT Stunden
DB150.DBW14 INT Minuten
DB150.DBW16 INT Sekunden
DB150.DBD18 TIME Gesamtzeit

mein Versuch über L DB150.DBW16
ITB
T DB150DBB 19
usw. ist leider gescheitert weil einfach nie die richtige Zeit
rauskam:(
 
Datentyp TIME

Der Datentyp Time hinterlegt den Zeitwert in Millisekunden (IEC Zeitwert).

Du musst die Millisekunden dementsprechend Dividieren damit du auf Sekunden, Minuten, Stunden und Tage kommst bzw wenn du die einzelnen Werte hast Multiplizieren.

zb.:
Code:
[SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Stunden; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] L#3600000; 
[/SIZE][SIZE=1][COLOR=#0000ff]*D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]T[/COLOR][/SIZE][SIZE=1] #Stundenwert; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Minuten; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] L#60000; 
[/SIZE][SIZE=1][COLOR=#0000ff]*D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]T[/COLOR][/SIZE][SIZE=1] #Minutenwert; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Sekunden; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] 1000; 
[/SIZE][SIZE=1][COLOR=#0000ff]*D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]T[/COLOR][/SIZE][SIZE=1] #Sekundenwert; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Millisekunden; 
[/SIZE][SIZE=1][COLOR=#408080]T[/COLOR][/SIZE][SIZE=1] #Millisekundenwert; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Sekundenwert; 
[/SIZE][SIZE=1][COLOR=#0000ff]+D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Minutenwert; 
[/SIZE][SIZE=1][COLOR=#0000ff]+D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]L[/COLOR][/SIZE][SIZE=1] #Stunden; 
[/SIZE][SIZE=1][COLOR=#0000ff]+D[/COLOR][/SIZE][SIZE=1] ; 
[/SIZE][SIZE=1][COLOR=#408080]T[/COLOR][/SIZE][SIZE=1] #IEC_Zeitwert; 
[/SIZE]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank für eure zahlreichen Antworten :) !
Ich habe heute noch mal etwas herumprobiert. Mit euren Lösungsansätzen habe ich folgenden Weg gewählt:

In einem FC wird der SFC 1 Read Clock aufgerufen.
In der Deklaration der temporären Variablen des FC wird die Variable X vom Typ DATE_AND_Time angelegt. Diese hat eine Adresse (z.B ab 0).
Im FC kann dann durch:
l lb 0 das Jahr (nur die letzten beiden Zahlen des Jahres z.B 06)
l lb 1 der Monat
l lb 2 der Tag
l lb 3 die Stunde
l lb 4 die Minute
l lb 5 die Sekunde
abgegriffen und direkt auf das Panel transferiert werden. Vorher muss die Variable X aber auf den Ausgang CDT des SFC 1 geschaltet werden.
Alle Variablen liegen im BCD Code vor.

Mit dem SFC 0 SET Clock kann die Uhrzeit am Eingang PDT gesetzt werden. Dazu wurde wieder eine Variable Y vom Typ Date_And_Time als temporäre Variable angelegt.
Die Bildung von DATE_And_Time erfolgt dann genau umgekehrt.

Der einzige Nachteil liegt darin, wenn temporäre Variablen vor den neu angelegten Variablen gelöscht werden. Dadurch verschiebt sich der Adressbereich.

Gruß Steffen
 
erstellung von date oder date_and_time

hallo,

der beitrag ist für mein problem schon sehr hilfreich. möchte in einem Panel op 177 die Uhrzeit einlesen ->Bereichszeiger auf uhrzeit db .. alles kein problem. Sollte jetzt aber stromausfall oder sonstige zeitänderung stattfinden soll über das Panel die Zeit neu vorgegeben werden. Dafür ist ja der sfc0 geeignet. nur das erstellen der Date_and_time Variable stellt sich als schwieriger heraus als gedacht.

hat jemand den quelcode in dem ich für dd.mm.yy und hh.mm also 5 variablen des typs int dieses date_and_time erstellen kann.
habe bisher einen db angelegt mit der variable zeit als date_and_time
und dann geschrieben:

auf db104

L #jahr
itb
T LB0

L #Monat
itb
T LB1

usw.

aber wenn ich jetzt den sfc0 aufrufe
muss ich beim pdt die adresse des date_and_time types eingeben.
wie muss dies erfolgen? db104.zeit hilft hier nicht..

Oder gibt es eine einfachere Variante die Systemzeit des Panels vielleicht zu ändern und diese dann mit der CPU abgleichen? Die Systemzeit kann ich aber schätzungsweise nur über die Systemsteuerung des Panels ändern? und da sollte der Benutzer ja eigentlich nicht ran
 
Zurück
Oben