Real Zahl von CP in Excel umwandeln

steinche

Level-2
Beiträge
112
Reaktionspunkte
2
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Zusammen,

ich bin mir nicht sicher, ob dieser Bereich der passende ist, aber ich habe schon viel gelesen und komme nicht weiter.

Über einen CP343-1 wird eine Gleichpunktzahl an einen Rechner gesendet. Ab und zu kommt diese dort nicht richtig an. Mittels Wireshark protokollieren wir den Netzwerkverkehr, um den Übeltäter einzugrenzen.
In der SPS steht beispielsweise ein Real Wert von 21,34 übertragen wird 41 AA B8 52
Bisher habe ich die Werte in freie Merkerbytes der SPS geschrieben und sie mir durch diese umwandeln lassen. Jetzt kommt aber das Problem, dass ich das außerhalb umwandeln muss, z.B. in Excel. Jetzt suche ich schon die ganze Zeit nach einer Lösung, wie ich das in ein "kleines" Makro packen kann? Also das handling mit Makro ist nicht das Problem, nur die passenden Befehle zum wandeln der HEX-Zahlen in Real.

Viele Grüße
Eric
 
... das sind doch alles Bits...

Ich habe vor Jahren mal Visualisierungen mit VB5 und VB6 für S5 und S7 Steuerungen geschrieben. Wenn ich mich recht entsinne konnte ich keine REAL lesen, sondern nur Wörter. In den Siemens Doku`s steht irgendwo welche Bits für Exponent und Mantisse sind, damit kann man sich dann mit einem VBA Script aus den 32Bits die xxxx,xxx wieder zusammenbasteln... in den Hex Werten sind ja auch die Bits... Die Projektdateien von damals habe ich aber leider nicht mehr, sonst würde ich dir den Code für VBA rüberschicken...
 
Hallo Andre,

vielen Dank für die Info! Werde mich mal durch die Hilfe wühlen ;)

Viele Grüße und einen schönen Abend
Eric

Nachtrag: @Ralle Das ist ja eine nette Bettlektüre, dankeschön :-D
 
Zuletzt bearbeitet:
wenn die S7-Daten nach Excel sollen, könnte auch LibNoDave eingesetzt werden.
Beispiel: 32-Bit-Real-Wert aus dem S7-Speicher MD50 lesen und an die Variante Var1 von Excel übergeben:
Dim buf(3) As Byte, Var1 as Variant
res = daveReadBytes(dc, daveFlags, 0, 50, 4, buf(0))
Var1 = daveGetFloatfrom(buf(0))

Ich weiß nicht, wie du den Wert vom CP zum Rechner (Excel) überträgst. Die Funktion daveGetFloatFrom( ) führt auch die Wandlung von Big Endian der S7 ins Littel Endian des Wintel-Rechners aus.

Gruß
Earny
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Earny,

da kommt zu so später Stunde ja richtig Schwung in das Thema ;)
Übertragen werden die Daten bereits an ein System, dass die Daten normalerweise auch korrekt darstellt. Gelegentlich funktioniert dies jedoch nicht. Zur Fehlersuche nutzen wir Wireshark und diese Daten wollte ich "einfach" in eine Gleitpunktzahl wandeln. Da sich meine Programmierkenntnisse auf Step7 ;) und etwas VBA beschränken, kommt mir Excel für sowas sehr gelegen.

Viele Grüße und gute N8!
Eric
 
In Excel 2010 funktioniert das folgende VBA-Makro für die Umwandlung einer 32-Bit-Hexadezimalzahl (42F1A395) in eine
IEEE 754 32-Bit-Gleitpunktzahl (120,8194962):

Code:
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
Sub HEX32_IEEE754_32()
 
' ====================================================
' Umwandlung
' 32-Bit-Hexadezimalzahl (42F1A395) in
' IEEE 754 32-Bit-Gleitkommazahl (120,8194962)
' ====================================================
 
Dim strSource As String
Dim bytArray(0 To 3) As Byte
Dim sngResult As Single
 
strSource = Worksheets(1).Cells(2, 2).Value
 
If strSource = "0" Then
    bytArray(0) = "&H00"
    bytArray(1) = "&H00"
    bytArray(2) = "&H00"
    bytArray(3) = "&H00"
Else
    bytArray(0) = "&H" + Mid(strSource, 7, 2)
    bytArray(1) = "&H" + Mid(strSource, 5, 2)
    bytArray(2) = "&H" + Mid(strSource, 3, 2)
    bytArray(3) = "&H" + Mid(strSource, 1, 2)
End If
 
CopyMemory sngResult, bytArray(0), 4
 
Worksheets(1).Cells(2, 4).Value = sngResult
 
End Sub

Gruß Kai
 

Anhänge

  • Excel.zip
    28,8 KB · Aufrufe: 35
In Excel 2010 funktioniert das folgende VBA-Makro für die Umwandlung einer 32-Bit-Hexadezimalzahl (42F1A395) in eine
IEEE 754 32-Bit-Gleitpunktzahl (120,8194962):

Gruß Kai

Hi Kai,

:s12: :TOOL: :s12:

kann leider nur einmal Danke klicken, aber dafür ganz fest! Echt Hammer, habe gestern Abend noch angefangen es umzusetzen, habe es dann aber schnell bleiben lassen. Das Makro ist genau da, was ich suchte! Vielen Dank!!!

Woher weiß man sowas? ;)

Viele Grüße
Eric
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Eric,

es freut mich, wenn ich Dir helfen konnte. :)

Ich habe ich das VBA-Makro für Excel 2010 noch einmal leicht überarbeitet:

Code:
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
Sub HEX32_IEEE754_32()
 
' ==============================================
' Umwandlung
' 32-Bit-Hexadezimalzahl (42F1A395) in
' IEEE 754 32-Bit-Gleitkommazahl (120,8194962)
' ==============================================
 
Dim strSource As String
Dim bytArray(0 To 3) As Byte
Dim sngResult As Single
 
strSource = Worksheets(1).Cells(2, 2).Value
 
If strSource = "0" Then
    bytArray(0) = &H0
    bytArray(1) = &H0
    bytArray(2) = &H0
    bytArray(3) = &H0
Else
    bytArray(0) = CByte("&H" & Mid(strSource, 7, 2))
    bytArray(1) = CByte("&H" & Mid(strSource, 5, 2))
    bytArray(2) = CByte("&H" & Mid(strSource, 3, 2))
    bytArray(3) = CByte("&H" & Mid(strSource, 1, 2))
End If
 
CopyMemory sngResult, bytArray(0), 4
 
Worksheets(1).Cells(2, 4).Value = sngResult
 
End Sub

Gruß Kai
 

Anhänge

  • Excel.zip
    28,9 KB · Aufrufe: 22
Hallo Kai,

für mich als Laie noch eine Frage, was ist der Unterschied zwischen

Code:
....
    bytArray(0) = CByte("&H" & Mid(strSource, 7, 2))
....
und

Code:
....
  bytArray(0) = "&H" + Mid(strSource, 7, 2)
....

Viele Grüße und eine angenehme Nachtruhe
Eric
 
Hallo Eric,

Code:
"&H" + Mid(strSource, 7, 2) 
 
"&H" & Mid(strSource, 7, 2)

in beiden Programmzeilen werden zunächst zwei Zeichenfolgen miteinander verkettet.

In der ersten Programmzeile wird dabei der +-Operand verwendet und in der zweiten Programmzeile der &-Operand.

Mit dem +-Operand kann man Zahlen addieren, man kann aber auch Zeichenfolgeoperanden miteinander verketten.

Der &-Operand wird nur für String-Operanden definiert und seine Operanden werden immer zum String-Datentyp erweitert.

Man sollte also bei der Verkettung von Zeichenfolgen den &-Operand verwenden, weil er nur für Zeichenketten definiert ist und das
Risiko einer unbeabsichtigten Konvertierung verringert.

Code:
"&H" + Mid(strSource, 7, 2)
 
CByte("&H" & Mid(strSource, 7, 2))

Anschließend erfolgt in der zweiten Programmzeile eine Typkonvertierung der Zeichenfolge in ein Byte-Datentyp.

Code:
Dim bytArray(0 to 3) As Byte
 
bytArray(0) = "&H" & Mid(strSource, 7, 2)
 
bytArray(0) = CByte("&H" + Mid(strSource, 7, 2))

Und zum Schluss erfolgt in beiden Programmzeilen eine Zuweisung zu einem Array-Element vom Byte-Datentyp.

In der ersten Programmzeile kommt es durch die Zuweisung zu einer Typkonvertierung. Die Zeichenkette wird durch die Zuweisung
zum Byte-Datentyp erweitert und dann dem Array-Element vom Byte-Datentyp zugewiesen.

In der zweiten Programmzeile wurde die Typkonvertierung bereits durch die CByte-Funktion durchgeführt. Es erfolgt nur noch eine Zuweisung der Zeichenkette als Byte-Operanden zum Array-Element vom Byte-Datentyp.

Zusammenfassung:

Man kann sowohl den Programmcode aus der ersten Programmzeile als auch den Programmcode aus der zweiten Programmzeile verwenden.

"Sauberer" programmiert ist meiner Meinung nach aber der Programmcode aus der zweiten Programmzeile.

Gruß Kai
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe das VBA-Makro für Excel 2010 noch einmal überarbeitet:

Code:
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
 
Sub HEX32_IEEE754_32()
 
' =============================================
' Umwandlung
' 32-Bit-Hexadezimalzahl (42F1A395) in
' IEEE 754 32-Bit-Gleitkommazahl (120,8194962)
' =============================================
 
Dim strSource As String
Dim bytArray(0 To 3) As Byte
Dim sngResult As Single
Dim intCounter As Integer
 
' 32-Bit-Hexadezimalzahl aus Excel-Tabelle lesen
strSource = Worksheets(1).Cells(2, 2).Value
 
' 32-Bit-Hexadezimalzahl mit führenden Nullen auffüllen
For intCounter = 1 To 8 - Len(strSource)
    strSource = "0" & strSource
Next intCounter
 
' 32-Bit-Hexadezimalzahl in Byte-Array umwandeln
' bei der Umwandlung die Reihenfolge der Bytes tauschen
bytArray(0) = CByte("&H" & Mid(strSource, 7, 2))
bytArray(1) = CByte("&H" & Mid(strSource, 5, 2))
bytArray(2) = CByte("&H" & Mid(strSource, 3, 2))
bytArray(3) = CByte("&H" & Mid(strSource, 1, 2))
 
' 32-Bit-Hexadezimalzahl in IEEE 754 32-Bit-Gleitpunktzahl umwandeln
CopyMemory sngResult, bytArray(0), 4
 
' IEEE 754 32-Bit-Gleitpunktzahl in Excel-Tabelle schreiben
Worksheets(1).Cells(2, 4).Value = sngResult
 
End Sub

In den Programmcode habe ich eine zusätzliche Abfrage für die Länge der von der Excel-Tabelle eingelesenen Zeichenkette eingefügt.
Wenn die Zeichenkette weniger als 8 Zeichen lang ist, wird die Zeichenkette mit führenden Nullen als Zeichen aufgefüllt.

Code:
' 32-Bit-Hexadezimalzahl mit führenden Nullen auffüllen
For intCounter = 1 To 8 - Len(strSource)
    strSource = "0" & strSource
Next intCounter
 
Beispiel:
 
42F1A395 -> Länge 8 Zeichen
 
 2F1A395 -> Länge 7 Zeichen -> 02F1A395

Wenn die Zeichenkette weniger als 8 Zeichen lang wäre und nicht mit führenden Nullen als Zeichen aufgefüllt werden würde,
würde es zu Problemen mit der Mid-Funktion bei der nachfolgenden Umwandlung der Zeichenkette in ein Byte-Array kommen.

Code:
' 32-Bit-Hexadezimalzahl in Byte-Array umwandeln
' bei der Umwandlung die Reihenfolge der Bytes tauschen
bytArray(0) = CByte("&H" & Mid(strSource, 7, 2))
bytArray(1) = CByte("&H" & Mid(strSource, 5, 2))
bytArray(2) = CByte("&H" & Mid(strSource, 3, 2))
bytArray(3) = CByte("&H" & Mid(strSource, 1, 2))

Gruß Kai
 

Anhänge

  • Excel.zip
    28,5 KB · Aufrufe: 23
Zurück
Oben