Date and Time, Bytes einzeln auswerten

smartie

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

ich hänge gerade an einem für euch sicher klitzekleinen Problem:

Ich lese mit der Funktion SFC1 die Systemuhr einer S7-313C aus und schiebe das Ergebniss in einen Datenbaustein.
Den Aufbau der Variable im Format Date and Time verstehe ich.

Mein Problem besteht nun darin das ich das Datum, welches ja im BCD Format vorliegt in einem Byte ausgeben muss. Also ich meine für jede Ziffer soll ein Byte stehen.

Damit z.B. 110208 so aussieht:

DB1.DBB0 8
DB1.DBB1 0
DB1.DBB2 2
DB1.DBB3 0
DB1.DBB4 1
DB1.DBB5 1

Das ganze will ich später über eine OPC Verbindung an einen PC übergeben.

Über BTI kann ich das das erste Byte von Date an Time, welches die Jahreszahl enthält in ein Integer wandeln.
Das ist soweit ganz gut.

Aber leider steht in diesem Byte dann die ganze Jahreszahl 8 (ohne 0 vorne dran !!) und beim Jahr 2011 steht dann da 11.

Mein Problem ist nun wie bekomme ich den Wert aus diesem Byte gesplittet, so das in einem Byte 0 steht und im anderen 8.

Ich hoffe ihr versteht was ich meine und könnt mir helfen, die Hilfefunktion hats nicht wirklich gebracht. :confused:


Vielen Dank

smartie
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Am Besten einzeln in BCD wandeln.

Also:

Code:
L #Jahr                     //Byte, Jahr, BCD-Codiert
SRW 4                       //Einerstelle rechts rausschieben
BTI                         //Integer daraus machen 
T #iZehnerJahr              //Zehnerstelle Jahr

L #Jahr                     //Byte, Jahr, BCD-Codiert
SLW 12                      //Zehnerstelle links rausschieben
SRW 12                      //Einerstelle wieder zurückschieben
BTI                         //Integer daraus machen 
T #iEinerJahr               //Zehnerstelle Jahr
 
Zuletzt bearbeitet:
Hallo Ralle,

dein Vorschlag funktioniert beim Jahr 08 ganz gut, aber beim Jahr 11 habe
ich das Problem das in dem zweiten Byte (MB41) 11 steht.

Code:
      L     DB201.DBB   18
      SRW   4
      BTI   
      T     MB    40

      L     MW    50
      SLW   4
      SRW   4
      BTI   
      T     MB    41
Gruß smartie
 
Hi Ralle,

dein Vorschlag funktioniert klasse.
Ich war einfach nur zu doof zum lesen. :rolleyes:

Der richtige Code bei mir muss lauten:

Code:
      L     DB201.DBB   18
      SRW   4
      BTI   
      T     MB    40

      L     MW    50
[B]      SLW   12
      SRW   12[/B]
      BTI   
      T     MB    41

Danke !! :)


smartie
 
Hi Ralle,

dein Vorschlag funktioniert klasse.
Ich war einfach nur zu doof zum lesen. :rolleyes:

Der richtige Code bei mir muss lauten:

Code:
      L     DB201.DBB   18
      SRW   4
      BTI   
      T     MB    40

      L     MW    50
[B]      SLW   12
      SRW   12[/B]
      BTI   
      T     MB    41
Danke !! :)


smartie

Ne ne, du warst nicht zu doof. Ich hatte zu schnell geschrieben und es gleich darauf nochmal verbessert :ROFLMAO:!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So sollte es auch funktionieren:
Code:
L     "dein Byte"        //als Dezimalziffer
ITB       
L     B#16#30
OW    
T    "dein CharByte"  //als ASCII-Zeichen
 
Zuletzt bearbeitet:
@Ralle:
Wenn ich den Code richtig interpretiere, dann macht
Code:
SLW 12
SRW 12

das selbe wie

Code:
UW	W#16#000F

Oder habe ich etwas übersehen bzw. nicht verstanden?

@smartie:
Der ASCII-Wert entspricht der Zahl + 48 (wenn die Zahl zwischen 0 und 9) ist. Somit wäre folgendes möglich:

Code:
L #Jahr                     //Byte, Jahr, BCD-Codiert
SRW 4                       //Einerstelle rechts rausschieben
OW W#16#0030                //Statt 48 zu laden und zu addieren
T #iZehnerJahr              //Zehnerstelle Jahr als ASCII

L #Jahr                     //Byte, Jahr, BCD-Codiert
UW W#16#000F                //Einerstellen übriglassen
OW W#16#0030                //Statt 48 zu laden und zu addieren
T #iEinerJahr               //Zehnerstelle Jahr als ASCII

BTI kann nur dann entfallen, wenn der Bytewert in Akku 1 mit absoluter Sicherheit positiv ist. Davon kann bei einem BCD-Wert ausgegangen werden. Die oberen (überflüssigen) Bits wurden bei der Ladeoperation bereits genullt.
 
@Rainer

Ja, viele Wege führen nach Rom ;)

@samrtie

Hättest du doch gleich sagen können :ROFLMAO:. Mein Originalcode sieht so aus:
Code:
      CALL  "READ_CLK"
       RET_VAL:=#RetVal
       CDT    :=#Zeit

//Jahr in Stringword wandeln
      L     0
      T     #Charvars.Jahr     //Definierte Tempvar Word

      L     P##Zeit            //Zeit ist in Temp als Date_and_Time definiert
      LAR1                     //Adresse von Zeit in Temp laden
      L     B [AR1,P#0.0]      //Jahr ist das 1.Byte, das wird hier geladen
      T     #HM_Char2          //und in HM_Char2 kopiert, Format Word in Temp

      SRW   4                  //Einerstelle von Jahr (BCD-Codiert) wird gelöscht, Zehnerstelle kommt an die Einerstelle
      L     W#16#30            //30Hex=48Dez addieren (Char "erzeugen")
      +I    
      SLW   8                  //in das linke Byte schieben und in HM_Char1 (Word in Temp) speichern, also in der Zehnerstelle
      T     #HM_Char1

      L     #HM_Char2          //wieder das Jahr laden
      SLW   12                 //so wird die Zehnerstelle gelösche, die Einerstelle bleibt übrig
      SRW   12
      L     W#16#30            //30Hex=48Dez addieren (Char "erzeugen")
      +I    
      T     #HM_Char2

      L     #Charvars.Jahr     //das ist mit 0 vorbelegt
      L     #HM_Char1          //Zehnerstelle im Charformat dazu
      OW    
      L     #HM_Char2          //Einerstelle im Charformat dazu
      OW    
      T     #Charvars.Jahr     //Im Word Charvars.Jahr steht jetzt im linken
Byte die Zehnerstelle des Jahres im Charformat, im rechten Byte steht die
Einerstellen im Charformat, also für 08 steht 3038hex drin, für 12 steht dann
3132hex

Das ist etwas "umständlicher" als das von OHGN und Rainer, aber für Leute mit etwas weniger Praxis evtl. ein wenig leichter lesbar. (Hoffe ich ;) )
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

vielen Dank für eure Tipps, ich habe zunächst mal das Beispiel von Rainer Hönle angeschaut und es funktioniert auch ganz gut.

Wenn ich es richtig verstehe wird da zu meinem Bytewert einfach 30 addiert.

Das ist ganz schön Neuland für mich, ich komme aus der S7-200er Welt und habe zwar schon die ein oder andere S7-300 zum laufen gebracht.
Aber mehr auf der E/A Ebene.

So Sachen wie AKKU 1 und AKKU 2 und dergleichen sagen mir NULL.

Ich glaube ich muss mir demnächst doch mal irgendwo ein Handbuch zulegen. :???:

@ Rainer Hönle :

Was ist denn mit " Der ASCII-Wert entspricht der Zahl + 48 (wenn die Zahl zwischen 0 und 9)" gemeint?

Das Beispiel von OHGN kann ich nicht nachvollziehen?
Soll ich den von BCD nach INT gewandelten Wert wieder nach BCD wandeln?
Oder soll ich den BCD Wert als Ausgang benutzen?

smartie
 
Was ist denn mit " Der ASCII-Wert entspricht der Zahl + 48 (wenn die Zahl zwischen 0 und 9)" gemeint?
schau dir mal eine ascii tabelle an dann siehst du sofort was reiner meint. die 0 steht dort an 'position' 48, 1 an 49 usw.

und wie erwähnt kannst du auch die fc's nehmen
 
OHGN und ich machen im Prinzip dasselbe.
Zu Deiner Frage: der ASCII-Wert von 0 ist 48, der von 1 ist 49, ... Dies entspricht einer Addition von 48. Dies gilt natürlich nur, wenn sichergestellt ist, dass die Zahl (besser der Ausgangswert im Akku) zwischen 0 und 9 ist. Dann darüber kommt für diese Rechenart Blödsinn raus (einfach mal probieren ;-)).
Bei einer Zahl zwischen 0 und 9 (oder besser wenn sichergestellt ist, dass Bit4 und Bit5 nicht gesetzt sind) kann statt einer Addition mit 48 (dezimal!!) auch eine Veroderung mit 30 (hexadezimal!!), was 48 dezimal entspricht, erfolgen. Diese Variante hat auch OHGN verwendet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hättest du doch gleich sagen können :ROFLMAO:.

Hi Ralle,

hab deinen Code nicht ausprobiert, verstehe ich ehrlich gesagt nicht ganz.
(Pointerkentnisse = 0)

Vom Ablauf her bekomme ich von der Fördertechnik SPS über eine S7-Verbindung eine Variable im Format Date and Time,
diese muss ich dann an den PC über eine OPC Verbindung Byte weise im ASCII Format ausgeben.

Zum Testen lese ich hier eben mit SFC1 die Systemuhr aus.

Vielleicht kannst du mir ja ein klein wenig kommentieren was du da getippselt hast. :)

smartie
 
Der ASCII-Wert entspricht der Zahl + 48

Achso, das sollte bedeuten das dezimal immer 48 dazu addiert werden kann, sofern der Wert zwischen 0 und 9 liegt.

Soweit klar :)

Bei einer Zahl zwischen 0 und 9 (oder besser wenn sichergestellt ist, dass Bit4 und Bit5 nicht gesetzt sind)

Das ist bei einer BCD kodierten Zahl sichergestellt?

Nochmals vielen Dank.

@ volker:

Den Vorschlag mit den FC´s habe ich mir auch angeschaut,
aber wenn ich das wie von Rainer Hönle beschrieben alles in einem Netzwerk machen kann dann ist das für mich etwas übersichtlicher.

Danke
 
Zurück
Oben