Receiving series of Bytes in Visual Basic - Programmer

This is a discussion on Receiving series of Bytes in Visual Basic - Programmer ; Hi, I have some problem to receive series of Bytes using MSComm in Visual Basic. If anyone could help me, I am so grateful to you. I am trying to receive series of Bytes from a PIC16F877. These bytes are ...

+ Reply to Thread
Results 1 to 9 of 9

Thread: Receiving series of Bytes in Visual Basic

  1. Receiving series of Bytes in Visual Basic

    Hi,

    I have some problem to receive series of Bytes using MSComm in Visual
    Basic. If anyone could help me, I am so grateful to you.

    I am trying to receive series of Bytes from a PIC16F877. These bytes
    are generated by an image sensor and stored in a SRAM, the PIC get
    each bytes and send it through USART. The total number of bytes is
    16384, but I am getting just less than that (the total number is
    varying). The following code is the part of Visual Basic programme to
    receive these bytes.

    ---------------------------------------------------------------------
    Public a, b, c as Integer

    Private Sub CmdImage_Click()
    MScomm1.RThreshold=1
    a = 0
    b = 0
    c = 0
    End Sub


    Private Sub MSComm1_OnComm()
    Dim pix As Integer
    If a > 127 Then
    a = 0
    b = b + 1
    End If
    a = a + 1
    c = c + 1
    If (a < 128 And b < 128) Then
    If MSComm1.CommEvent = comEvReceive Then
    data = MSComm1.Input
    pix = Asc(data)
    Picture1.PSet (a * Picture1.DrawWidth, b *
    Picture1.DrawWidth), RGB(pix, pix, pix)
    End If
    End If
    MSComm1.InBufferCount=0
    Text2.Text = b ' Number of Lines
    Text3.Text = c ' Total number of Bytes
    End Sub

    ---------------------------------------------------------------------------

    I believe the VB programme couldn't detect some of the Bytes. I have
    tried my circuit with HyperTerminal, I am getting right number of
    bytes.

    Thanks for your time,

    T.Balakrishnan

  2. Re: Receiving series of Bytes in Visual Basic

    See inline comments:

    "T.Balakrishnan" wrote
    > I have some problem to receive series of Bytes using MSComm in Visual
    > Basic. If anyone could help me, I am so grateful to you.
    >
    > I am trying to receive series of Bytes from a PIC16F877. These bytes
    > are generated by an image sensor and stored in a SRAM, the PIC get
    > each bytes and send it through USART. The total number of bytes is
    > 16384, but I am getting just less than that (the total number is
    > varying). The following code is the part of Visual Basic programme to
    > receive these bytes.
    >
    > ---------------------------------------------------------------------
    > Public a, b, c as Integer



    Did you know only C is declared as an Integer here? A and B
    are not typed so they take on the default type (Variant).

    Private A As Integer, B As Integer, C As Integer

    .... is probably what you meant....


    > Private Sub MSComm1_OnComm()


    > End Sub



    Perhaps you are doing a significant amount of work in that
    event. I would suggest you move all your drawing code out
    of that event and put it in a re-enterant sub fed by a queue.

    That means all you do in the OnComm event is stuff the
    latest value in the queue and get out.

    >
    > I believe the VB programme couldn't detect some of the Bytes. I have
    > tried my circuit with HyperTerminal, I am getting right number of
    > bytes.


    I am not certain but it may be that VB could not call the OnComm event
    while your code in that event was still executing. Here is a slow motion
    demo of using a queue. Put a command button and a text box, and a
    timer on a new form. Paste in the code and try it out. It is slowed down
    100 times so that 1 second of your time equates to (about) 1 millisecond
    of computer time. Type a single letter/number in the textbox, and hit the
    button (or Enter) to simulate the receiving of that value. What you should
    notice is that you can enter text as fast as you want, and the program will
    plod through the data (at a real slow rate because it is purposely slowed
    down for the simulation).

    HTH
    LFS

    Option Explicit

    Private Que As New Collection
    Private X As Long


    Private Sub Form_Load()
    Show
    ScaleMode = vbPixels
    Text1.Text = ""
    Text1.Move 4, 4, 24, 24
    Command1.Caption = "Send"
    Command1.Move 30, 4, 64, 24
    Timer1.Interval = 1000 ' 1 sec. delays
    Timer1.Enabled = False
    Text1.SetFocus
    End Sub

    Private Sub Command1_Click()
    OnComm Left$(Text1.Text & Chr(0), 1)
    Text1.Text = ""
    Text1.SetFocus
    End Sub

    Private Sub Text1_KeyPress(KeyAscii As Integer)
    If KeyAscii = vbKeyReturn Then
    KeyAscii = 0
    Command1.Value = True
    End If
    End Sub


    Private Sub OnComm(data As String)
    ' Short and sweet
    Que.Add Asc(data)
    Timer1.Enabled = True
    End Sub


    Private Sub Timer1_Timer()
    Dim y As Long

    ' wrap around
    X = X + 5
    If X > ScaleWidth Then
    X = 0
    CurrentX = X
    End If

    ' Process data
    If Que.Count Then
    y = Que(1)
    Que.Remove 1
    Line -(X, y * 1.5)

    Caption = Chr$(y) ' just to see it
    End If

    ' Adjust clock
    Timer1.Enabled = Que.Count

    End Sub







    -----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
    http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
    -----== Over 100,000 Newsgroups - 19 Different Servers! =-----

  3. Re: Receiving series of Bytes in Visual Basic


    The line
    data = MSComm1.Input
    can place more than one byte into the data variable.

    Try something like
    data = MSComm1.Input
    for x = 1 to len(data)
    pix = Asc(mid(data,x,1))
    Picture1.PSet (a * Picture1.DrawWidth, b * Picture1.DrawWidth),
    RGB(pix, pix, pix)
    next x

    HTH

    Mike

    "T.Balakrishnan" wrote in message
    news:833fc115.0403011113.6f1beb72@posting.google.c om...
    > Hi,
    >
    > I have some problem to receive series of Bytes using MSComm in Visual
    > Basic. If anyone could help me, I am so grateful to you.
    >
    > I am trying to receive series of Bytes from a PIC16F877. These bytes
    > are generated by an image sensor and stored in a SRAM, the PIC get
    > each bytes and send it through USART. The total number of bytes is
    > 16384, but I am getting just less than that (the total number is
    > varying). The following code is the part of Visual Basic programme to
    > receive these bytes.
    >
    > ---------------------------------------------------------------------
    > Public a, b, c as Integer
    >
    > Private Sub CmdImage_Click()
    > MScomm1.RThreshold=1
    > a = 0
    > b = 0
    > c = 0
    > End Sub
    >
    >
    > Private Sub MSComm1_OnComm()
    > Dim pix As Integer
    > If a > 127 Then
    > a = 0
    > b = b + 1
    > End If
    > a = a + 1
    > c = c + 1
    > If (a < 128 And b < 128) Then
    > If MSComm1.CommEvent = comEvReceive Then
    > data = MSComm1.Input
    > pix = Asc(data)
    > Picture1.PSet (a * Picture1.DrawWidth, b *
    > Picture1.DrawWidth), RGB(pix, pix, pix)
    > End If
    > End If
    > MSComm1.InBufferCount=0
    > Text2.Text = b ' Number of Lines
    > Text3.Text = c ' Total number of Bytes
    > End Sub
    >
    > --------------------------------------------------------------------------

    -
    >
    > I believe the VB programme couldn't detect some of the Bytes. I have
    > tried my circuit with HyperTerminal, I am getting right number of
    > bytes.
    >
    > Thanks for your time,
    >
    > T.Balakrishnan




  4. Re: Receiving series of Bytes in Visual Basic

    Even though you have set the .RThreshold=1 the MsComm can receive more
    than one byte at a time, this is why you are missing bytes. To make
    your code work better you should move the receive data into the OnComm
    event...here is an example from MS on how to receive BINARY data,
    which should then be placed into the OnComm event...which follows
    after first example

    '// from VB MS Help
    Private Sub Command1_Click()
    Dim Buffer as Variant
    Dim Arr() as Byte

    ' Set and open port
    MSComm1.CommPort = 1
    MSComm1.PortOpen = True

    ' Set InputMode to read binary data
    MSComm1.InputMode = comInputModeBinary

    ' Wait until 10 bytes are in the input buffer
    Do Until MSComm1.InBufferCount < 10
    DoEvents
    Loop

    ' Store binary data in buffer
    Buffer = MSComm1.Input

    ' Assign to byte array for processing
    Arr = Buffer

    End Sub

    '// from VB MS Help
    Private Sub MSComm_OnComm ()
    Select Case MSComm1.CommEvent
    ' Handle each event or error by placing
    ' code below each case statement

    ' Errors
    Case comEventBreak ' A Break was received.
    Case comEventFrame ' Framing Error
    Case comEventOverrun ' Data Lost.
    Case comEventRxOver ' Receive buffer overflow.
    Case comEventRxParity ' Parity Error.
    Case comEventTxFull ' Transmit buffer full.
    Case comEventDCB ' Unexpected error retrieving DCB]

    ' Events
    Case comEvCD ' Change in the CD line.
    Case comEvCTS ' Change in the CTS line.
    Case comEvDSR ' Change in the DSR line.
    Case comEvRing ' Change in the Ring Indicator.
    Case comEvReceive ' Received RThreshold # of chars...and
    possibly more
    '// Receive your data here....

    Case comEvSend ' There are SThreshold number of
    ' characters in the transmit
    ' buffer.
    Case comEvEof ' An EOF charater was found in
    ' the input stream
    End Select
    End Sub

    Here is a combined sample where the Input buffer is placed into a
    Circular buffer.

    Private Sub MSComm1_OnComm()

    Dim In_Buf() As Byte
    Dim Num_Bytes As Long
    Dim Ix As Long
    Dim Rx_Byte As Byte
    Dim Success As Boolean

    Static First_Time As Boolean



    Select Case MSComm1.CommEvent
    ' Handle each event or error by placing
    ' code below each case statement

    ' Errors
    Case comEventBreak ' A Break was received.
    Case comEventFrame ' Framing Error
    Case comEventOverrun ' Data Lost.
    Case comEventRxOver ' Receive buffer overflow.
    Case comEventRxParity ' Parity Error.
    Case comEventTxFull ' Transmit buffer full.
    Case comEventDCB ' Unexpected error retrieving DCB]

    ' Events
    Case comEvCD ' Change in the CD line.
    Case comEvCTS ' Change in the CTS line.
    Case comEvDSR ' Change in the DSR line.
    Case comEvRing ' Change in the Ring Indicator.
    Case comEvReceive ' Received RThreshold # of chars.

    If gbl_SHUTDOWN_IN_PROGRESS = False Then

    Num_Bytes = MSComm1.InBufferCount
    In_Buf() = MSComm1.Input

    If First_Time = False Then
    First_Time = True
    Picture1.Cls
    X_Pos = 0
    Y_Pos = 1
    End If

    End If

    '// I now add bytes input into a Circular buffer...
    Success = CBUF_Add_Byte_Array(In_Buf())
    '// In_Buf at this point contains Num_Bytes # of bytes

    '// you could just copy In_Buf to your current storage
    location
    '// using a for loop
    for Ix = 0 to Num_bytes - 1
    Your_storage(??) = In_Buf(Ix)
    next Ix


    Case comEvSend ' There are SThreshold number of
    ' characters in the transmit buffer.

    Case comEvEOF ' An EOF charater was found in
    ' the input stream
    End Select

    End Sub




    bala_thanushan@yahoo.co.uk (T.Balakrishnan) wrote in message news:<833fc115.0403011113.6f1beb72@posting.google.com>...
    > Hi,
    >
    > I have some problem to receive series of Bytes using MSComm in Visual
    > Basic. If anyone could help me, I am so grateful to you.
    >
    > I am trying to receive series of Bytes from a PIC16F877. These bytes
    > are generated by an image sensor and stored in a SRAM, the PIC get
    > each bytes and send it through USART. The total number of bytes is
    > 16384, but I am getting just less than that (the total number is
    > varying). The following code is the part of Visual Basic programme to
    > receive these bytes.
    >
    > ---------------------------------------------------------------------
    > Public a, b, c as Integer
    >
    > Private Sub CmdImage_Click()
    > MScomm1.RThreshold=1
    > a = 0
    > b = 0
    > c = 0
    > End Sub
    >
    >
    > Private Sub MSComm1_OnComm()
    > Dim pix As Integer
    > If a > 127 Then
    > a = 0
    > b = b + 1
    > End If
    > a = a + 1
    > c = c + 1
    > If (a < 128 And b < 128) Then
    > If MSComm1.CommEvent = comEvReceive Then
    > data = MSComm1.Input
    > pix = Asc(data)
    > Picture1.PSet (a * Picture1.DrawWidth, b *
    > Picture1.DrawWidth), RGB(pix, pix, pix)
    > End If
    > End If
    > MSComm1.InBufferCount=0
    > Text2.Text = b ' Number of Lines
    > Text3.Text = c ' Total number of Bytes
    > End Sub
    >
    > ---------------------------------------------------------------------------
    >
    > I believe the VB programme couldn't detect some of the Bytes. I have
    > tried my circuit with HyperTerminal, I am getting right number of
    > bytes.
    >
    > Thanks for your time,
    >
    > T.Balakrishnan


  5. Re: Receiving series of Bytes in Visual Basic

    Hi,

    Actually, I suggest that you simplify your code

    Static Buffer As String
    Buffer = Buffer & MSComm1.Input
    If Len(Buffer) >= 16384 Then
    Process Buffer
    Buffer = "" 'reset to empty for the next go
    End If

    In the "Process subroutine," do whatever you need to do to extract the
    actual image. This will be fast -- and won't miss any data.

    Dick

    --
    Richard Grier (Microsoft Visual Basic MVP)

    See www.hardandsoftware.net for contact information.

    Author of Visual Basic Programmer's Guide to Serial Communications, 3rd
    Edition ISBN 1-890422-27-4 (391 pages) published February 2002.



  6. Re: Receiving series of Bytes in Visual Basic

    "Dick Grier" wrote
    >
    > Actually, I suggest that you simplify your code
    >
    > Static Buffer As String
    > Buffer = Buffer & MSComm1.Input
    > If Len(Buffer) >= 16384 Then
    > Process Buffer
    > Buffer = "" 'reset to empty for the next go
    > End If
    >
    > In the "Process subroutine," do whatever you need to do to extract the
    > actual image. This will be fast -- and won't miss any data.



    Can you give use the nickle tour on buffering the data like you show,
    compared to setting RThreshold to the desired value (16384)?

    LFS




    -----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
    http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
    -----== Over 100,000 Newsgroups - 19 Different Servers! =-----

  7. Re: Receiving series of Bytes in Visual Basic


    The length of the receive threshold is not relevant. The original problem
    had a receive threshold length of 1 and overran. The important bit is to
    read all the buffer rather than assume it has a length of RThreshhold.

    Mike.

    >
    > Can you give use the nickle tour on buffering the data like you show,
    > compared to setting RThreshold to the desired value (16384)?
    >
    > LFS
    >
    >
    >
    >
    > -----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
    > http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
    > -----== Over 100,000 Newsgroups - 19 Different Servers! =-----




  8. Re: Receiving series of Bytes in Visual Basic

    In VB5 and up you'd better use 'Static Buffer As byte' or else you'll
    get unwanted DBCS->ASCII conversion. This is from bitter experience; it
    took me many hours with a serial sniffer before I figured what was going
    on.

    Dick Grier wrote:

    > Hi,
    >
    > Actually, I suggest that you simplify your code
    >
    > Static Buffer As String
    > Buffer = Buffer & MSComm1.Input
    > If Len(Buffer) >= 16384 Then
    > Process Buffer
    > Buffer = "" 'reset to empty for the next go
    > End If
    >
    > In the "Process subroutine," do whatever you need to do to extract the
    > actual image. This will be fast -- and won't miss any data.
    >
    > Dick
    >



  9. Re: Receiving series of Bytes in Visual Basic

    Hi Larry,

    >>

    Can you give use the nickle tour on buffering the data like you show,
    compared to setting RThreshold to the desired value (16384)?
    <<

    Sure.

    If you set RThreshold to a large value, you also must set the InBufferSize
    property sufficiently large to hold the entire buffer (this is OK, but there
    are limits, and I prefer the alternate). If you set it only slightly larger
    than RThreshold, you stand a good chance of Receive Overrun and data loss.
    This never should happen if you double-buffer receive data.

    More importantly, RThreshold fires when that number of bytes have been
    received. This is fine, except... What happens if you receive one character
    short of a "full message?" You don't get a receive event, and you have no
    idea why. If, however, you use the technique that I outline, it is easy to
    debug because comm events are regular. If a byte (or more) is/are missed,
    you have a chance, often a good chance, of actually detecting the missing
    data. Sure, it takes some work, but a couple of extra lines of code is well
    worth it, IMO.

    The most important issue is buffering. As string buffer has much more
    capacity than does the underlying Windows serial APIs (these invoke
    interrupt service handlers for the actual buffering, and small buffers are
    more efficient than large ones, at that level).

    There are a couple of other less significant issues, but debugging and
    performance are the primary ones.

    Dick

    --
    Richard Grier (Microsoft Visual Basic MVP)

    See www.hardandsoftware.net for contact information.

    Author of Visual Basic Programmer's Guide to Serial Communications, 3rd
    Edition ISBN 1-890422-27-4 (391 pages) published February 2002.



+ Reply to Thread