---
# System prepended metadata

title: '[C# WinForm] - USB to UART loopback test study'

---

Github: [https://github.com/CarterWu-M/CS-WinForm_COM-Loopback]

This article uses a Prolific USB-to-UART TTL adapter with TX and Rx connected in a loopback configuration. It introduces how to use *ManagementObjectSearcher()* to list devices in a combo box and demonstrates using a utility class, *ComPort*, to access the COM port for standard operations.

![image](https://hackmd.io/_uploads/BkIvvnNZkx.png)
![image](https://hackmd.io/_uploads/S18tlIIbJx.png)
![image](https://hackmd.io/_uploads/Hy_iEUIZJl.png)

---
### Utility Class ComPort
---
![image](https://hackmd.io/_uploads/ByOj8WSWkl.png)
```C#=
namespace serialPortStudy.Utilities
{
    internal class ComPort
    {
        //Fields
        private SerialPort _serialPort;

        //Constructor
        public ComPort(string szPortName, int baudRate, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
        {
            this._serialPort = new SerialPort
            {
                PortName = szPortName,
                BaudRate = baudRate,
                Parity = parity,
                DataBits = dataBits,
                StopBits = stopBits
            };
        }

        //Method
        public bool Open()
        {
            try
            {
                if (!this._serialPort.IsOpen)
                {
                    // Open the device
                    this._serialPort.Open();
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
        }

        public void Close()
        {
            try
            {
                if (this._serialPort.IsOpen)
                {
                    // Close the device
                    this._serialPort.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public int writeStr(string szData)
        {
            try
            {
                if (this._serialPort.IsOpen)
                {
                    // Write data (TX)
                    this._serialPort.Write(szData);
                }
                else
                {
                    Console.WriteLine("Port is not open");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public string readStr()
        {
            try
            {
                if (this._serialPort.IsOpen)
                {
                    // Read data (RX)
                    return this._serialPort.ReadExisting();
                }
                else
                {
                    Console.WriteLine("Port is not open");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return string.Empty;
        }
    }
}
```
---
### Form1.cs
---
![image](https://hackmd.io/_uploads/r1aP91HWJx.png)
```C#=
using System.Management;
using serialPortStudy.Utilities;

namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //Constructor
        public Form1()
        {
            InitializeComponent();
            searchComPortNames(); //Display available COM port devices when the form is loaded.
        }
        
        //Method
        private void searchComPortNames()
        {
            cbComPorts.Items.Clear();

            // Research COM port devices in Win32_PnPEntity
            using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%'"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    string szName = obj["Name"]?.ToString();
                    if (szName != null)
                    {
                        // If the device exists, add it to the combo box
                        cbComPorts.Items.Add(szName);
                    }
                }
                if (cbComPorts.Items.Count > 0)
                {
                    // If the combo box contains a device, select the first item to display in the combo box
                    cbComPorts.SelectedIndex = 0;
                }
                else
                {
                    // If there is no device in the combo box, display an empty string in the combo box
                    cbComPorts.Text = "";
                }
            }
        }

        //...
    }
}
```
![image](https://hackmd.io/_uploads/H1exaJHbyg.png)
If you want to use *ManagementObjectSearcher()*, remember to add a reference to *System.Management*.

---
### Refresh button
---
![image](https://hackmd.io/_uploads/HktTIgSW1x.png)
```C#=
namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //...   
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            // The refresh button also calls searchComPortNames() to display COM port devices
            this.searchComPortNames();
        }
    }
}
```
---
### Open button
---
![image](https://hackmd.io/_uploads/r1JFtgB-kx.png)
![image](https://hackmd.io/_uploads/S1nycgSZJg.png)
```C#=
namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //...   
        
        // Because the combo box item includes the device name and COM port name, 
        // the ComPort Class only uses the COM port name to open the device. 
        // Therefore, getComPOrtName() will filter the device name and return only the COM port name.
        private string getComPortName(string szDeviceName)
        {
            // Use a regular expression to filter
            string szPattern = @"\(COM\d+\)";
            Match match = Regex.Match(szDeviceName, szPattern);
            if (match.Success)
            {
                // If there is a match, then return the COM port name.
                return match.Value.Trim('(', ')');
            }
            else
            {
                return "";
            }
        }
        
        private void btnOpen_Click(object sender, EventArgs e)
        {
            // Get the COM port name from the selected item in the combo box.
            string szComPortName = getComPortName(cbComPorts.SelectedItem?.ToString());
            // Use the ComPort class to create a new object for the field _comPort.
            this._comPort = new ComPort(szComPortName, 115200);
            if (this._comPort.Open())
            {
                // If the COM port opens successfully, then change the button's background color.
                btnOpen.BackColor = Color.LightGray;
                btnClose.BackColor = Color.LightGreen;
            }
        }
    }
}
```
---
### Close button
---
![image](https://hackmd.io/_uploads/SyRKz-HbJe.png)
![image](https://hackmd.io/_uploads/S1jsz-SWyx.png)
```C#=
namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //...   

        private void btnClose_Click(object sender, EventArgs e)
        {
            // Close the COM port
            this._comPort.Close();
            // Change the button's background color to what it was before opening.
            btnOpen.BackColor = Color.Thistle;
            btnClose.BackColor = Color.LightGray;
        }
    }
}
```
---
### Read button
---
![image](https://hackmd.io/_uploads/H1n_BWHZJx.png)
```C#=
namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //...   

        private void btnRead_Click(object sender, EventArgs e)
        {
            // If _comPort is not null, then read the string into the read textbox.
            txtRead.Text = this._comPort?.readStr();
        }
    }
}
```

---
### Write button
---
![image](https://hackmd.io/_uploads/S13crWrW1x.png)
```C#=
namespace serialPortStudy
{
    public partial class Form1 : Form
    {
        //Fields
        private ComPort _comPort; //use the Utility ComPort Class
        
        //...

        private void btnWrite_Click(object sender, EventArgs e)
        {
            // If _comPort is not null, then write the string from the write textbox.
            this._comPort?.writeStr(txtWrite.Text);
        }
    }
}
```

---
### Youtube video
---
{%youtube Boh_ZYwYsRM %}
