Solved

OnComm Event

Posted on 2001-07-27
5
565 Views
Last Modified: 2007-12-19
I am currently communication with a proprietry hardware using Rs232 communication protocol.
Firstly I transmit a request

I am using the oncomm event to notify when there is data in the recieve buffer.the Oncomm event kick in but the following code receives no data
temp_string = MSComm1.Input
But if I put a break point after this statement put mouse over the MSComm1.Input there is data visible


Is the OnComm event to fast  or what am I doing wrong??

0
Comment
Question by:turloughm
  • 2
  • 2
5 Comments
 
LVL 43

Expert Comment

by:TimCottee
Comment Utility
The OnComm event doesn't guarantee that you will get all of the input at any one time, you will however get all of the input at some time. You should check your RThreshold property to see how many characters should be present in the buffer before the event fires. It may be that it is set to one and your first character is a control character that is not displayed. When you set the breakpoint, additional characters will pile up in the buffer and therefore be visible in the .Input property.

With the OnComm event I always find it better to receive each input and then pass this to another function with a static wider scope variable so that you can concatenate multiple inputs into one string before attempting to do anything with that string.
0
 
LVL 4

Accepted Solution

by:
VincentLawlor earned 100 total points
Comment Utility
The OnComm event signals a communications event not necessarily that there is data available.

Add this code to the OnComm Event

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.
      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

Change your RTThreshold to 1 i.e. recieve 1 character at a time if you dont know the length of the data packet coming back or to the lenght of a packet of known size

Add a handler for your data in the case comEvRecieve
e.g
    Buffer = Buffer + MSComm1.Input

Where Buffer is a public String

This should solve the problem for you

Vin.

 
0
 

Author Comment

by:turloughm
Comment Utility
Does the OnComm event trigger when a doevents statement is executed or does it trigger when Event happens?

This is a simplified version of my code

private sub SendRequest
 '\\Send Request
 mscomm.output = "343434"
 '\\Wait for All Packet Recieved flag or time out
  result = pausetime 3

  if result = true assign data to database
end sub

Private Function PauseTime(TimeOutWait As Single) as Boolean
Dim Start           As Single
Dim Finish          As Single
Dim InputStr        As String
Dim ExtraWait       As Single
Dim Count           As Long
Dim Flag            As Boolean

On Error Resume Next
  Start = Timer
    Do While Timer < Start + TimeOutWait
      If Rx_PacketRcvd = True Then Exit Do
        DoEvents
    Loop
    PauseTime = Rx_PacketRcvd
    Finish = Timer
End Function

Private Sub Mscomm_1_OnComm()
Dim strInput As String

  Select Case Mscomm_1.CommEvent

     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
     '\\READ INPUTBUFFER
     strInput = Mscomm_1.Input
     'Unstuff string and verify end of packet    
     Unstuff_Input_String strInput
 End Select
End Sub
0
 
LVL 43

Expert Comment

by:TimCottee
Comment Utility
Ok, doevents and event driven code, sounds a bit dodgy to me! A tight loop like that may not give the event time to be fired when you expect it to be, this is probably why the breakpoint shows data there.

If you want to simulate a timeout on this I would use a timer that is fired after the timeout has expired.
0
 
LVL 4

Expert Comment

by:VincentLawlor
Comment Utility
I agree with Tim on this one.

Ususally with Comms software we use framing on the packets to determine when we have recieved all the data we are waiting for.

Framing means adding a character in front and behind the data and a linear redundancy check character at the very end of the data.
For example the BS4505 protocol adds a STX (Start of text) character to the start of the packet and an ETX (End of text) character to the end. (STX and ETX are the characters &H02 and &H03)
So in your code you start a new packet when you receive a STX then keep receiving data until you receive the ETX character.

Set your RThreshold to 1
In your OnComm code

Case comEvReceive
    '\\READ INPUTBUFFER
    Dim strTemp as String
    strTemp = MSComm1.Input
   
    Buffer = Buffer + strTemp

    If strTemp <> Chr(&H03) 'Not ETX yet
        'Keep Reading        
    else
        'Unstuff string and verify end of packet    
        Unstuff_Input_String Buffer
    end if

Using this approach you only need to set a timer on the receipt of the entire packet i.e. a receive timeout. I would use the timer control for this rather than a loop.

Vin.

 


0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

728 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

14 Experts available now in Live!

Get 1:1 Help Now