converting HEX string in .net

cmdolcet
cmdolcet used Ask the Experts™
on
How can I convert this HEX string to a readable result? I get this string returned from a device I am sending a function to. What can I use to parse and represent the actual result from the device?

HEX String
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ste5anSenior Developer

Commented:
Check your device's manual.

Cause if you really receive a string containing an hexadecimal value, then it should be documented. Otherwise, check your code. Do you convert the received bytes to an hexadecimal string yourself?

Your result contains 7 bytes, unusual, seems not to be a number otherwise it would be aligned.
Then the first four bytes are non-printable ASCII codes.
The last three would be ?9?, which makes not much sense also.
Shaun VermaakSenior Consultant
Awarded 2017
Distinguished Expert 2018

Commented:
Change your baud rate. I get those kinds of values when I use the incorrect one

Author

Commented:
Shaun that is the Baudrate specified by the vendor and it is also the corerct response.
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Author

Commented:
ste5an,

Looking more into it I wasn;t returning the correct amount of registers. So now the HEX string I get "01030600e300e300f814d7"

So how can I cover this into reading something?

I have attached their map but still do not know how to read this.ieeefloats.xls
ste5anSenior Developer

Commented:
22 bytes is still uncommon. Cause IEEE floats according to your specs are DWORDs, thus 4 bytes.

E.g. https://www.h-schmidt.net/FloatConverter/IEEE754.html

Author

Commented:
OK great ste5an!

So backing up I return a response in HEX with the following
01 03 02 00 CE 39 D0

I know the following of the message response
01 = Rank (always stays the same)
03 = command ( always stays the same)
02 = Byte length
00 = Part of the Temp Field
CE = Part of the Temp Field
39 = CRC
D0 = CRC

I need to pull out the  00 and the CE of the HEX response message and convert it to Decimal.  How can I always pull out these two fields in the HEX response message and convert to Decimal?
ste5anSenior Developer

Commented:
Now a completely new direction?

Okay, here we need to look at the device and how it transmits data. Thus we need to know: is a strict datagram protocol used or a plain-text protocol?

It looks like a datagram protocol (TLV: tag, length, value). This means that we need to start with the basics of serial communications:

1. Read data into a buffer.
2) Examine the buffer after read for complete datagrams.
3) In the case of incomplete datagrams, maybe request transmission again.
4) When a complete datagram is in the buffer (at the begin), remove it.
5) Handover the datagram for processing.

Author

Commented:
No not a completely different direction!... Just I understand a little better what I am reading from the device. In this example. I will only ever need to read the following

01 = Rank (always stays the same)
03 = command ( always stays the same)
02 = Byte length
00 = Part of the Temp Field
CE = Part of the Temp Field
39 = CRC
D0 = CRC

I need to read the 2 bytes after the length and before the CRC. and then convert them into decimal. That what I am looking for how to do that?
ste5anSenior Developer

Commented:
We need to start with the receiving code. What do you have so far?

Author

Commented:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If ComboBox1.SelectedIndex = -1 Then
            MessageBox.Show("Please select a port")
            Exit Sub
        Else
            SerialPort1.BaudRate = 9600
            SerialPort1.DataBits = 8
            SerialPort1.Parity = IO.Ports.Parity.None
            SerialPort1.StopBits = IO.Ports.StopBits.One
            SerialPort1.PortName = ComboBox1.SelectedItem.ToString
            serialport1.Open()
            'HEX values to read temperature 01 03 00 0E 00 01 E5 C9
            Dim bytes() As Byte = {&H1, &H3, &H0, &HE, &H0, &H1, &HE5, &HC9}
            serialport1.Write(bytes, 0, bytes.Length)
        End If

Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serialport1.DataReceived

        Dim rcv As String = serialport1.ReadExisting
        buffer = String.Concat(buffer, rcv)
        Dim hexVal As String = ""
        For Each c As Char In rcv
            hexVal = hexVal & AsciiCharToHexSring(c)
        Next

        MessageBox.Show(hexVal)

    End Sub

Open in new window

ste5anSenior Developer

Commented:
Nope. E.g.

Private Buffer As String

Private Sub SerialPort1_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles serialport1.DataReceived
    Dim datagram As String = Nothing

    Buffer = Buffer & serialport1.ReadExisting
    datagram = DequeueDatagram()
    Do While Not datagram Is Nothing
        HandleDatagram(datagram)
        datagram = DequeueDatagram()
    Loop
End Sub

Private Function DequeueDatagram() As String
    Dim valueLength As Long

    DequeueDatagram = Nothing
    If Buffer.Length > 3 Then
        valueLength = Asc(Mid(Buffer, 3, 1))
        If Buffer.Length >= 5 + valueLength Then
            DequeueDatagram = Mid(Buffer, 1, 5 + valueLength)
            If Buffer.Length = 5 + valueLength Then
                Buffer = ""
            Else
                Buffer = Buffer.Substring(5 + valueLength + 1)
            End If
        End If
    End If
End Function

Private Sub HandleDatagram(ADatagram As String)
    Dim datagramRank As Byte = Asc(ADatagram.Substring(0, 1))
    Dim datagramCommand As Byte = Asc(ADatagram.Substring(1, 1))
    Dim datagramLength As Byte = Asc(ADatagram.Substring(2, 1))
    Dim datagramValue() As Byte = Encoding.GetEncoding(1252).GetBytes(ADatagram.Substring(3, datagramLength))
    Dim datagramCrc() As Byte = Encoding.GetEncoding(1252).GetBytes(ADatagram.Substring(ADatagram.Length - 2, 2))

    Console.WriteLine(Hex(datagramRank))
    Console.WriteLine(Hex(datagramCommand))
    Console.WriteLine(Hex(datagramLength))
    Console.WriteLine(Hex(datagramCrc(0)))
    Console.WriteLine(Hex(datagramCrc(1)))
    Console.WriteLine(Hex(datagramValue(0)))
    Console.WriteLine(Hex(datagramValue(1)))
End Sub

Open in new window

Author

Commented:
My Example above was able to produce the HEX string inside a message box. I need help with converting the HEX to decimal.

Author

Commented:
OK let me look at the code. Losing my mind today.  Thank you very much!
ste5anSenior Developer

Commented:
And?? Did you read the manual at all? Cause the sample above returns two bytes as payload. Your IEEE sheet only describes four byte floats.

Just convert your number from datagramValue(0) and datagramValue(1) in your case.

Author

Commented:
Ste5an,

Running you code I am not getting the same values with a manufacture software example.  I notice you flipped the CRC position on the write. But my number are not matching the manufacture????

Author

Commented:
Ste5an, no manual at all. Again only what I have given above. I am not sure with your code as stated above why do you flip the Value and CRC position?

Not really following you on your code example. What is different from my example?

Author

Commented:
Looking at this further is it the encoding that is causing the issue? I think what you are using is a 32 versus 16?
ste5anSenior Developer

Commented:
I just changed the output order on the console, not the byte order (lines 35 and 36). What is the corresponding value according to the manufacturer's sample?

btw, what did they give you exactly?

Author

Commented:
Using the Manufacture Software I get the following

01  03  02  00 DE 38 1C

where 00 DE  = 222 dec which in there eyes equals 22.2 degrees Celsius.

Using your code I get the following in the console window:

01 03  02 3F 3F 00 3F
Capture.PNG
Senior Developer
Commented:
Please make yourself familiar with byte wise data transmission. The output is just a sample of the received data. YOU need to interpret it.

Without documentation it's hard to tell, but it seems like a simple decimal encoding. Thus you simply need to divide the integer value in the word transmitted by ten.

E.g.

Private Sub HandleDatagram(ADatagram As String)
    Dim datagramCommand As Byte = Asc(ADatagram.Substring(1, 1))

    'TODO: CRC-Check.
    'IF IsValidCrc(ADatagram) Then
        Select Case datagramCommand
        Case Is = 3
            HandleDatagrammCommand3 ADatagram
        Case Else
            Console.WriteLine("Unkown datagram type.")
        End Select
    'Else
    '    Console.WriteLine("Incorrect CRC.")
    'End If

End Sub

Private Sub HandleDatagrammCommand3(ADatagram As String)
'Implement a separate handler for each datagram type.
    Dim datagramCommand As Byte = Asc(ADatagram.Substring(1, 1))
    Dim datagramLength As Byte = Asc(ADatagram.Substring(2, 1))
    Dim datagramValue() As Byte = Encoding.GetEncoding(1252).GetBytes(ADatagram.Substring(3, datagramLength))
    Dim value As Long = datagramValue(0) * 256 + datagramValue(1)

    If datagramCommand = 3 Then
        If  datagramLength = 2 Then
            Console.WriteLine("Temprature is {0}°.", value / 10)
        Else
            'Throw excption or other kind of error handling
            Console.WriteLine("Incorrect datagram length.")
        End If
    Else
        Console.WriteLine("Incorrect datagram type.")
    End If

End Sub

Open in new window

Author

Commented:
Yes thank you but my problem is HEX return compared from the device from the manufacture software and the HEX code you provided

01  03  02  00 DE 38 1C

Using your code I get the following in the console window:

01 03  02 3F 3F 00 3F

My issue is the same conditions are present and their program returns  00 DE and the code you provided returns 00 3F

Author

Commented:
Ste5an

Anymore Ideas on how the code you gave  has different return values:

Yes thank you but my problem is HEX return compared from the device from the manufacture software and the HEX code you provided

01  03  02  00 DE 38 1C

Using your code I get the following in the console window:

01 03  02 3F 3F 00 3F

My issue is the same conditions are present and their program returns  00 DE and the code you provided returns 00 3F

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial