How to receive binary data in VB6?

Posted on 2005-05-04
Last Modified: 2010-05-18
I can receive ascii-formatted integers without a problem - I just want to avoid the overhead of formatting on my embedded PIC microprocessor & I the overhead of extracting the data back into integer form at the PC end.  
I've set MScomm.InputMode to binary, and the Rthreshold to 10 bytes (0 because I have 5 channels worth of 16 bit data)
Every string received is minced: its either the null string"", or "?????"

Private Sub MSComm1_OnComm()    
    Dim i As Integer
    Dim InBufferCount As Integer
    Dim Tmp As Integer
    UploadData As String ' I've tried Byte and Variant. A byte array might work, but I don't know how to copy a String into a
                                   ' Byte array  
   InBufferCount = MSComm1.InBufferCount ' is 10 only if inputMode is set to Text
    UploadData = MSComm1.Input ' copy Input in case it gets overwritten by more incoming data
    For i = 0 To 4 ' 5 channels of 16 bit data - haven't included the stuff to combine the hi & lo bytes.
' this is the bit that doesn't work....
        'Tmp = Val(Mid(UploadData, i, 1)) ' Tmp and Val give a type mismatch - can't seem to extract the data from the sub
                                                          ' string from Mid(UploadData, i, 1))
        Ch(i).Text = MidB(UploadData, (2 * i) + 1, 1) * 256   ' this works but only
                                                          ' when  UploadData contain Text rather than binary
    Next i

'End Sub

Any ideas?
Question by:KenMac06
    LVL 13

    Expert Comment

    Um, if the data is coming as a binary (byte), then you'll need to convert the string, try

    bytValue = Asc(Mid(UploadData,i,1))  (will return a byte in the range 0 - 254)

    For 5 channels of 16 bit data, you should however do it more like this:
    For i = 0 to 4
      intValue = Asc(Mid(UploadData, i*2, 1)) * 256 + Asc(Mid(UploadData, i*2 + 1, 1))
    (possibly swap high and low bytes, I'm not certain)

    This is assuming you're receiving the data correctly (i.e. speed, stopbits, parity all correct; which I assume since you were able to get text data).

    LVL 13

    Expert Comment

    "intValue" = the value for the channel, i.e. save it in an array or something; the way it is here it will be overwritten each time :)

    Author Comment

    The first problem is that UploadData is not getting the data - it seems as if, because its defined as a string, it will treat any 0 in the binary stream as a null terminator, and hence return "".  
    LVL 23

    Expert Comment


    Input Property
    Returns and removes a stream of data from the receive buffer. This property is not available at design time and is read-only at run time.

    The Input property syntax has these parts:
    Part Description
    object An object expression that evaluates to an object in the Applies To list.

    The InputLen property determines the number of characters that are read by the Input property. Setting InputLen to 0 causes the Input property to read the entire contents of the receive buffer.

    The InputMode property determines the type of data that is retrieved with the Input property. If InputMode is set to comInputModeText then the Input property returns text data in a Variant. If InputMode is comInputModeBinary then the Input property returns binary data in an array of bytes in a Variant.

    Author Comment

    "If InputMode is comInputModeBinary then the Input property returns binary data in an array of bytes in a Variant." Does that mean that I have to copy the bytes from .Input,  one at a time, or is there a way to pass a pointer to a byte array, and copy a message-worth at a time? i.e. can I avoid having to  take over the responsibility of managing the input buffer?
    LVL 13

    Accepted Solution

    Sorry, my mistake -- don't use strings when retrieving binary data, use arrays of byte

    Something like this:
    dim intData%(0 to 4)
    dim bytInput() as Byte

       InBufferCount = MSComm1.InBufferCount ' is 10 only if inputMode is set to Text
       ' should be 10, if you're waiting for 5 words
      bytInput = MSComm1.Input ' make sure inputMode is set to binary
      if InBufferCount <> 10 then exit sub ' throw error, whatever, something's fishy :)

      for i = 0 to 4
        intData(i) = bytInput( i*2 +1 ) * 256 + bytInput(i*2)

    One issue you'll need to cover: synchronisation! When do you start recieving? when do you stop? Do you always get 10 bytes? What happens when one byte goes missing or is corrupted in transmission? This will all depend a bit on your setup, I can't imagine that the input is just 5 words without any start/stop information :). Capturing the binary input from the serial port is the easy part, syncing it to the desired channels could be tougher - meaning you'll probably need to manage the input buffer yourself and read the values byte by byte, determine start/stop and somehow check for impossible values (meaning corrupted or missing bytes). A good idea would be to add some sort of simple start/stop information (for example 5x 0), a simple checksum (just xor the 5 words and pass that on the end). That way you know where to start recieving data, if data has been corrupted on the way - meaning you just collect valid data and throw the bad stuff away :)

    LVL 1

    Assisted Solution

    If you leave it as a string, do a UploadData = StrConv(UploadData, vbUnicode).  This will pad your binary string out with ascii 0's so that it is a normal string.  Then your Mid() stuff should work properly.  What you are seeing with the "?????" is 10 bytes of data being treated as 5 unicode bytes, since all strings in VB are unicode.

    Author Comment

    I gave up on binary - I too was worried about synchronisation and not being able to add a checksum.
    For the record, the overhead of formatting binary as ascii is insignificant (1 - 2 millisecs) in comparison to the time to transmit the bytes (1millisec/byte, so about 40 millisecs in all). That gets me 20 lots of samples per sec easily, and possibly 25. I'm digitising something with 5 shaft encoders, rather than a waveform against time, so it doesn't matter if I lose  the odd (set of) sample.
    So here is the non-binary message catcher, for the record...

    Private Sub MSComm1_OnComm()
    ' triggered by the arrival of 38 bytes 5 Channels worth of 16 bit samples, formatted as 5 ascii digits/chan, split up by commas.
    ' I use a timer to fire Q's out to a PIC micro, and it sends the data back. The two programs work in lock step.
    ' tried InputMode = Binary, to reduce the cpu overhead (no need to format the int16 as ascii),
    ' although it precludes software XOn/XOff flowcontrol or buffering
    ' However, UploadData was always "" or "?????"

    ' RThreshold = 10 for binary to suit the bare minumum packet size of 5 Channels worth of 16 bit samples
    ' Now 30 5 bytes/ch, comma delimiter after each field except for end of line <Cr><Lf>
    ' byte ordering:  Byte 0 = Ch(0)MSB...Byte 9:= Ch(4)LSB

    ' Comes into this Sub when MSComm1.InBufferCount = RThreshold i.e. 10 chars...
        Dim InBufferCount As Integer ' mostly just for checking in debugger to see how much data I've got
        'Dim Finish As Single
        Dim TmpString(5), T As String
        Dim i As Integer
        ' Dim Chan(5) As Integer ' Ch is the control - no need for Chan.
        Dim Tmp, Zsigned As Integer
        'Dim Period As Single
        Dim X, Z As Long
        'Finish = Timer   ' note end time.
        'Period = Finish - Start
        'txtPeriod.Text = Str(Period)
        InBufferCount = MSComm1.InBufferCount
        UploadData = MSComm1.Input ' copy Input in case it gets overwritten by more incoming data
        bReplyRxd = True
        For i = 0 To 4
            Ch(i).Text = Mid(UploadData, (6 * i) + 7, 5) ' String elements start at 1, not 0
                                                                            ' 6* because each field is delimited by a "," for readability
        Next i
    End Sub

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    Suggested Solutions

    Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
    If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
    Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
    In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    19 Experts available now in Live!

    Get 1:1 Help Now