Date_and_Time vom OB auslesen

taucherd

Level-2
Beiträge
61
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, habe ein Problem was ich mir nicht erklären kann. Lese die aktuelle Uhrzeit vom OB 1 aus unter den Lokaldaten und es funktioniert auch alles bis auf den Wochentag. Habe keine Ahnung wieso der nicht richtig ausgelesen wird.

Die Standartdeklaration von Siemens im OB 1:
OB1_DATE_TIME Adresse:12.0

Das ist der Code dafür:
L LB 12 //Jahr
BTI
T "Jahr"

L LB 13 //Monat
BTI
T "Monat"

L LB 14 //Tag
BTI
T "Tag"

L LB 15 //Stunde
BTI
T "Stunde"

L LB 16 //Minute
BTI
T "Minute"

L LB 17 //Sekunde
BTI
T "Sekunde"

L LB 18 //Millisekunden
BTI
T "Millisekunden"

L LB 19 //Wochentag
BTI
T "Wochentag"

das Problem ist das der Wochentag von 0-100 (INT) läuft???
Habe es auch schon mit dem READ_CLK versucht und da ist es das selbe- irgendwie komme ich drauf auf diesen Fehler.

Der Aufbau des Formats ist ja: Byte n ist Jahr, Byte n+1 ist das Monat und Byte n+7 ist der Wochentag usw...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja meine Variablen sind als INT definiert, hier eine Abbildung der Sysmboltabelle.
Wie gesagt es funktioniert auch nicht mit dem SFC1- der macht das selbe.

Sysmboltabelle

Jahr MW 30 INT
Monat MW 32 INT
Tag MW 34 INT
Stunde MW 36 INT
Minute MW 38 INT
Sekunde MW 40 INT
Millisekunden MW 42 INT
Wochentag MW 44 INT
 
Hallo Taucherd,

im letzte Byte im DATE_AND_TIME steht auch noch die letzte Stelle der ms BCD-Codiert.
Wenn Du mit
Code:
SLW 12
SRW 12
die ms rausschiebst hast Du dann im AKKU1 den Wochentag von 1-7 (INT).


Grüße
Gebs
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Steht die letzte Stelle von den Millisekunden vielleicht im Byte n+7 an erster Stelle? und der Wochentag an zweiter Stelle? denn das würde stimmen 3=Dienstag

Und laut Siemens steht im Byte n+6 die Milisekunden von 000...999 als BCD, wie soll das gehen? dafür ist ein byte ein bischen zu klein, oder...
 
für die ms mit 3 Stellen BCD-Codiert brauchst Du auch 3 Nibble.
d.h. Byte 6 linkes Nibble : 100er -Stelle (BCD)
Byte 6 rechtes Nibble: 10er-Stelle (BCD)
Byte 7 linkes Nibble: 1er-Stelle (BCD)
Byte 7 rechtes Nibble: Wochentag (INT)

Grüße
Gebs
 
ich würde einfach die IEC-funktionen

Zusammenfassen DATE und TIME_OF_DAY zu DT D_TOD_DT FC 3
Extrahieren DATE aus DT DT_DATE FC 6
Extrahieren des Wochentags aus DT DT_DAY FC 7
Extrahieren TIME_OF_DAY aus DT DT_TOD FC 8

verwenden, das spart ne menge nerven
 
Zuviel Werbung?
-> Hier kostenlos registrieren
so sieht es aus, wenn man sich an Gebs vorgaben hält - danke dafür auch von mir.

Code:
*
      L     LW    18
      SRW   4
      BTI   
      T     "Millisekunden"

      L     LW    18
      SLW   12
      SRW   12
      BTI   
      T     "Wochentag"
 
Code:
*
FUNCTION FC 1710 : VOID
TITLE =READ_CLK
//Funktion zum Lesen und Speichern der Systemzeit im Merker- oder 
//Datenbausteinbereich
//Die Uhrzeit wird fortlaufend ab dem ersten Word am Eingang anyDateTime gespeichert
//Jahr,Monat,Tag,Stunde,Minute,Sekunde,Millisekunde,Wochentag
//
//Aufrufbeispiel:
//      CALL  FC     2
//       anyDateTime   :=#OB1_DATE_TIME
//       anyDestination:=DB1.DBW16
//
//DATE:     09.12.2008
//AUTHOR:   4lagig
//VERSION:  V0.1 BasicVer
AUTHOR : '4lagig'
FAMILY : ClockGF
VERSION : 0.1

VAR_INPUT
  anyDateTime : ANY ;    
  anyDestination : ANY ;    
END_VAR
VAR_TEMP
  dwTempAR1 : DWORD ;    
  dwTempAR2 : DWORD ;    
  xDB : BOOL ;    
  wDB : WORD ;    
  iLoop : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =

      TAR1  #dwTempAR1; // adressregister
      TAR2  #dwTempAR2; // sichern

      L     0; // schleife
      T     #iLoop; // initialisieren

      L     P##anyDestination; // ziel prüfen
      LAR1  ; 

      L     W [AR1,P#4.0]; // ob DB
      L     0; 
      <>I   ; 
      SPBN  db2; 
      TAK   ; 
      T     #wDB; 
      SET   ; 
      =     #xDB; 
      SPA   ver; 
db2:  CLR   ; 
      =     #xDB; // oder nicht

ver:  L     D [AR1,P#6.0]; // speicherbereich aus ANY
      LAR1  ; // in AR1

      L     P##anyDateTime; // quelle
      LAR2  ; 
      L     D [AR2,P#6.0]; // adressieren
      LAR2  ; 

      U     #xDB; // wenn DB
      SPB   ver2; // die andere schleife nutzen

      L     6; 
nex1: T     #iLoop; // jahr, monat, tag,
      L     B [AR2,P#0.0]; // stunden, minuten, sekunden
      BTI   ; // in integer wandeln
      T     W [AR1,P#0.0]; // und speichern
      +AR1  P#2.0; 
      +AR2  P#1.0; 
      L     #iLoop; 
      LOOP  nex1; 

      L     W [AR2,P#0.0]; // millisekunden
      SRW   4; // filtern
      BTI   ; 
      T     W [AR1,P#0.0]; // und speichern

      L     W [AR2,P#0.0]; // wochentag
      SLW   12; // filtern
      SRW   12; 
      BTI   ; 
      T     W [AR1,P#2.0]; // und speichern

      SPA   ver3; 

ver2: AUF   DB [#wDB]; 

      L     6; 
nex2: T     #iLoop; 
      L     B [AR2,P#0.0]; 
      BTI   ; 
      T     DBW [AR1,P#0.0]; 
      +AR1  P#2.0; 
      +AR2  P#1.0; 
      L     #iLoop; 
      LOOP  nex2; 

      L     W [AR2,P#0.0]; 
      SRW   4; 
      BTI   ; 
      T     DBW [AR1,P#0.0]; 

      L     W [AR2,P#0.0]; 
      SLW   12; 
      SRW   12; 
      BTI   ; 
      T     DBW [AR1,P#2.0]; 

ver3: LAR1  #dwTempAR1; // adressregister zurückspeichern
      LAR2  #dwTempAR2; 

      SET   ; //EN0-handling
      SAVE  ; 
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
so sieht es aus, wenn man sich an Gebs vorgaben hält - danke dafür auch von mir.

Code:
*
      L     LW    18
      SRW   4
      BTI   
      T     "Millisekunden"

      L     LW    18
      SLW   12
      SRW   12
      BTI   
      T     "Wochentag"

So hab ich´s gemacht mit Ausblenden
Code:
 CALL SFC1
RET_VAL:=MW10
CDT:=#DATUM_UHRZEIT

LAR1 P##DATUM_UHRZEIT
...

L W#16#FFF0
L W [AR1, P#6.0]
UW
T "Millisekunden"
L B#16#F
L B [AR1, P#7.0]
UW
T "Wochentag"
PS: Sollte man nicht besser immer über den Pointer arbeiten, falls jemand von den Kollegen mal auf die pfiffige Idee kommt eine Variable dazwischen zu schieben? ;-)
Gruß, Mike
 
Zuletzt bearbeitet:
Zurück
Oben