I created a very simple VB.NET application to communicate over a serial port. A couple notes on it:
- The program automatically connects to the first COM port it finds. That's generally pretty safe as nowadays the average computer user doesn't have any devices that communicate over a serial port. (Ahh, I remember back in the day, before USB, when you plugged the mouse into a COM port. Or Doom over serial, good times.) This automatic connection is dangerous if you do have devices such as 3-D printers that communicate over a COM port.
- The baud rate and similar are hard coded to match my Arduino code, but you may want to expose that as a configurable item.
The application in action:
The application in Visual Studio's designer:
The first dropdown list is for the COM port (automatically selected to the first found at startup). It is named ddlCOMPort.
The buttons from left to right are: btnConnect, btnDisconnect, btnRefreshPorts, btnClear, and btnSend.
The input text box is txtSend, and the output read-only text box is txtReceive.
The code:
Imports System.IO.Ports
Public Class FormMain
''' <summary>
''' Definite a delegate to transfer incoming data from the background
''' (serial) thread to the foreground (UI) thread.
''' </summary>
''' <param name="incomingBuffer"></param>
''' <remarks></remarks>
Private Delegate Sub ProcessIncomingTextDelegate(ByVal incomingBuffer As String)
''' <summary>
''' The serial port object that will communicate.
''' </summary>
''' <remarks></remarks>
Private WithEvents connectedSerialPort As New SerialPort()
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Private Sub FormMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Try
refreshPortsList()
If ddlCOMPort.SelectedIndex >= 0 Then
' Port is found, attempt to connect to it.
connectSerialPort()
Else
' Update which controls are enabled (so disconnect button is disabled at startup).
updateConnectedEnableFields()
End If
Catch ex As Exception
End Try
End Sub
Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
Try
connectSerialPort()
Catch ex As Exception
End Try
End Sub
Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
Try
disconnectSerialPort()
Catch ex As Exception
End Try
End Sub
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
Try
connectedSerialPort.Write(txtSend.Text + vbCrLf)
txtSend.Text = ""
Catch ex As Exception
End Try
End Sub
Private Sub connectedSerialPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles connectedSerialPort.DataReceived
Try
' Received data from the serial port, send it for processing.
processIncomingData(connectedSerialPort.ReadExisting())
Catch ex As Exception
End Try
End Sub
Private Sub connectedSerialPort_ErrorReceived(sender As Object, e As SerialErrorReceivedEventArgs) Handles connectedSerialPort.ErrorReceived
Try
Catch ex As Exception
End Try
End Sub
Private Sub btnRefreshPorts_Click(sender As Object, e As EventArgs) Handles btnRefreshPorts.Click
Try
refreshPortsList()
Catch ex As Exception
End Try
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
Try
txtReceive.Text = ""
Catch ex As Exception
End Try
End Sub
''' <summary>
''' Returns if the serial port is currently connected.
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Private ReadOnly Property isSerialPortConnected
Get
Return connectedSerialPort.IsOpen()
End Get
End Property
''' <summary>
''' Update whether or not each UI control should be enabled based on
''' the connection state.
''' </summary>
''' <remarks></remarks>
Private Sub updateConnectedEnableFields()
Try
Dim isConnected As Boolean = isSerialPortConnected
btnConnect.Enabled = Not isConnected
btnDisconnect.Enabled = isConnected
ddlCOMPort.Enabled = Not isConnected
btnRefreshPorts.Enabled = Not isConnected
btnSend.Enabled = isConnected
Catch ex As Exception
End Try
End Sub
''' <summary>
''' Connect to the selected serial port.
''' </summary>
''' <remarks></remarks>
Private Sub connectSerialPort()
Try
If ddlCOMPort.SelectedIndex >= 0 Then
connectedSerialPort.PortName = ddlCOMPort.SelectedItem
connectedSerialPort.BaudRate = 9600
connectedSerialPort.WriteTimeout = -1
connectedSerialPort.ReadTimeout = -1
connectedSerialPort.ReadBufferSize = 4096
connectedSerialPort.WriteBufferSize = 2048
connectedSerialPort.Parity = IO.Ports.Parity.None
connectedSerialPort.StopBits = IO.Ports.StopBits.One
connectedSerialPort.DataBits = 8
connectedSerialPort.Open()
End If
updateConnectedEnableFields()
Catch ex As Exception
End Try
End Sub
''' <summary>
''' Disconnect the serial port.
''' </summary>
''' <remarks></remarks>
Private Sub disconnectSerialPort()
Try
connectedSerialPort.Close()
updateConnectedEnableFields()
Catch ex As Exception
End Try
End Sub
''' <summary>
''' Detect available serial ports and update the COM port list.
''' </summary>
''' <remarks></remarks>
Private Sub refreshPortsList()
Try
' Keep track of the selected port so we can reselect it after fresh.
Dim currentlySelectedPort As String = ddlCOMPort.SelectedItem
' Get the available ports and update the dropdown list.
Dim availablePorts As Array = IO.Ports.SerialPort.GetPortNames()
ddlCOMPort.Items.Clear()
ddlCOMPort.Items.AddRange(availablePorts)
' Reselect the previously selected port as a default.
If currentlySelectedPort IsNot Nothing Then
If ddlCOMPort.Items.Contains(currentlySelectedPort) Then
ddlCOMPort.SelectedItem = currentlySelectedPort
End If
End If
If ddlCOMPort.SelectedIndex = -1 AndAlso ddlCOMPort.Items.Count > 0 Then
' No port selected but one is available, default to it.
ddlCOMPort.SelectedIndex = 0
End If
Catch ex As Exception
End Try
End Sub
''' <summary>
''' Function to process incoming data from the serial port.
''' </summary>
''' <param name="incomingBuffer"></param>
''' <remarks></remarks>
Private Sub processIncomingData(ByVal incomingBuffer As String)
Try
If txtReceive.InvokeRequired Then
' On background (serial port) thread. Invoke a delegate to call this
' function again on the foreground (UI) thread.
Dim incomingTextDelegate As New ProcessIncomingTextDelegate(AddressOf processIncomingData)
Me.Invoke(incomingTextDelegate, New Object() {incomingBuffer})
Else
' On foreground (UI) thread. Process the message.
txtReceive.Text += incomingBuffer
End If
Catch ex As Exception
End Try
End Sub
End Class
The code within this post is released into the public domain. You're free to use it however you wish, but it is provided "as-is" without warranty of any kind. In no event shall the author be liable for any claims or damages in connection with this software.
No comments:
Post a Comment