Modbus - DWORD in DEZ umwandeln klappt nicht

  • VB.NET

Es gibt 36 Antworten in diesem Thema. Der letzte Beitrag () ist von Murdersquad.

    Aus 436AE78E soll 234.90451 werden


    436AE78E ergibt sowohl im Windows Rechner als auch mit

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Module Module1
    4. Sub Main()
    5. Dim t$ = "00 03 00 00 00 07 FF 03 04 43 6A E7 8E"
    6. Dim z As UInteger = 0 'DWord
    7. Dim E$ = ""
    8. t = t.Replace(" ", "")
    9. t = t.Substring(t.Length - 8, 8)
    10. z = Convert.ToUInt32(t, 16)
    11. E = (z / 1000).ToString("#,###.000")
    12. Debug.Print(E)
    13. End Sub
    14. End Module


    1.131.079.566
    Jetzt habe ich nichts zum Testen, aber ich denke, dass ich es dann so machen müsste:

    VB.NET-Quellcode

    1. Dim ReceiMsgArray() As String = txtReceiMsg.Text.Trim.Split(" "c)
    2. Dim RcvMsg2Byte As Byte = Convert.ToByte(ReceiMsgArray)
    3. Dim Last4Bytes() As Byte = {RcvMsg2Byte}
    4. Label1.Text = BitConverter.ToDouble(Last4Bytes, 0).ToString


    Werde es später mal testen. Es sei denn, jemand sieht direkt einen Fehler. Könnte wahrscheinlich auch Convert.FromBase64String nutzen.


    @Eierlein:
    Ja, das Format wäre dann Float - Big Endian (ABCD) und nicht mehr INT32 - Big Endian (ABCD).

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Murdersquad“ ()

    Murdersquad schrieb:

    Werde es später mal testen.
    Erst testen, dann posten.
    Dein Code läuft nicht:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Eierlein schrieb:

    436AE78E ergibt im Windows Rechner ... 1.131.079.566

    Man muss hier glaube ich wissen, dass der Hex-Wert einen 4 Byte Floating Wert (Single) darstellen soll.
    Wenn du es in FloatToHex eingibst, kommt das gewünschte Ergebnis raus.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Double wäre: 5.588275563e-315

    Richtig ist Single.

    So sehen die unterschiedlichen Werte aus:

    Quellcode

    1. HEX : 436AE78E
    2. Double: 5.58827556273627E-315
    3. Single: 234.9045
    4. Dword : 1131079566
    5. Word : 59278
    6. Long : 1131079566

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Eierlein“ ()

    Ein Zahlensystem Konverter.

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System
    4. Imports System.Runtime.InteropServices
    5. <StructLayout(LayoutKind.Explicit)> _
    6. Public Structure Union
    7. <FieldOffset(0)> Public i As Integer
    8. <FieldOffset(0)> Public s As Single
    9. <FieldOffset(0)> Public d As Double
    10. <FieldOffset(0)> Public l As Long
    11. End Structure
    12. Module Module1
    13. Sub Main()
    14. Dim u As Union
    15. u.i = &H436AE78E
    16. Debug.Print("Hex : " & u.i.ToString("X8"))
    17. Debug.Print("")
    18. Debug.Print("Ingeger: " & u.i.ToString)
    19. Debug.Print("Single : " & u.s.ToString)
    20. Debug.Print("Double : " & u.d.ToString)
    21. Debug.Print("Long : " & u.l.ToString)
    22. End Sub
    23. End Module


    Kann selbstverständlich erweitert werden.

    Quellcode

    1. █▀▀▀ ▀ █ ▀
    2. █▄▄ ▀█ ▄▀▀▄ █▄▀▄ █ ▄▀▀▄ ▀█ █▄▀▀▄
    3. █ █ █▀▀▀ █ █ █▀▀▀ █ █ █
    4. ▀▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀

    Eierlein schrieb:

    Ein Zahlensystem Konverter.
    Diese Bezeichnung ist nicht korrekt, da in diesem Sinne nichts konvertiert wird.
    Die Binärdarstellung des Zahlenwertes eines Typs wird als Binärdarstellung des Zahlenwertes eines anderen Typs interpretiert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe es mal wie unten geschrieben gelöst und komme zum gewünschten Ergebnis.
    Natürlich habe ich während der Versuche ein weiteres Problem entdeckt.
    Es gibt einen Wert, der lt. Hersteller im Double-Format (Überlauf 1.0e+12) ausgegeben wird.

    Double bedeutet dann, dass ich 8 Bytes habe... Als Rückgabe vom Gerät erhalte ich "43 69 F1 80 43 69 36 5D". Umgewandelt sollte 938,xxx herauskommen.
    Ich kriege alles mögliche raus, nur nicht die 938,xxx.

    Gibt es einen Online Konverter hex to double, ähnlich dieser Seite?
    scadacore.com/tools/programming-calculators/online-hex-converter/

    Oder weiß eventuell jemand, wie die Byte-Reihenfolge lautet?

    "0 1 2 3 4 5 6 7" und "7 6 5 4 3 2 1 0" und andere Sachen klappen schon mal nicht...

    VB.NET-Quellcode

    1. Dim ReceiMsgArray() As String = txtReceiMsg.Text.Trim.Split(" "c)
    2. Dim Byte1 As String = ReceiMsgArray(9) 'Kannst hier natürlich auch variabel die Länge abfragen, falls dein Byte-Array nicht immer gleich lang ist
    3. Dim Byte2 As String = ReceiMsgArray(10)
    4. Dim Byte3 As String = ReceiMsgArray(11)
    5. Dim Byte4 As String = ReceiMsgArray(12)
    6. Dim Last4Bytes As String = Byte4 & Byte3 & Byte2 & Byte1
    7. Dim l4b2sngl As Byte() = New Byte(Last4Bytes.Length / 2 - 1) {}
    8. For i As Integer = 0 To l4b2sngl.Length - 1
    9. l4b2sngl(i) = Convert.ToByte(Last4Bytes.Substring(i * 2, 2), 16)
    10. l4b2sngl(l4b2sngl.Length - i - 1) = Convert.ToByte(Last4Bytes.Substring(i * 2, 2), 16)
    11. Next
    12. Dim wert As Single = BitConverter.ToSingle(l4b2sngl, 0)
    13. txtTest1.Text = wert.ToString("#.000")


    so sieht meine einzige Anpassung für Double aus:

    VB.NET-Quellcode

    1. Dim wert As Double = BitConverter.ToDouble(l4b2sngl, 0)
    2. txtTest1.Text = wert.ToString("#.000")

    Murdersquad schrieb:

    Oder weiß eventuell jemand, wie die Byte-Reihenfolge lautet?
    Mach das doch einfach anders herum: Double to Byte, allerdings solltest Du den Double-Wert genau kennen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mittels Bitconverter bekommt man anscheinend nur 4 Nachkommastellen:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Module Module1
    3. Sub Main()
    4. Dim t$ = "43 6A E7 8E"
    5. Dim b As Byte() = {0, 0, 0, 0}
    6. Dim ReceiMsgArray() As String = t.Split(" "c)
    7. b(0) = Convert.ToByte(ReceiMsgArray(3), 16)
    8. b(1) = Convert.ToByte(ReceiMsgArray(2), 16)
    9. b(2) = Convert.ToByte(ReceiMsgArray(1), 16)
    10. b(3) = Convert.ToByte(ReceiMsgArray(0), 16)
    11. Dim wert As Single = BitConverter.ToSingle(b, 0)
    12. t = wert.ToString("#.00000")
    13. Debug.Print(wert)
    14. End Sub
    15. End Module
    16. ' Ergebnis 234.9045


    Aber

    Mittels der Struct UNION und dem Formatzeichen "G9" erhälst du 234,90451

    Quellcode

    1. ___ _ _ _
    2. | __| (_) ___ _ _ | | ___ (_) _ _
    3. | _| | | / -_) | '_| | | / -_) | | | ' \
    4. |___| |_| \___| |_| |_| \___| |_| |_||_|
    Ich habe es, dank eurer Hilfe, gelöst.
    Es sieht wie folgt aus:

    VB.NET-Quellcode

    1. Dim ReceiMsgArray() As String = txtReceiMsg.Text.Trim.Split(" "c)
    2. Dim b As Byte() = {0, 0, 0, 0, 0, 0, 0, 0}
    3. b(0) = Convert.ToByte(ReceiMsgArray(16), 16)
    4. b(1) = Convert.ToByte(ReceiMsgArray(15), 16)
    5. b(2) = Convert.ToByte(ReceiMsgArray(14), 16)
    6. b(3) = Convert.ToByte(ReceiMsgArray(13), 16)
    7. b(4) = Convert.ToByte(ReceiMsgArray(12), 16)
    8. b(5) = Convert.ToByte(ReceiMsgArray(11), 16)
    9. b(6) = Convert.ToByte(ReceiMsgArray(10), 16)
    10. b(7) = Convert.ToByte(ReceiMsgArray(9), 16)
    11. Dim wert As Double = BitConverter.ToDouble(b, 0)
    12. Dim calc As Double = wert / 1000
    13. txtTest1.Text = calc.ToString("#.000")