dcsimg

Working with the SerialPort Component in .NET

Hello and welcome to my article. Today, I'd like to show you how to perform basic serial port communication. It is quite easy, so let's get started.

Open Visual Studio 2019 and create a new Console Application in either C# or VB.NET

As usual, let's start by adding the necessary namespaces.

C#

using System;
using System.IO.Ports;
using System.Threading;

VB.NET

Imports System.IO.Ports
Imports System.Threading

Add the modular variables that will be used throughout the program.

C#

   private static bool blnCont;   
   private static SerialPort spPort;

VB.NET

   Shared blnCont As Boolean
   Shared spPort As SerialPort

blnCont is a Boolean flag that determines if we should continue trying to connect or not. spPort is the physical serial port object which we will work with.

Add the methods.

C#

   public static string SetPortName(string strDefault)
   {
      string strPort;

      Console.WriteLine("Available Ports:");

      foreach (string s in SerialPort.GetPortNames())

         Console.WriteLine("{0}", s);

      Console.Write("Choose COM port (Default: {0}): ",
         strDefault);

      strPort = Console.ReadLine();

      if (strPort == "" || !(strPort.ToLower()).StartsWith("com"))
         strPort = strDefault;

      return strPort;
   }
   public static int SetBaudRate(int intDefault)
   {
      string strRate;

      Console.Write("Baud Rate(Default:{0}): ", intDefault);

      strRate = Console.ReadLine();

      if (strRate == "")
         strRate = intDefault.ToString();

      return int.Parse(strRate);
   }

   public static Parity SetParity(Parity pDefault)
   {
      string strParity;

      Console.WriteLine("Available Parity options:");

      foreach (string s in Enum.GetNames(typeof(Parity)))

         Console.WriteLine("{0}", s);

      Console.Write("Choose Parity (Default: {0}):",
         pDefault.ToString(), true);

      strParity = Console.ReadLine();

      if (strParity == "")
         strParity = pDefault.ToString();

      return (Parity)Enum.Parse(typeof(Parity), strParity, true);
   }

   public static int SetDataBits(int intDefault)
   {
      string strBits;

      Console.Write("Choose DataBits (Default: {0}): ",
         intDefault);
      strBits = Console.ReadLine();

      if (strBits == "")
         strBits = intDefault.ToString();

      return int.Parse(strBits.ToUpperInvariant());
   }

   public static StopBits SetStopBits(StopBits sbDefault)
   {
      string strBits;

      Console.WriteLine("Available StopBits options:");

      foreach (string s in Enum.GetNames(typeof(StopBits)))

         Console.WriteLine("{0}", s);

      Console.Write("Choose StopBits (Default: {0}):",
         sbDefault.ToString());

      strBits = Console.ReadLine();

      if (strBits == "")
         strBits = sbDefault.ToString();

      return (StopBits)Enum.Parse(typeof(StopBits), strBits, true);
   }
   public static Handshake SetHandshake(Handshake hsDefault)
   {
      string strHandShake;

      Console.WriteLine("Available Handshake options:");

      foreach (string s in Enum.GetNames(typeof(Handshake)))

         Console.WriteLine("{0}", s);

      Console.Write("Choose Handshake (Default: {0}):",
         hsDefault.ToString());

      strHandShake = Console.ReadLine();

      if (strHandShake == "")
         strHandShake = hsDefault.ToString();

      return (Handshake)Enum.Parse(typeof(Handshake),
         strHandShake, true);
   }
   public static void ReadMessage()
   {
      while (blnCont)
      {
         try
         {
            string strMessage = spPort.ReadLine();

            Console.WriteLine(strMessage);
         }
         catch (TimeoutException)
         {
         }
      }
   }

VB.NET

   Public Shared Function SetPortName(strDefault As String) _
         As String

      Dim strPort As String

      Console.WriteLine("Available Ports:")

      For Each s As String In SerialPort.GetPortNames()

         Console.WriteLine("{0}", s)

      Next

      Console.Write("Choose COM port (Default: {0}): ", +_
         strDefault)

      strPort = Console.ReadLine()

      If strPort = "" OrElse Not (strPort.ToLower()) _
            .StartsWith("com") Then

         strPort = strDefault

      End If

      Return strPort

   End Function

   Public Shared Function SetBaudRate(intDefault As Integer) _
         As Integer

      Dim strRate As String

      Console.Write("Baud Rate(Default:{0}): ", intDefault)

      strRate = Console.ReadLine()

      If strRate = "" Then

         strRate = intDefault.ToString()

      End If

      Return Integer.Parse(strRate)

   End Function

   Public Shared Function SetParity(pDefault As Parity) As Parity

      Dim strParity As String

      Console.WriteLine("Available Parity options:")

      For Each s As String In [Enum].GetNames(GetType(Parity))

         Console.WriteLine("{0}", s)

      Next

      Console.Write("Choose Parity (Default: {0}):", _
         pDefault.ToString(), True)

      strParity = Console.ReadLine(

      If strParity = "" Then

         strParity = pDefault.ToString()

      End If

      Return CType([Enum].Parse(GetType(Parity), strParity, _
         True), Parity)

   End Function

   Public Shared Function SetDataBits(intDefault As Integer) _
         As Integer

      Dim strBits As String

      Console.Write("Choose DataBits (Default: {0}): ", _
         intDefault)
      strBits = Console.ReadLine()

      If strBits = "" Then

         strBits = intDefault.ToString()

      End If

      Return Integer.Parse(strBits.ToUpperInvariant())

   End Function

   Public Shared Function SetStopBits(sbDefault As StopBits) _
         As StopBits

      Dim strBits As String

      Console.WriteLine("Available StopBits options:")

      For Each s As String In [Enum].GetNames(GetType(StopBits))

         Console.WriteLine("{0}", s)

      Next

      Console.Write("Choose StopBits (Default: {0}):", _
         sbDefault.ToString())

      strBits = Console.ReadLine()

      If strBits = "" Then

         strBits = sbDefault.ToString()

      End If

      Return CType([Enum].Parse(GetType(StopBits), strBits, _
         True), StopBits)

   End Function
   Public Shared Function SetHandshake(hsDefault As Handshake) _
         As Handshake

      Dim strHandShake As String

      Console.WriteLine("Available Handshake options:")

      For Each s As String In [Enum].GetNames(GetType(Handshake))

         Console.WriteLine("{0}", s)

      Next

      Console.Write("Choose Handshake (Default: {0}):", _
         hsDefault.ToString())

      strHandShake = Console.ReadLine()

      If strHandShake = "" Then

         strHandShake = hsDefault.ToString()

      End If

      Return CType([Enum].Parse(GetType(Handshake), strHandShake, _
         True), Handshake)

   End Function
   Public Shared Sub ReadMessage()

      While blnCont

         Try

            Dim strMessage As String = spPort.ReadLine()

            Console.WriteLine(strMessage)

         Catch

         End Try

      End While

   End Sub

We set the various properties of the serial port object here. We specify the parity, the baud rate, and so forth that are ultimately obtained from the user. Now, let's put it all together in the main sub.

C#

   public static void Main()
   {
      string strName;
      string strMessage;

      StringComparer scCompare = StringComparer.OrdinalIgnoreCase;
      Thread tRead = new Thread(ReadMessage);

      spPort = new SerialPort();

      spPort.PortName = SetPortName(spPort.PortName);
      spPort.BaudRate = SetBaudRate(spPort.BaudRate);
      spPort.Parity = SetParity(spPort.Parity);
      spPort.DataBits = SetDataBits(spPort.DataBits);
      spPort.StopBits = SetStopBits(spPort.StopBits);
      spPort.Handshake = SetHandshake(spPort.Handshake);

      spPort.ReadTimeout = 500;
      spPort.WriteTimeout = 500;

      spPort.Open();
      blnCont = true;
      tRead.Start();

      Console.Write("Enter Your Name: ");
      strName = Console.ReadLine();

      Console.WriteLine("Type QUIT to exit");

      while (blnCont)
      {
         strMessage = Console.ReadLine();

         if (scCompare.Equals("quit", strMessage))
            blnCont = false;
         else
            spPort.WriteLine(String.Format("<{0}>: {1}",
               strName, strMessage));
      }

      tRead.Join();
      spPort.Close();
   }

VB.NET

   Public Shared Sub Main()

      Dim strName As String
      Dim strMessage As String

      Dim scCompare As StringComparer = _
         StringComparer.OrdinalIgnoreCase
      Dim tRead As New Thread(AddressOf ReadMessage)

      spPort = New SerialPort()

      spPort.PortName = SetPortName(spPort.PortName)
      spPort.BaudRate = SetBaudRate(spPort.BaudRate)
      spPort.Parity = SetParity(spPort.Parity)
      spPort.DataBits = SetDataBits(spPort.DataBits)
      spPort.StopBits = SetStopBits(spPort.StopBits)
      spPort.Handshake = SetHandshake(spPort.Handshake)

      spPort.ReadTimeout = 500
      spPort.WriteTimeout = 500

      spPort.Open()
      blnCont = True
      tRead.Start()

      Console.Write("Enter Your Name: ")
      strName = Console.ReadLine()

      Console.WriteLine("Type QUIT to exit")

      While blnCont

         strMessage = Console.ReadLine()

         If scCompare.Equals("quit", strMessage) Then
            blnCont = False

         Else

            spPort.WriteLine([String].Format("<{0}>: {1}", _
               strName, strMessage))

         End If

      End While

      tRead.Join()

      spPort.Close()

   End Sub

Conclusion

This was a lot of work! Hopefully, this article has shown you how to work with serial ports. Until next time, happy coding!



This article was originally published on January 28th, 2020

About the Author

Hannes DuPreez

Hannes du Preez is a self-taught developer who started learning to program in the days of QBasic. He has written several articles over the years detailing his programming quests and adventures. .NET is his second love, just after his wife and kid. He has always been an avid supporter of .NET since the beginning and is an expert in VB and C#. He was given the Microsoft Most Valuable Professional Award for .NET (2008–2017). He has worked as a moderator and an article reviewer on online forums and currently works as a C# developer and writes articles for CodeGuru.com, Developer.com, DevX.com, and the Database journal.
His first book Visual Studio 2019 In Depth is currently on sale on Amazon and Bpb Publications.

You could reach him at: ojdupreez1978[at]gmail[dot]com

Related Articles

Thanks for your registration, follow us on our social networks to keep up-to-date