Creating the Chat Application
Using Visual Studio 2005, create a new Windows application and save it as
C:\SerialCommChat. Populate the default Form1 as shown in
Figure 3.
 | |
Figure 3. Controlling: Populate the default Form1 with the various controls, as shown in the figure, including buttons, labels, and text box controls. |
Set the properties for the various controls as shown in Table 1.
Table 1. Set the properties for the various controls, as shown.
CONTROL
|
PROPERTY
|
VALUE
|
txtDataReceived |
Scrollbars |
Vertical |
txtDataToSend |
Multiline |
True |
Switch to the Code View for Form1 to start coding the form. First, declare a member variable SerialPort to represent the serial port that you want to work with:
Public Class Form1
Dim WithEvents serialPort As New IO.Ports.SerialPort
Author's Note: In addition to the SerialPort you can also use the IO.Ports.SerialPort class; both are the same. |
Notice that you need to declare SerialPort with the WithEvents keyword. This is because the SerialPort class has the DataReceived event that is fired when data arrives at the serial port and hence you need to service this event to receive the data.
When the form is first loaded, you will retrieve all the available serial port names on your computer using the My.Computer.Ports.SerialPortNames collection and then add these port names to the ComboBox control:
Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
For i As Integer = 0 To _
My.Computer.Ports.SerialPortNames.Count - 1
cbbCOMPorts.Items.Add( _
My.Computer.Ports.SerialPortNames(i))
Next
btnDisconnect.Enabled = False
End Sub
Figure 4 shows what the ComboBox control will look like when the form is first loaded.
 | |
Figure 4. Port o' Call: The screen shot shows the ComboBox control displaying all the serial port names. |
Once a port name is selected, the user clicks the Connect button to open the selected port. This is accomplished by the following method:
'-------------------------------------------
' Event handler for the Connect button
'-------------------------------------------
Private Sub btnConnect_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnConnect.Click
If serialPort.IsOpen Then
serialPort.Close()
End If
Try
With serialPort
.PortName = cbbCOMPorts.Text
.BaudRate = 9600
.Parity = IO.Ports.Parity.None
.DataBits = 8
.StopBits = IO.Ports.StopBits.One
End With
serialPort.Open()
lblMessage.Text = cbbCOMPorts.Text & " connected."
btnConnect.Enabled = False
btnDisconnect.Enabled = True
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
In particular, notice that I have explicitly set the various properties of the SerialPort class, such as PortName, BaudRate, Parity, etc. These are the communications parameters you need to set when communicating with serial devices. When communicating with serial devices, check their settings such as baudrate, parity, databits, and stopbits and set them accordingly in your application.
The Disconnect button closes the current opened serial port:
'-------------------------------------------
' Event handler for the Disconnect button
'-------------------------------------------
Private Sub btnDisconnect_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnDisconnect.Click
Try
serialPort.Close()
lblMessage.Text = serialPort.PortName & " disconnected."
btnConnect.Enabled = True
btnDisconnect.Enabled = False
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
To send data to the recipient through the serial port, use the
Write() method of the SerialPort class:
'-------------------------------------------
' Event handler for the Send button
'-------------------------------------------
Private Sub btnSend_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnSend.Click
Try
serialPort.Write(txtDataToSend.Text & vbCrLf)
With txtDataReceived
.SelectionColor = Color.Black
.AppendText(txtDataToSend.Text & vbCrLf)
.ScrollToCaret()
End With
txtDataToSend.Text = String.Empty
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
One nice feature of the SerialPort class is that you need not constantly poll for incoming data. Instead, you just need to service the DataReceived event and it will automatically fire when incoming data is detected. However, as this event is running on a separate thread, any attempt to update the main Form directly will result in an error. Hence, you need to use a delegate to update controls on the main thread (Form1):
'-------------------------------------------
' Event handler for the DataReceived
'-------------------------------------------
Private Sub DataReceived( _
ByVal sender As Object, _
ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _
Handles serialPort.DataReceived
txtDataReceived.Invoke(New _
myDelegate(AddressOf updateTextBox), _
New Object() {})
End Sub
The delegate and the
updateTextBox() subroutine is defined as follows:
'------------------------------------------------------
' Delegate and subroutine to update the Textbox control
'------------------------------------------------------
Public Delegate Sub myDelegate()
Public Sub updateTextBox()
With txtDataReceived
.Font = New Font("Garamond", 12.0!, FontStyle.Bold)
.SelectionColor = Color.Red
.AppendText(serialPort.ReadExisting)
.ScrollToCaret()
End With
End Sub