Step 7 CPU-Zeit Format

kruz_007

Level-1
Beiträge
31
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe folgendes Problem, und zwar ich bekomme von einem OPC Router die Aktuelle Zeit in einem DB als "DATE_AND_TIME", diese Zeit kann ich in meiner Variable Tabelle als zwei werte beobachten High und Low:
DB16.DBD 8 DEZ L#14033111 jahr/Monat/Tag/Std
DB16.dbD12 DEZ L#31180501 Min/Sek/milsek/.........

ich möchte diese Zeit über SFC 0 als Aktuelle Zeit in meiner CPU schreiben, ich weiss dass CPU-zeit als BCD Format dargestellt werden soll.
meine Frage wie kann ich diese Zeit teilen (spliten) in Hex MB20= Jahr, MB21 = Monat ..................so dass ich über SFC0 in meiner CPU schreiben kann ???

Danke im Voraus
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo AVentinus,

danke für die Antwort,
so habe ich gemacht leider hat nicht geklappt


U M 10.0
SPBNB _008
CALL "SET_CLK"
PDT :="DATE_AND_TIME".OPC
RET_VAL:=MW2
_008: NOP 0
 
Wieso hat das nicht geklappt. Anscheinend hat er das Symbol dazu gefunden und der Datentyp passt auch.
Wenn es nicht klappt liegt es möglicherweise daran, dass der OPC-Server nicht im gültigen Format sendet.
 
Genau das ist das Problem, ich kann die gesendete Zeit nur als zwei Dezimale werte in meiner Variable Tabele beobachten (high and low, wie oben beschrieben) und nicht als Byte-weise wie man das von DATE_AND_TIME Format kennt.
wie kann ich jetzt diese Zeit Byteweise teilen (spliten) so dass ich mit sfc0 schreiben kann ?
 
Das passt ja gar nicht.

du müsstest in der Ansicht in Byte 8 z.B. B#16#14 für 2014 stehen haben die B#16#0 deutet auf Jahr 2000.
In der nächsten Zeile hast du nicht mal einen gültigen BCD-Wert. Wenn du da den März haben möchtest müsste B#16#3 stehen usw
 
das meine ich ja auch, aber ganz oben bei DB16.DBD8 = L#14033114 ist aber die Richtige zeit :-(
kann ich anhand DB16.dbd8 und DB16.dbd12 die zeit in CPU schreiben ??
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...kann ich anhand DB16.dbd8 und DB16.dbd12 die zeit in CPU schreiben ??

Definitiv nicht.

Wenn mich mein Gedächtnis nicht trügt muss der DATE_AND_TIME Pointer im BCD-Format vorliegen.

Versuche es mal mit DTB die beiden Doppelwörter in eien anderen DB umzusetzen und mit diesen neuen Bytes den SFC zu füttern
 
@dtsclipper

habe ich auch schon mal gemacht leider hat auch nicht geklappt, sogar die Werte nach der konvertierung sich nicht ändern

L db16.dbd 8
DTB
T MD214
NOP 0


L db16.dbd 12
DTB
T MD220
NOP 0


Variable tabelle2.jpg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
FUNCTION FC 2 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  Zeit_1 : DINT ;    //Zeit Teil 1 von OPC
  Zeit_2 : DINT ;    //Zeit Teil 1 von OPC
END_VAR
VAR_OUTPUT
  Zeit_DT : DATE_AND_TIME ;    
END_VAR
VAR_TEMP
  Datenbaustein : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Zeit konvertieren

      L     P##Zeit_DT; 
      LAR1  ; 

      L     B [AR1,P#2.0]; 
      L     B#16#84; 
      <>I   ; 
      SPB   kdb; 
      L     W [AR1,P#0.0]; 
      T     #Datenbaustein; 
      AUF   DB [#Datenbaustein]; 
kdb:  L     D [AR1,P#2.0]; 
      LAR1  ; 



// Jahr
      L     #Zeit_1; 
      L     L#1000000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#0.0]; 

// Monat
      L     #Zeit_1; 
      L     L#1000000; 
      MOD   ; 
      L     L#10000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#1.0]; 

// Tag
      L     #Zeit_1; 
      L     L#10000; 
      MOD   ; 
      L     L#100; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#2.0]; 

// Stunde
      L     #Zeit_1; 
      L     L#100; 
      MOD   ; 
      ITB   ; 
      T     B [AR1,P#3.0]; 

// Minute
      L     #Zeit_2; 
      L     L#1000000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#4.0]; 

// Sekunde
      L     #Zeit_2; 
      L     L#1000000; 
      MOD   ; 
      L     L#10000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#5.0]; 

// Millisekunden
      L     #Zeit_2; 
      L     L#10000; 
      MOD   ; 
      L     L#100; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#6.0]; 

// Millisekunde / WT
      L     #Zeit_2; 
      L     L#100; 
      MOD   ; 
      ITB   ; 
      T     B [AR1,P#7.0]; 

END_FUNCTION

Hier mal eine Quelle. Sollte passen, ist aber nicht 100% getestet.
 
@ Aventinus

wie gesagt es funktioniert, danke nochmal, möchte nur mal verstehen was du genau gemacht hast, kannst du mir bitte paar kommentare zu dem Programm schreiben.

Danke im Voraus
 
nochmal eine Quelle, besser kommentiert.
Code:
FUNCTION FC 2 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  Zeit_1 : DINT ;    //Zeit Teil 1 von OPC
  Zeit_2 : DINT ;    //Zeit Teil 2 von OPC
END_VAR
VAR_OUTPUT
  Zeit_DT : DATE_AND_TIME ;    
END_VAR
VAR_TEMP
  Datenbaustein : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Zeit konvertieren

// Pointer auf Out-Variable laden und in AR1 ablegen
      L     P##Zeit_DT; 
      LAR1  ; 

      L     B [AR1,P#2.0]; // Speicherbereich der aussen anparametrierten Variable laden
      L     B#16#84; 
      <>I   ; 
      SPB   kdb; // Wenn Speicherbereich <> DB --> Springe zu kdb
      L     W [AR1,P#0.0]; // DB-Nummer laden
      T     #Datenbaustein; 
      AUF   DB [#Datenbaustein]; // DB aufschlagen
kdb:  L     D [AR1,P#2.0]; // Adresse der Variable laden
      LAR1  ; // und in AR1 ablegen



// Jahr                                 
      L     #Zeit_1; // Wert durch 1000000 Teilen, so dass nur die vorderen 2 Stellen übrigbleiben
      L     L#1000000; 
      /D    ; 
      ITB   ; // Integer zu BCD wandeln
      T     B [AR1,P#0.0]; // und an der richtigen Stelle in der am Out-Parameter anparametrierten Variable ablegen

// Monat
      L     #Zeit_1; // Wert modulo 1000000 um die vorderen 2 Stellen zu löschen
      L     L#1000000; 
      MOD   ; // Ergebnis durch 10000 Teilen, so dass die Stellen 3 und 4 übrigbleiben
      L     L#10000; // ... der Rest sollte dann einleuchten
      /D    ; 
      ITB   ; 
      T     B [AR1,P#1.0]; 

// Tag
      L     #Zeit_1; 
      L     L#10000; 
      MOD   ; 
      L     L#100; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#2.0]; 

// Stunde
      L     #Zeit_1; 
      L     L#100; 
      MOD   ; 
      ITB   ; 
      T     B [AR1,P#3.0]; 

// Minute
      L     #Zeit_2; 
      L     L#1000000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#4.0]; 

// Sekunde
      L     #Zeit_2; 
      L     L#1000000; 
      MOD   ; 
      L     L#10000; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#5.0]; 

// Millisekunden
      L     #Zeit_2; 
      L     L#10000; 
      MOD   ; 
      L     L#100; 
      /D    ; 
      ITB   ; 
      T     B [AR1,P#6.0]; 

// Millisekunde / WT
      L     #Zeit_2; 
      L     L#100; 
      MOD   ; 
      ITB   ; 
      T     B [AR1,P#7.0]; 

END_FUNCTION
 
Zurück
Oben