The most common method of performing serial port communication in Visual Basic is via the mscomm control. This control is packaged with the Professional and Enterprise editions of VB. Basically you add the control to the toolbox via the "Add Component" item of the "Project" menu. The mscomm icon looks like a telephone in the toolbox. You then drop a control onto a form after which you can access its properties, methods and events.
A typical sequence of events would be:
1) Initialize the control (eg. select baud rate, port number etc)
2) Open the port
3) Send data
4) Receive data
5) Close the port
You initialize the mscomm control via its properties. There are a number of properties but the 3 most important are:
1) Settings - normally set to "9600,n,8,1" This means 9600 baud, no parity, 8 data bits, 1 stop bit. Baud rate can be increased to as much as 57600 but not all baud rates are supported.
2) CommPort - indicates which port the control is linked to.
3) RThreshold - Determines how many bytes to receive before a comEvReceive event is triggered. If this value is 0, then it never triggers. If you wish to use event based data reception, set this property to 1.
Sending data is done via the .Output property. Normally the control is in text mode and so you pass a STRING variable to this property. Sometimes though, you may want to put the control in binary mode in which case you would pass a BYTE ARRAY to this property.
There are two main methods of receiving data. Either you can POLL the mscomm control periodically to see if any data has arrived or you can wait for incoming data to trigger the OnComm event. Both methods have their uses although the event method is the most prevalent.
a) Polling - You would normally use polling when you are waiting for a response to a message. Since the message you sent may have been lost or corrupted at its destination, you may not get a response. So when you send a message, you usually include a "timeout" mechanism. You send a message and if you don't get a reply within the timeout period, you assume that the message was lost and try again. Since we need a timer or a loop to wait for the timeout, it's convenient to poll for incoming data at the same time. Here is a code snippet using a loop:
Private Function SendMessage(ByRef msc As MsComm, ByVal msg As String, Optional ByVal timeout% = 1000) As String
'sends a message out msc and waits for a response.
'Returns the response or a null string if nothing is returned within the timeout period
Dim t as date
Dim buffer as string
msc.Output = msg
t = Now() + timeout/86400000# 'determines when to timeout
'the now() function is accurate to maybe 1/10 of a second. For more precision use API functions like timeGetTime
If msc.InBufferCount then buffer = buffer & msc.Input 'If there is data in the port, extract it and append it to the buffer
If Now() > t then Exit Do
SendMessage = buffer
b) Event - The event driven method is most useful when you waiting for data that may arrive at any time. For example, consider two computers linked together via their serial ports. You don't know *when* the other computer will send you data so it doesn't make that much sense to continually poll the port. While it is doable, it sends the CPU usage level to 100%, which tends to scare your users. The event driven method simply sets the control to trigger an event when data comes in. You then put code in the event to handle the incoming data.
Private sBuffer as String 'data buffer
Private Sub Form_Load()
mscomm1.CommPort = 1 'control is using COM1
mscomm1.Settings = "9600,n,8,1" 'set up the port parameters
mscomm1.RThreshold = 1 'set the oncomm event to trigger whenever data arrives
mscomm1.PortOpen = true 'open the port
Private Sub Mscomm1_OnComm()
If mscomm1.CommEvent = comEvReceive then 'a lot of events trigger the oncomm event....
'...this event has been triggered by incoming data
sBuffer = sBuffer & mscomm1.Input
'at this point you would normally check sBuffer to see if it has a complete command in it
' if it does, then process it and remove it from the buffer. If not, then wait and when the rest
'of the command comes in, it will trigger another OnComm event.
Private Sub Form_Unload()
If mscomm1.PortOpen then mscomm1.Portopen = false 'close the port