The following shows how to read data using SerialPort - it subscribes to the DataReceived event. In VB.NET there are two different options to subscribe to an event.
Option 1 (WithEvents)
Private WithEvents Port As SerialPort = Nothing
Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
Dim result As String = String.Empty
If Port Is Nothing Then
'create new instance
Port = New SerialPort(comPort)
End If
...
Return result
End Function
To subscribe to the Port.DataReceived event:
Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles Port.DataReceived
End Sub
Option 2 (AddHandler)
Private Port As SerialPort = Nothing
Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
Dim result As String = String.Empty
If Port Is Nothing Then
'create new instance
Port = New SerialPort(comPort)
'subscribe to events (add event handlers)
AddHandler Port.DataReceived, AddressOf Port_DataReceived
AddHandler Port.ErrorReceived, AddressOf Port_ErrorReceived
End If
...
Return result
End Function
To subscribe to the Port.DataReceived event:
Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
End Sub
Below are the steps to create a new Windows Forms (WinForms) project that uses SerialPort to read data along with the necessary code.
Create a WinForms project
VS 2017:
- Open Visual Studio
- Click File
- Select New
- Select Project
- Expand Installed
- Expand Visual Basic
- Click Windows Desktop
- Select Windows Forms App (.NET Framework)
- Specify project name (name: ReadSerialPort)
- Click OK
VS 2019:
- Open Visual Studio
- Click Continue without code
- Click File
- Select New
- Select Project
- Visual Basic Windows Desktop
- Click Windows Forms App (.NET Framework)
- Click Next
- Specify project name (name: ReadSerialPort)
- Click Create
Note: From this point forward, the process is the same for both VS 2017 and VS 2019.
Add some controls to Form1

Open Properties Window
- In VS menu, select View
- Select Properties Window
Open Solution Explorer
- In VS menu, select View
- Select Solution Explorer
- In Solution Explorer, double-click Form1.vb to open the designer.
Add "Connect" button to Form1
- In VS menu, select View
- Select Toolbox
- Select Button
- Click on Form1 to add the button to the form
- In Properties Window, for "button1", set (name): btnConnect; set Text: Connect
- In Properties Window, click
(Events). Double-click Click to add event handler to Form1.vb
Add "Disconnect" button to Form1
- In VS menu, select View
- Select Toolbox
- Select Button
- Click on Form1 to add the button to the form
- In Properties Window, for "button1", set (name): btnDisconnect; set Text: Disconnect
- In Properties Window, click
(Events). Double-click Click to add event handler to Form1.vb
Add TextBox to Form1
- In VS menu, select View
- Select Toolbox
- Select TextBox
- Click on Form1 to add the button to the form
Add "Load" event handler to Form1
- In Properties Window, for "Form1"", click
(Events). Double-click Load to add event handler to Form1.vb
Add "FormClosing" event handler to Form1
- In Properties Window, for "Form1"", click
(Events). Double-click FormClosing to add event handler to Form1.vb
Add class: HelperSerialPort
- On VS menu, select Project
- Select Add Class (name: HelperSerialPort.vb)
Option 1 (WithEvents)
HelperSerialPort.vb
Imports System.IO.Ports
Public Enum PortBaudRate As Integer
Baud1200 = 1200
Baud2400 = 2400
Baud4800 = 4800
Baud9600 = 9600
Baud14400 = 14400
Baud19200 = 19200
Baud28800 = 28800
Baud38400 = 38400
Baud56000 = 56000
Baud76800 = 76800
Baud115200 = 115200
End Enum
Public Class HelperSerialPort
Implements IDisposable
Private WithEvents Port As SerialPort = Nothing
'events that can be subscribed to
Public Event DataReceived(ByVal sender As Object, ByVal data As String)
Public Event ErrorReceived(ByVal sender As Object, ByVal errMsg As String)
Sub New()
End Sub
Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
Dim errMsg As String = String.Empty
Dim portName As String = String.Empty
Dim result As String = String.Empty
If String.IsNullOrEmpty(comPort) Then
errMsg = "COM port not selected"
Throw New Exception(errMsg)
End If
Try
If Port Is Nothing Then
'create new instance
Port = New SerialPort(comPort)
End If
If Not Port.IsOpen Then
'set properties
Port.BaudRate = baudRate
Port.Handshake = Handshake.None
'if parity is even or odd, then set DataBits = 7
'if parity is none, set DataBits = 8
Port.Parity = Parity.Even 'Even, None, Odd
Port.DataBits = 7
Port.StopBits = StopBits.One
Port.ReadTimeout = 200
Port.WriteTimeout = 50
Port.DtrEnable = True 'enable Data Terminal Ready
Port.RtsEnable = True 'enable Request to Send
'open port
Port.Open()
result = "Status: Connected"
Else
result = "Status: Already Connected"
End If
Catch ex As Exception
errMsg = "Error: " & ex.Message
result = errMsg 'set value
Debug.WriteLine(errMsg)
Throw ex
End Try
Debug.WriteLine(result)
Return result
End Function
Public Sub Disconnect()
Dispose()
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
If Port IsNot Nothing Then
Port.Dispose()
Port = Nothing
End If
End Sub
Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles Port.DataReceived
'read SerialPort data
Dim data As String = String.Empty
data = Port.ReadExisting()
'data = Port.ReadLine
Debug.WriteLine("Data: " & data)
'raise event
RaiseEvent DataReceived(Me, data)
End Sub
Private Sub Port_ErrorReceived(ByVal sender As Object, ByVal e As SerialErrorReceivedEventArgs) Handles Port.ErrorReceived
Dim errMsg As String = e.EventType.ToString()
Debug.WriteLine("Error: " & errMsg)
'raise event
RaiseEvent ErrorReceived(Me, errMsg)
End Sub
Public Sub WriteToSerialPort(ByVal data As String)
Dim errMsg As String = String.Empty
Try
If Port.IsOpen Then
'convert string to Byte array
Dim hexArr As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
For Each hexVal As Byte In hexArr
'convert byte to byte array
Dim tempArr As Byte() = New Byte() {hexVal}
'write
Port.Write(tempArr, 0, 1)
'add 1 ms delay before writing next byte
System.Threading.Thread.Sleep(1)
Next
Else
errMsg = "Error: Port is not open. Please open the connection and try again."
Debug.WriteLine(errMsg)
Throw New Exception(errMsg)
End If
Catch ex As Exception
errMsg = "Error: " & ex.Message
Debug.WriteLine(errMsg)
Throw ex
End Try
End Sub
End Class
Modify Form1.vb code
- In Solution Explorer, right-click Form1.vb
- Select View Code
Form1.vb
Imports System.IO.Ports
Public Class Form1
Private WithEvents helper As HelperSerialPort = New HelperSerialPort
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'get port names
For Each portName In SerialPort.GetPortNames()
Debug.WriteLine("portName: " & portName)
Next
End Sub
Private Sub Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600)
If helper IsNot Nothing Then
Debug.WriteLine("comPort: " & comPort & " baudRate: " & baudRate.ToString())
helper.Connect(comPort, baudRate)
End If
End Sub
Private Sub Helper_DataReceived(ByVal sender As Object, ByVal data As String) Handles helper.DataReceived
Debug.WriteLine("Data: " & data)
'set value
Dim tempData As String = data
If tempData.StartsWith("ww") AndAlso tempData.EndsWith("kg") Then
tempData = tempData.Substring(2, data.Length - 4)
End If
'If tempData.StartsWith("ww") Then
'tempData = tempData.Substring(2)
'End If
'If tempData.EndsWith("kg") Then
'tempData = tempData.Substring(0, tempData.IndexOf("kg"))
'End If
'set text in TextBox
TextBox1.Invoke(New MethodInvoker(Sub()
TextBox1.Text = tempData
TextBox1.Refresh()
End Sub))
End Sub
Private Sub Helper_ErrorReceived(ByVal sender As Object, ByVal errMsg As String) Handles helper.ErrorReceived
Debug.WriteLine(errMsg)
End Sub
Private Sub Disconnect()
If helper IsNot Nothing Then
helper.Disconnect()
End If
End Sub
Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
Connect("COM1", PortBaudRate.Baud9600)
End Sub
Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
Disconnect()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
'dispose
If helper IsNot Nothing Then
helper.Dispose()
End If
End Sub
End Class
Option 2 (AddHandler)
HelperSerialPort.vb
Imports System.IO.Ports
Public Enum PortBaudRate As Integer
Baud1200 = 1200
Baud2400 = 2400
Baud4800 = 4800
Baud9600 = 9600
Baud14400 = 14400
Baud19200 = 19200
Baud28800 = 28800
Baud38400 = 38400
Baud56000 = 56000
Baud76800 = 76800
Baud115200 = 115200
End Enum
Public Class HelperSerialPort
Implements IDisposable
Private Port As SerialPort = Nothing
Public Event DataReceived(ByVal sender As Object, ByVal data As String)
Public Event ErrorReceived(ByVal sender As Object, ByVal errMsg As String)
Sub New()
End Sub
Public Function Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600) As String
Dim errMsg As String = String.Empty
Dim portName As String = String.Empty
Dim result As String = String.Empty
If String.IsNullOrEmpty(comPort) Then
errMsg = "COM port not selected"
Throw New Exception(errMsg)
End If
Debug.WriteLine("comPort: " & comPort)
Try
If Port Is Nothing Then
Debug.WriteLine("creating new instance of SerialPort")
'create new instance
Port = New SerialPort(comPort)
'subscribe to events (add event handlers)
AddHandler Port.DataReceived, AddressOf Port_DataReceived
AddHandler Port.ErrorReceived, AddressOf Port_ErrorReceived
End If
If Not Port.IsOpen Then
Debug.WriteLine("Port isn't open")
'set properties
Port.BaudRate = baudRate
Port.Handshake = Handshake.None
'if parity is even or odd, then set DataBits = 7
'if parity is none, set DataBits = 8
Port.Parity = Parity.Even 'Even, None, Odd
Port.DataBits = 7
Port.StopBits = StopBits.One
Port.ReadTimeout = 200
Port.WriteTimeout = 50
Port.DtrEnable = True 'enable Data Terminal Ready
Port.RtsEnable = True 'enable Request to Send
'open port
Port.Open()
result = "Status: Connected"
Else
result = "Status: Already Connected"
End If
Catch ex As Exception
errMsg = "Error: " & ex.Message
result = errMsg 'set value
Debug.WriteLine(errMsg)
Throw ex
End Try
Debug.WriteLine(result)
Return result
End Function
Public Sub Disconnect()
Dispose()
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
If Port IsNot Nothing Then
'unsubscribe from events (remove event handlers)
RemoveHandler Port.DataReceived, AddressOf Port_DataReceived
RemoveHandler Port.ErrorReceived, AddressOf Port_ErrorReceived
Port.Dispose()
Port = Nothing
End If
End Sub
Private Sub Port_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
'read SerialPort data
Dim data As String = String.Empty
data = Port.ReadExisting()
'data = Port.ReadLine
Debug.WriteLine("Data: " & data)
'raise event
RaiseEvent DataReceived(Me, data)
End Sub
Private Sub Port_ErrorReceived(ByVal sender As Object, ByVal e As SerialErrorReceivedEventArgs)
Dim errMsg As String = e.EventType.ToString()
Debug.WriteLine("Error: " & errMsg)
'raise event
RaiseEvent ErrorReceived(Me, errMsg)
End Sub
Public Sub WriteToSerialPort(ByVal data As String)
Dim errMsg As String = String.Empty
Try
If Port.IsOpen Then
'convert string to Byte array
Dim hexArr As Byte() = System.Text.Encoding.ASCII.GetBytes(data)
For Each hexVal As Byte In hexArr
'convert byte to byte array
Dim tempArr As Byte() = New Byte() {hexVal}
'write
Port.Write(tempArr, 0, 1)
'add 1 ms delay before writing next byte
System.Threading.Thread.Sleep(1)
Next
Else
errMsg = "Error: Port is not open. Please open the connection and try again."
Debug.WriteLine(errMsg)
Throw New Exception(errMsg)
End If
Catch ex As Exception
errMsg = "Error: " & ex.Message
Debug.WriteLine(errMsg)
Throw ex
End Try
End Sub
End Class
Modify Form1.vb code
- In Solution Explorer, right-click Form1.vb
- Select View Code
Form1.vb
Imports System.IO.Ports
Public Class Form1
Private helper As HelperSerialPort = Nothing
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'create new instance
helper = New HelperSerialPort()
'subscribe to events (add event handlers)
AddHandler helper.DataReceived, AddressOf Helper_DataReceived
AddHandler helper.ErrorReceived, AddressOf Helper_ErrorReceived
'get port names
For Each portName In SerialPort.GetPortNames()
Debug.WriteLine("portName: " & portName)
Next
End Sub
Private Sub Connect(ByVal comPort As String, ByVal Optional baudRate As PortBaudRate = PortBaudRate.Baud9600)
If helper IsNot Nothing Then
Debug.WriteLine("comPort: " & comPort & " baudRate: " & baudRate.ToString())
helper.Connect(comPort, baudRate)
End If
End Sub
Private Sub Helper_DataReceived(ByVal sender As Object, ByVal data As String)
Debug.WriteLine("Data: " & data)
'set value
Dim tempData As String = data
If tempData.StartsWith("ww") AndAlso tempData.EndsWith("kg") Then
tempData = tempData.Substring(2, data.Length - 4)
End If
'If tempData.StartsWith("ww") Then
'tempData = tempData.Substring(2)
'End If
'If tempData.EndsWith("kg") Then
'tempData = tempData.Substring(0, tempData.IndexOf("kg"))
'End If
'set text in TextBox
TextBox1.Invoke(New MethodInvoker(Sub()
TextBox1.Text = tempData
TextBox1.Refresh()
End Sub))
End Sub
Private Sub Helper_ErrorReceived(ByVal sender As Object, ByVal errMsg As String)
Debug.WriteLine(errMsg)
End Sub
Private Sub Disconnect()
If helper IsNot Nothing Then
helper.Disconnect()
End If
End Sub
Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
Connect("COM1", PortBaudRate.Baud9600)
End Sub
Private Sub btnDisconnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
Disconnect()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
'dispose
If helper IsNot Nothing Then
helper.Dispose()
End If
End Sub
End Class
Resources: