Using the Communications Control
The
Communications control allows you to add both simple serial port communication
functionality to your application and advanced functionality to create a
full-featured, event-driven communications tool.
The Communications Control
The
Communications control provides an interface to a standard set of
communications commands. It allows you to establish a connection to a serial
port, connect to another communication device (a modem, for instance), issue
commands, exchange data, and monitor and respond to various events and errors
that may be encountered during a serial connection.
Possible Uses
·
To
dial a phone number.
·
To
monitor a serial port for incoming data.
·
To
create a full-featured terminal program.
Sample Applications: Dialer.vbp
and VBTerm.vbp
The
Dialer.vbp and VBTerm.vbp
sample applications which are listed in the samples directory, demonstrate
simple and complex (respectively) programming techniques of the Communications
control.
Basics of Serial Communications
Every
computer comes with one or more serial ports. They are named successively:
COM1, COM2, and so on. On a standard PC, the mouse is usually connected to the
COM1 port. A modem may be connected to COM2, a scanner to COM3, etc. Serial
ports provide a channel for the transmission of data from these external serial
devices.
The
essential function of the serial port is to act as an interpreter between the
CPU and the serial device. As data is sent through the serial port from the CPU,
Byte values are converted to serial bits. When data is received, serial bits
are converted to Byte values.
A
further layer of interpretation is needed to complete the transmission of data.
On the operating system side, Windows uses a communications driver, Comm.drv, to send and receive data using standard Windows
API functions. The serial device manufacturer provides a driver that connects
its hardware to Windows. When you use the Communications control, you are
issuing API functions, which are then interpreted by Comm.drv
and passed to the device driver.
As
a programmer, you need only concern yourself with the Windows side of this
interaction. As a Visual Basic programmer, you need only concern yourself with
the interface that the Communications control provides to API functions of the
Windows communications driver. In other words, you set and monitor properties
and events of the Communications control.
Establishing the Serial Connection
The
first step in using the Communications control is establishing the connection
to the serial port. The following table lists the properties that are used to
establish the serial connection:
Properties
|
Description
|
CommPort
|
Sets and
returns the communications port number.
|
Settings
|
Sets and
returns the baud rate, parity, data bits, and stop bits as a string.
|
PortOpen
|
Sets and
returns the state of a communications port. Also opens and closes a port.
|
Opening the Serial Port
To
open a serial port, use the CommPort, PortOpen, and Settings properties. For example:
'
Open the serial port
MSComm1.CommPort
= 2
MSComm1.Settings
= "9600,N,8,1"
MSComm1.PortOpen
= True
The
CommPort property sets which serial port to open.
Assuming that a modem is connected to COM2, the above example sets the value to
2 (COM2) and connects to the modem. You can set the CommPort
property value to any number between 1 and 16 (the default is 1). If, however,
you set this value to a COM port that does not exist for the system on which
your application is run, an error will be generated.
The
Settings property allows you to specify the baud rate, parity, and the number
of data bits and stop bits. By default, the baud rate is set at 9600. The
parity setting is for data validation. It is commonly not used, and set to
"N". The data bits setting specifies the
number of bits that represent a chunk of data. The stop bit indicates when a
chunk of data has been received.
Once
youve specified which port to open and how data
communication is to be handled, you use the PortOpen
property to establish the connection. It is a Boolean value, True or False. If,
however, the port is not functional, if the CommPort
property is set incorrectly, or if the device does not support the settings youve specified, an error will be generated or the external
device may not work correctly. Setting the value of the PortOpen
property to False closes the port.
Working with a Modem
In
most cases, you will use the Communications control to program your application
to work with a modem. With the Communications control, you can use the standard
Hayes-compatible command set to dial a phone number, or connect to and interact
with another modem.
Once
the serial port connection has been established using the CommPort,
Settings, and PortOpen properties, you use the Output
property to activate and interact with the modem. The Output property is used
to issue commands which control the interaction between one modem and another.
For example:
'
Activate the modem and
dial a phone number.
MSComm1.Output =
"ATDT 555-5555" & vbCr
In
the example above, the command "AT" initiates the connection,
"D" dials the number, and "T" specifies touch tone (rather
than pulse). A carriage return character (vbCr) must
be specified when outputting to a terminal. You do not need to add the return
character when outputting byte arrays.
When
a command is successfully processed, an "OK" result code will be
returned. You can test for this result code to determine if a command was
processed successfully.
For More Information For a complete list of Hayes-compatible
commands, check your modem documentation.
Setting Receive and Transmit Buffer
Properties at Design Time
When
a port is opened, receive and transmit buffers are created. To manage these
buffers, the Communications control provides you with a number of properties
that can be set at design time using the controls Property Pages.
Setting buffer properties at design time
Buffer Memory Allocation
The
InBufferSize and OutBufferSize
properties specify how much memory is allocated to the
receive and transmit buffers. Each are set by
default to the values shown above. The larger you make the number, the less
memory you have available to your application. If, however, your buffer is too
small, you run the risk of overflowing the buffer unless you use handshaking.
Note Given
the amount of memory available to most PCs at this time, buffer memory
allocation is less crucial because you have more resources available. In other
words, you can set the buffer values higher without affecting the performance
of your application.
The RThreshold
and SThreshold Properties
The
RThreshold and SThreshold
properties set or return the number of characters that are received into the receive and transmit buffers before the OnComm event is fired. The OnComm
event is used to monitor and respond to changes in communications states.
Setting the value for each property to zero (0) prevents the OnComm event from firing. Setting the value to something
other than 0 (1, for instance) causes the OnComm event
to be fired every time a single character is received into either buffer.
For More Information See "The OnComm
Event and the CommEvent Property" in this topic
for more information on these properties.
The InputLen and
EOFEnable Properties
Setting
the InputLen property to 0 causes the Communications
control to read the entire contents of the receive buffer when the Input
property is used. When reading data from a machine whose output is formatted in
fixed-length blocks of data, the value of this property can be set
appropriately.
The
EOFEnable property is used to indicate when an End of
File (EOF) character is found during data input. Setting this to True causes data input to stop and the OnComm
event to fire to inform you that this condition has occurred.
For More Information See "Managing the Receive and Transmit
Buffers" and "The OnComm Event and the CommEvent Property" in this topic for more
information.
Managing the Receive and Transmit Buffers
As
mentioned above, receive and transmit buffers are created whenever a port is
opened. The receive and transmit buffers are used to
store incoming data and to transmit outgoing data. The Communications control
allows you to manage these buffers by providing you with a number of properties
that are used to place and retrieve data, return the size of each buffer, and
handle both text and binary data. Properly managing these buffers is an
important part of using the Communications control.
The Receive Buffer
The
Input property is used to store and retrieve data from the receive buffer. For
example, if you wanted to retrieve data from the receive buffer and display it
in a text box, you might use the following code:
txtDisplay.Text = MSComm1.Input
To
retrieve the entire contents of the receive buffer, however, you must first set
the InputLen property to 0. This can be done at
design or run time.
You
can also receive incoming data as either text or binary data by setting the InputMode property to one of the following Visual Basic
constants: comInputModeText or comInputModeBinary.
The data will either be retrieved as string or as binary data in a Byte array.
Use comInputModeText for data that uses the ANSI
character set and comInputModeBinary for all other
data, such as data that has embedded control characters, Nulls, etc.
As
each byte of data is received, it is moved into the receive buffer and the InBufferCount property is incremented by one. The InBufferCount property, then, can be used to retrieve the
number of bytes in the receive buffer. You can also clear the receive buffer by
setting the value of this property to 0.
The Transmit Buffer
The
Output property is used to send commands and data to the transmit buffer.
Like
the Input property, data can be transmitted as either text or binary data. The
Output property, however, must transmit either text or binary data by
specifying either a string or Byte array variant.
You
can send commands, text strings, or Byte array data with the Output property.
For example:
'
Send an AT command
MSComm1.Output =
"ATDT 555-5555"
'
Send a text string
MsComm1.Output =
"This is a text string"
'
Send Byte array data
MSComm1.Output =
Out
As
previously mentioned, transmit lines must end with a carriage return character
(vbCr). In the last example, Out is a variable
defined as a Byte array: Dim Out() As Byte. If it were
a string variant, it would be defined as: Dim Out() As
String.
You
can monitor the number of bytes in the transmit buffer by using the OutBufferCount property. You can clear the transmit buffer
by setting this value to 0.
Handshaking
An
integral part of managing the receive and transmit buffers is ensuring that the
back-and-forth transmission of data is successful — that the speed at which the
data is being received does not overflow the buffer limits, for example.
Handshaking
refers to the internal communications protocol by which data is transferred
from the hardware port to the receive buffer. When a character of data arrives
at the serial port, the communications device has to move it into the receive
buffer so that your program can read it. A handshaking protocol ensures that
data is not lost due to a buffer overrun, where data arrives at the port too
quickly for the communications device to move the data into the receive buffer.
You
set the Handshaking property to specify the handshaking protocol to be used by
your application. By default, this value is set to none (comNone).
You can, however, specify one of the other following protocols:
Setting
|
Value
|
Description
|
comNone
|
0
|
No handshaking
(Default).
|
comXOnXOff
|
1
|
XOn/XOff
handshaking.
|
comRTS
|
2
|
RTS/CTS
(Request To Send/Clear To Send) handshaking.
|
comRTSXOnXOff
|
3
|
Both Request To
Send and XOn/XOff handshaking.
|
The
protocol that you choose depends upon the device to which youre
connecting. Setting this value to comRTSXOnXOff
supports both of the protocols.
In
many cases, the communications protocol itself handles handshaking. Therefore,
setting this property to something other than comNone
may result in conflicts.
Note If
you do set this value to either comRTS or comRTSXOnXOff, you need to set the RTSEnabled
property to True. Otherwise, you will be able to connect and send, but not
receive, data.
The OnComm Event
and the CommEvent Property
Depending
upon the scope and functionality of your application, you may need to monitor
and respond to any number of events or errors which may occur during the
connection to another device or in the receipt or transmission of data.
The
OnComm event and the CommEvent
property allow you to trap and check the value of communication events and
errors.
When
a communication event or error occurs, the OnComm
event is fired and the value of the CommEvent
property is changed. Therefore, if necessary, you can check the value of the CommEvent property each time the OnComm
event is fired. Because communications (especially over telephone lines) can be
unpredictable, trapping these events and errors allows you to respond to them
appropriately.
The
following table lists the communication events that will trigger the OnComm event. The values will then be written to the CommEvent property.
Constant
|
Value
|
Description
|
comEvSend
|
1
|
There are fewer
than SThreshold number of characters in the
transmit buffer.
|
comEvReceive
|
2
|
Received RThreshold number of characters. This event is generated
continuously until you use the Input property to remove the data from the
receive buffer.
|
comEvCTS
|
3
|
Change in Clear
To Send line.
|
comEvDSR
|
4
|
Change in Data
Set Ready line. This event is only fired when DSR changes from 1 to 0.
|
comEvCD
|
5
|
Change in
Carrier Detect line.
|
comEvRing
|
6
|
Ring detected.
Some UARTs (universal asynchronous
receiver-transmitters) may not support this event.
|
comEvEOF
|
7
|
End Of File
(ASCII character 26) character received.
|
The
OnComm event is also triggered, and a value is
written to the CommEvent property, when the following
errors are encountered.
Setting
|
Value
|
Description
|
comEventBreak
|
1001
|
A Break signal
was received.
|
comEventFrame
|
1004
|
Framing Error.
The hardware detected a framing error.
|
comEventOverrun
|
1006
|
Port Overrun. A
character was not read from the hardware before the next character arrived
and was lost.
|
comEventRxOver
|
1008
|
Receive Buffer
Overflow. There is no room in the receive buffer.
|
comEventRxParity
|
1009
|
Parity Error.
The hardware detected a parity error.
|
comEventTxFull
|
1010
|
Transmit Buffer
Full. The transmit buffer was full while trying to queue a character.
|
comEventDCB
|
1011
|
Unexpected
error retrieving Device Control Block (DCB) for the port.
|