Solved

MSComm control input property

Posted on 1997-08-25
4
459 Views
Last Modified: 2008-03-03
I want to use the MSComm active X control to get some data from a serial device.  I know that the device is sending me data because I have another device that lets me look at the data comming through the serial port directly, therefore, the availability of data is not an issue.
I have defined the input buffer to be of 1000 bytes. I also defined the inputlen property to be 0 so that I can read the entire contents of the buffer at once.
Here is the problem: when I define the input to be text, the input property only retrieves a few characters from the buffer eventhough I know the buffer has 1000 characters by looking at the inputbuffercount property.  The number of characters retrieved vary from 1 to 9; no more, no matter what I define the inputlen property to be.
If I define the input to be binary, the input property only retrieves half the buffer, no more, no matter what the buffer size is.
How can I retrieve the whole buffer?
P.S. By the way, my settings are 9600,n,8,1
0
Comment
Question by:pizarro
  • 2
  • 2
4 Comments
 
LVL 3

Accepted Solution

by:
ChrisLewis earned 200 total points
Comment Utility
You shouldn't have to deal with your InputBufferSize.  Try leaving it at default (1024) rather than messing with it.  I'm going to be stupid and just give you some generals on the MSComm control.

How are you retrieving your information? There are two ways to retrieve information from the Comm control, polling and event driven.

For polling, you set up a do loop and read characters.  This is useful if you are reading a set string from the comm port, or a string that is terminated with a character sequence.  Just loop until a set numer of characters are retrieved, or the terminating string is recieved.

Polling is easier if you are causing the comm device to send you information.  You send the command to start information, then retrieve it as it comes to you.

MSComm1.CommPort = 1
MSComm1.Settings = "9600,N,8,1"
MSComm1.InputLen = 0
MSComm1.PortOpen = True
MSComm1.Output = "RUN PROGRAM" + Chr$(13)
'Here's where we do our retrieval...
'-----+----- for a set number of characters...
Do
  DoEvents
Loop Until MSComm1.InBufferCount >= 20  'wait for 20 characters
Instring = MSComm1.Input
MSComm1.PortOpen = False

- or -
'-----+----- Waiting for a terminating string...
Instring = ""
Do
  DoEvents
  Instring = Instring & MSComm1.Input
Loop Until instr(Instring,"+++END+++") > 0
MSComm1.PortOpen = False

For event driven, you set the RThreshold property to indicate how many characters of information cause an event.

sub form_load
  MSComm1.CommPort = 1
  MSComm1.Settings = "9600,N,8,1"
  MSComm1.RThreshold = 1
  MSComm1.PortOpen = True
  INSTRING = ""
  MSComm1.Output = "RUN PROGRAM" + Chr$(13)
End sub

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

    ' Errors - CHECK FOR THESE, and fix as neccessary...
    Case comEventBreak      ' A Break was received.
    Case comEventCDTO      ' CD (RLSD) Timeout.
    Case comEventCTSTO      ' CTS Timeout.
    Case comEventDSRTO      ' DSR Timeout.
    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 - HERE'S THE IMPORTANT STUFF
    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.
      'Grab your characters here...
      INSTRING = INSTRING & MSComm1.Input
      IF LEN(INSTRING) >= 20 THEN 'Deal with fixed string
         CALL PROCESS_INSTRING_HERE
     END IF
    ' - OR -
    IF instr(Instring,"+++END+++") > 0  THEN
       CALL PROCESS_INSTRING_HERE
    END IF

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


PROCESS_INSTRING_HERE would send a stop command to your comm device, or whatever you need to do next.

Event driven has one big advantage in that you can be doing other things while waiting for your comm device.

I wrote a program to read analog temp sensors, and toyed with both methods.  I ended up using polling because my return information was small enough to not need event driven processing.

Hope this helps,
Chris
0
 

Author Comment

by:pizarro
Comment Utility
The answer is very complete; however, the problem that I am facing is that whenever I invoke one of the methods you explained, I don't get the contents of the whole buffer.
For example, when I use polling, I do it so that the control reads 20 characters, but when I use the input method to retrieve the contents, I only get from 1 to 9 characters.  i.e. although the inbuffercount property says there are 20 characters in the receive buffer, I only get a few when I use the input method.
This happens when I am expecting the receive buffer to have text characters.
When I define the control so that I'm expecting binary characters, I only get half the size of the buffer.  Why is this?
0
 
LVL 3

Expert Comment

by:ChrisLewis
Comment Utility
It's interesting that InputBuffer has 20 characters, yet input is only showing from 1 to 9 characters.  Could you be getting some null characters or CHR$(0)'s that are terminating the VB string early?  

What exactly are you expecting from the Comm Device.

With BinaryMode, have you tried setting the input buffer to twice your need and gotten the full string?  Could your comm device have a different size byte that VB? Could you be looking at UniCode characters?  (Most likely not...)

Chris!
0
 

Author Comment

by:pizarro
Comment Utility
Forget the comment above. This works like a charm.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

762 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