handling binary data in vb.net

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kboyd
    New Member
    • Aug 2009
    • 6

    handling binary data in vb.net

    Dear all, I'm new to the forum, I'm really sorry if this has appeared elsewhere. I'm not really a programmer and am having major difficulties handling a binary stream which I am trying to read and process in vb.net.

    The stream is coming in from an FTDI chip and should contain 64 8-bit values.

    An example of the stream is here
    ÿÿÿÿ²ÛÿÿލïÿŒ©÷ ÿÿÿ»¡ÿÿþÄÿÿÿÿÿÿ ÿÿÿÿÿÿ¬¬ùÿ‚ ïÿ…™Òÿÿí¡ÿÙ¶ÿ ÿÿÿÿÿÿÿ

    I need to get this into something that I can read (decimal or hex or 1s and 0s) in vb and I just don't know what to do - I tried using Asc() but it wasn't working and I know now that it can't work with characters higher than 127.

    I am running really short of time and am desperate - any help will be massively appreciated!

    Thanks very much, Ken
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    How about hex?
    Learn how to convert between hexadecimal strings and numeric types. See code examples and view additional available resources.

    Comment

    • kboyd
      New Member
      • Aug 2009
      • 6

      #3
      Thanks very much but I've managed to get it working converting these characters to 1s and 0s - in principle this is fine for me.

      I'm using this function:

      Code:
      Public Function TextToBinary(ByVal Text As String, Optional ByVal Separator As String = "  ") As String
              MsgBox(Len(Text))
              Dim oReturn As New StringBuilder
              Dim count As Integer
              count = 0
              oReturn.Remove(0, oReturn.Length)
      
              ' Convert all the bytes
              For Each Character As Byte In UTF8Encoding.UTF8.GetBytes(Text)
                  count = count + 1
                  oReturn.Append(Convert.ToString(Character, 2).PadLeft(8, "0"))
                  oReturn.Append(Separator)
              Next
      
              MsgBox(count)
              Return oReturn.ToString
          End Function
      The only problem is that I'm getting more bytes once converted than what I shoudl have - the reading coming in has 64 pieces of data and yet I seem to be getting on average about 120 once I've translated them. Even the input string doesn't seem to always be the same length although it always has fewer characters than what I'm outputting.

      The input string of characters is:
      Ö´ÿÿÿÿÿÿÿÿ
      èöÿÿ—¸àÿ~’Ëÿ‚˜× ÿÿÿ¯žÿÿ÷Èÿÿÿÿÿÿ ÿÿðÿÿÿ••âÿv’Þÿ~ “Éÿÿé* (which is 63 characters)

      The output in binary is:
      11000011 10010110 11000010 10110100 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 00001101 11000011 10101000 11000011 10110110 11000011 10111111 11000011 10111111 11100010 10000000 10010100 11000010 10111000 11000011 10100000 11000011 10111111 01111110 11100010 10000000 10011001 11000011 10001011 11000011 10111111 11100010 10000000 10011010 11001011 10011100 11000011 10010111 11000011 10111111 11000011 10111111 11000011 10111111 11000010 10101111 11000101 10111110 11000011 10111111 11000011 10111111 11000011 10110111 11000011 10001000 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10111111 11000011 10110000 11000011 10111111 11000011 10111111 11000011 10111111 11100010 10000000 10100010 11100010 10000000 10100010 11000011 10100010 11000011 10111111 01110110 11100010 10000000 10011001 11000011 10011110 11000011 10111111 01111110 11100010 10000000 10011100 11000011 10001001 11000011 10111111 11000011 10111111 11000011 10101001 11000010 10100000 00100000 (which is 128 bytes)

      Does anyone have any ideas - I'm just really struggling here!

      Thanks, Ken
      Last edited by tlhintoq; Aug 13 '09, 04:30 PM. Reason: [CODE] ...your code goes here... [/CODE] tags added

      Comment

      • tlhintoq
        Recognized Expert Specialist
        • Mar 2008
        • 3532

        #4
        Does anyone have any ideas - I'm just really struggling here!
        The input string of characters is:
        You can't work it from a string. All it takes is for some of your "characters " to be the "backspace" or "delete" and your are screwed.
        You need to read the chip as a series of bytes (8 bits is a byte) and just work with bytes. I do the same thing with RFID wristbands.

        Comment

        • kboyd
          New Member
          • Aug 2009
          • 6

          #5
          Thanks very much once again - ok, this sounds good - can you give me a pointer about how to do this - I'm a bit out of my depth here! I really appreciate your help. Thanks, Ken

          Comment

          • tlhintoq
            Recognized Expert Specialist
            • Mar 2008
            • 3532

            #6
            I don't do VB. I code in C# so I can't give you much for code.
            But let's start with you showing me how you are reading the file. The code snippet above is just about converting text once you have it read the file.

            Comment

            • kboyd
              New Member
              • Aug 2009
              • 6

              #7
              Please use [CODE] tags

              ok, I just wrote a reply and then it logged me out - so here goes again!!
              Thanks so much for your help.

              I have realised that the functions I am using to read the string in are clearly not workign although they are FTDI examples that I have adapted. Here they are:

              Code:
               '//Write string data to device
                      Dim sendd As String
                      sendd = TextBox4.Text + vbCr 'must add a line feed at the end of this
                      FT_Status = FT_Write_String(FT_Handle, sendd, Len(sendd), BytesWritten)
                      chksend.Checked = True
                      If FT_Status <> FT_OK Then
                          Exit Sub
                      End If
              
                      '//Wait()
                      Sleep(100)
              
                      ' //Get number of bytes waiting to be read
                      FT_Status = FT_GetQueueStatus(FT_Handle, FT_RxQ_Bytes)
                      If FT_Status <> FT_OK Then
                          Exit Sub
                      End If
              
              
                      ' //Read number of bytes waiting
                      ' //Allocate string to recieve data
                      TempStringData = Space(FT_RxQ_Bytes + 1)
                      MsgBox(FT_RxQ_Bytes)
                      FT_Status = FT_Read_String(FT_Handle, TempStringData, FT_RxQ_Bytes, BytesRead)
                      If FT_Status <> FT_OK Then
                          Exit Sub
                      End If
              That msgbox is showing that the amount of data it reckons is there - is coming in but when I poll this com port in hyperterminal I am getting 64 bytes every time, so there is clearly something wrong there.

              Incidentally, I tried encoding in unicode and it seems almost right although it is adding a byte of zeros in between each character - not a big deal though!

              What do you reckon?

              Thanks for your help again!
              Last edited by tlhintoq; Aug 13 '09, 05:16 PM. Reason: [

              Comment

              • tlhintoq
                Recognized Expert Specialist
                • Mar 2008
                • 3532

                #8
                I have realised that the functions I am using to read the string in are clearly not workign
                Well... That's seems like a good place to start. Garbage in, garbage out as the old saying goes.
                although they are FTDI examples that I have adapted.
                Code:
                 '//Write string data to device
                This looks like a C# comment, that you turned into a VB comment.
                Are the FTDI examples in C#?

                Comment

                • kboyd
                  New Member
                  • Aug 2009
                  • 6

                  #9
                  These comments and all code came straight from FTDI - I guess they may have just been lazy and copied them over each time!

                  Ok, I've made some progress - I realised that I wasn't letting it wait long enough between write and read! Now, I have it producing reliably 64 bytes of data and the carriage return.

                  Using the unicode encoding, I think the conversion is almost right, but it puts a spare byte in between each one - most of the time this is 00000000 but sometimes it is something else.

                  Here is the code that I am using in its present state:
                  For Each Character As Byte In UnicodeEncoding .Unicode.GetByt es(Text)
                  count = count + 1
                  oReturn.Append( Convert.ToStrin g(Character, 2).PadLeft(8, "0"))
                  oReturn.Append( Separator)
                  Next

                  Here is an example of the output:
                  11000110 00000010 00011100 00100000 10110110 00000000 11111111 00000000 01011010 00000000 01110000 00000000 01100000 00000001 11100000 00000000 01001110 00000000 01011100 00000000 10000001 00000000 11101000 00000000 01010100 00000000 01100011 00000000 01010010 00000001 11111011 00000000 11111111 00000000 10101100 00000000 01110110 00000000 01101010 00000000 11111111 00000000 11001001 00000000 10101001 00000000 00110000 00100000 11111111 00000000 11111111 00000000 11111111 00000000 11011100 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 10001101 00000000 11011100 00000010 11001101 00000000 11111111 00000000 01011010 00000000 01011011 00000000 11000110 00000010 11011110 00000000 01001001 00000000 01011010 00000000 00100001 00100000 11011001 00000000 01010010 00000000 01011110 00000000 01111111 00000000 11011010 00000000 11110000 00000000 00010011 00100000 01101001 00000000 01100001 00000000 01100001 00000000 10101110 00000000 11011100 00000010 10000001 00000000 11111111 00000000 11111111 00000000 11011011 00000000 11101100 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 00000000 00001101 00000000 00100000 00000000

                  Does this make any sense to you?
                  Thanks again, finally some progress!!! Ken

                  Comment

                  • tlhintoq
                    Recognized Expert Specialist
                    • Mar 2008
                    • 3532

                    #10
                    Does this make any sense to you?
                    Doing all of this conversion to text, then to a string representation of binary doesn't make sense to me. I see no reason to introduce all these places where something gets translated and you are reliant on someone else's code.

                    Using the unicode encoding, I think the conversion is almost right, but it puts a spare byte in between each one
                    Of course it does. Unicode is a two byte encoding scheme for text. It's how we have these huge alphabets that can read from right to left, or Japanese Kanji. You use two bytes to represent a letter.

                    You said yourself that you only have 64 bytes of data. Just read in 64 bytes from the reader. In this example when the serial port ("MyPort") raises an event that data has been received we read all the bytes into a byte array ("ReadBytes" ). No conversion. Throughout the application I only ever work with the bytes. Each byte has a value 0-255 which can be represented however you like: As a decimal number... has a binary string... has a hex... That's up to you. But I don't tamper with the actual bytes that were read. Make copies in other representations if you like, but don't be destructive with the original data.

                    Code:
                            void MyPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
                            {
                                MyPort.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(MyPort_DataReceived);
                                // We don't need to respond while we are still processing
                    
                                try
                                {
                                    int ByteCount = MyPort.BytesToRead;
                                    byte[] ReadBytes = new byte[ByteCount];
                                    for (int Index = 0; Index < ByteCount; Index++)
                                    {
                                        ReadBytes[Index] = (byte)MyPort.ReadByte();
                                    }
                                    BytesReadIn = ReadBytes;// BytesReadIn is a global that gets set to the local ReadBytes
                                }
                                catch (TimeoutException) { }
                    }

                    Comment

                    • tlhintoq
                      Recognized Expert Specialist
                      • Mar 2008
                      • 3532

                      #11
                      An example of the stream is here
                      ÿÿÿÿ²ÛÿÿލïÿŒ©÷ ÿÿÿ»¡ÿÿþÄÿÿÿÿÿÿ ÿÿÿÿÿÿ¬¬ùÿ‚ ïÿ…™Òÿÿí¡ÿÙ¶ÿ ÿÿÿÿÿÿÿ
                      No. This is not an example of the byte stream. It is an attempt to translate the bytes into a human readable alphabet. The data itself is a bunch of bytes from 0-255

                      Comment

                      • kboyd
                        New Member
                        • Aug 2009
                        • 6

                        #12
                        tlhintoq, thank you so much. As I explained before, I am a bit out of my depth here, but clearly reading it in as a string was the wrong way to go - it is changed to bytes now and as you said, there are no conversion errors - so clearly that was my problem all along! I now have 64 beautiful bits of data coming in reliably and giving the correct readings!

                        Thank you for all your help yesterday, it is really really appreciated! Now to tidy up and make it all look pretty!!! Cheers, Ken

                        Comment

                        • tlhintoq
                          Recognized Expert Specialist
                          • Mar 2008
                          • 3532

                          #13
                          Glad it all worked out for you. Don't be a stranger... just be stranger than most

                          Comment

                          • raids51
                            New Member
                            • Nov 2007
                            • 59

                            #14
                            If you're getting it from a stream into a byte array it is fairly easy, just use hex to read it. I'll give you a short little tutorial if you want to read it lol. Basically with binary there's a few things you might want to do with it:

                            1. Get the value of individual bytes
                            This is useful if you want the value of for example byte 16. If you would want to check if byte 16 = FF in hex then you could use
                            Code:
                            If Bytes(16) = "&HFF" then
                            Msgbox("Byte 16 = FF")
                            end if
                            Where bytes() is your byte array from the stream and 16 is the byte

                            2. Convert a byte array into ASCII text
                            This is useful if you want to convert the bytes from the stream into a byte array and then a steam.
                            you could use System.text.enc oding.ascii.get strings(ByteArr ray)

                            3. Get an integer value from a byte array
                            This is used to read numbers from a stream.
                            Dim Number as integer
                            Number = bitconverter.to int32(ByteArray ,0)
                            This code would read the first 4 bytes from the byte array and convert it into an integer for you. You could also do the reverse with bitconverters.

                            I have quite a bit of experience with binary in vb.net, but i suck at explaining some things lol. So if you need more help or more info about anything binary in vb.net you can message me and ill try my best to help you. Happy coding ;)
                            Last edited by tlhintoq; Aug 18 '09, 05:40 PM. Reason: you're not your, I'll not lll, capitalization,

                            Comment

                            Working...