GUI based Serial Communication Program using C#
This is my Second Tutorial on programming the serial port using C# and dotnet framework.In the previous one ,I explained how to open,close,read and write to a serial port using simple command line programs.
In this tutorial we will build a GUI based Serial port Communication program using C# and Visual Studio Community edition.Here we will combine both the transmission and reception parts into a single Windows Form based program that will communicate with an Arduino Uno.The Program will be able to transmit and receive few strings to Arduino and blink the LED's connected pin13 of Arduino Uno.
The C# source codes used in this tutorial along with the Arduino Uno codes are available on our Github Repository.
You can also download the entire code files as Zip archive .
You can download the prebuilt windows executable (.exe) from below.
If you are new to serial port programming using C# ,I would recommend that you check my previous tutorial before starting.The IDE used here for building the program is Visual Studio 2015 Community Edition which can be freely downloaded from the web.
First thing to do is to create a Windows Form Project using the " New -> Project " Option on Visual Studio which would add all the required references for your Project.If you are creating an Empty Project you will have to add all those references manually (references to System.Windows.Forms,System.Drawing etc).
After you have created the project you can use the designer to Create your own Serial Communication program by adding and rearranging the controls on your Form1.
Now here I am only going to explain how my Form1 is arranged and what are code snippets that make it tick.All of the code that makes the program is inside the Form1 partial class .
First thing to do is to add the System.IO.Ports namespace to the top of your code so that you can use the SerialPort Class in your program.
You can access the Form1.cs code file by double clicking on Form1 in Design View.
Next thing is to populate your Form with various controls like Buttons,ComboBoxes,TextBoxes etc using the Design View in Visual Studio.
In my Form,
I have used Two ComboBox Controls to set the Serial port settings (Port Name and Baud rate).
A " Transmit " Button together with TextBox to sent data to Arduino or any other Microcontroller which is grouped under a "Serial Transmit" GroupBox.
A " Receive Data " Button together with " Received Data " TextBox to receive data from Arduino or any other Microcontroller which is grouped under a "Serial Receive" GroupBox.
A " Log " TextBox to Display additional information to the user.
Below Figure shows the Name associated with each control on my Form.
I didn't want to use the default TextBox1,ComboBox1 naming convention as it was quite confusing.
You can use the "Properties Window" to change the "Design Name" of each Control as shown below.
After the form is populated with the required controls,We will change the " FormBorder Style " to " Fixed Single " using the " Properties Window " so that user will not be able to change the size of program window. You can also change the name of your Form from Form1 to Simple Serial [c#] by changing the " Text " property of Form1 as shown below.
We will also disable the "Maximize Button" on the Title Bar.
Now Lets populate the Baudrate ComboBox ( ComboBox_Standard_Baudrates ) with standard baudrates (1200,2400,4800,9600,19200,38400 bps).
Click on the Baudrate ComboBox control and then Click on Collections in Items( under Data Grouping) in the Property Window.
A new Window will open, manually type the baudrates line by line and then press OK.
Now if you run your Program by pressing F5 ,You can see the Baudrates listed in the ComboBox Dropdown list.
After you have decided on the Visual style , name of the properties and controls in your program ,Its time to add the functional part to your Form1 code.
I want the program to automatically detect, available serial ports on a particular Windows system and populate the "Available Ports" ComboBox (ComboBox_Available_SerialPorts).
For this we will use the GetPortNames() method of the SerialPort Class.Here GetPortNames() is a static method and can be used without instantiating a SerialPort Object.The method returns the available serial ports in a string array.
In our code we are using the AddRange() method of ComboBox_Available_SerialPorts control to convert the array of Serial port names into collections which are then added as items in the "Available Ports" ComboBox.
This was added just for fun.It has no operational significance,I just wanted to show Machine Name ,OS version and number of Processors in the "Log TextBox".
All these information can be easily obtained using the properties of System.Environment object.
Since I didn't want the user to Transmit or Receive before the COM port is Selected, I have disabled the
- Serial Transmit Groupbox (GroupBox_Serial_Transmit)
- Serial Receive Groupbox (GroupBox_Serial_Receive)
- Baudrate selection combobox (ComboBox_Standard_Baudrates).
The Baudrate Selection combobox will become active only after the user have selected the COM port number and the Serial Transmit ,Serial Receive Groupbox's will get enabled after the user have selected the Baudrate.
All the above codes (Detecting Serial Ports and Detecting OS version) are inside the Form1() constructor so that it will run when the Form is created by the Main().
When the user selects a Serial port name eg:COM97 using the Available Ports ComboBox.
The code jumps into the SelectionChangeCommitted Event shown below ,Where we enable the Baudrate Selection ComboBox.
After the user Selects the required Baudrate,The code jumps to the SelectionChangeCommitted Event shown below.In this Event we enable both Serial Transmit and Serial Receive GroupBoxes.Now the user is free to Receive or Transmit data at his choosen Baudrate and Port.
The Event also has code which prints the choosen serial port and baudrate to the Log TextBox.
Now we are going to discuss how to transmit a string or character using the selected Serialport in C#.
The data / characters that will be transmitted to the Arduino uno/Microcontroller by the C# program is entered into the " Data " TextBox (TextBox_Data_Transmitted) above the " Transmit " Button.
All the Transmission code is implemented inside the Click Event of Transmit button (Button_Transmit_Data_Click) as shown below.
Here the " Serial Receive " GroupBox is disabled first. We then use 3 local varaiables to store SerialPort name,Baudrate and data to be transmitted.
The Baudrate returned by ComboBox_Standard_Baudrates.SelectedItem is in string format which we have to convert into Int32 format so that it can be based to the SerialPort Object COMport.
We then create a new SerialPort object called COMport by passing the Port Name (Port_Name) and Baud rate (Baud_Rate) to SerialPort Constructor.The constructor creates a default serialport object in 8N1 format (8 databits,No Parity,1Stopbit) using the given portname and baudrate.
After the COMport Object is created ,We open a connection to the Serial port.This action is written inside a try catch statement to catch any issues while opening the port like Port in use ,Access denied etc.
During opening a serial port lot of things can go wrong like
- you tried to Open the same port twice,
- Access to port is restricted
- Port is already under use etc.
Here we are using 4 catch statements to contain the error and close the serialport gracefully as shown below
UnauthorizedAccessException is thrown when the operating system denies access to open the serial port because of an I/O error or a specific type of security error.
System.IO.IOException is thrown when the requested port is used by another process or program.
For eg when i tried to write into the virtual Serial Port used by my USB modem,I got the following error messages.
InvalidOperationException is thrown when you do an operation on the port that is not permitted.
Eg when you try to open a port that is already opened.
You can see the error message below.
and in the end ,I have included an empty catch statement that would catch any other unforseen exceptions .
After you have opened the Serialport successfully,You can write into the port using the statement
and then close the Port using
Please note that COMport.WriteLine(Data); will send a NewLine character ('/n') with every write towards your Microcontroller or Arduino.
Also you should enable the " Receive Data " ComboBox which you have disabled in the beginning of this Click Event.
All the code for reading a string from the PC serial Port is organised inside the Click Event of " Receive Data " Button (Button_Receive_Data_Click).Most of it is similar to " Transmit Data " Click Event (Button_Transmit_Data_Click) discussed before.
At first we disable the " Serial Transmit " Groupbox to prevent the user from transmitiing anything when program is trying to receive data.
Then we set the read timeout property of COMport to 3500 milliseconds or 3.5 seconds using the following line of code .
|COMport.ReadTimeout = 3500;|
A connection to the port is opened and the program waits for data from arduino using the below line of code.
|ReceivedData = COMport.ReadLine();|
On receiving the string from Arduino microcontroller,the string is displayed on the " Received Data " TextBox.
If no data is received within 3.5 seconds a TimeoutException is raised and the program closes the SerialPort.
Please note that when you are sending data from arduino or any microcontroller ,Remember to send a NewLine Character ('/n') at the end of the string, other wise COMport.ReadLine(); will not return and a timeout will occur.
Now we will interface an Arduino Uno development board with our PC and communicate with it using our C# Serial Port program.
What we are doing can easily be done using the serial monitor program in the Arduino IDE but if you want to build a PC based control software with good looking GUI,you can use my program as a starting point.
Connecting the Arduino to the PC is straight forward ,Just connect the USB cable to your PC's USB port and find out the COM port number from your Windows Device Manager.
In my case it is COM97.
Open the Serial_Transmit.ino sketch from Arduino-TX-RX-Code directory in the Arduino IDE and upload it to your Arduino board.
This Sketch will send a "Hello from Arduino" string to your PC at 9600bps every two seconds.After uploading the sketch you can see the LED connected to Pin13 blinking.
Now compile and run the "Simple Serial" C# code ,Select Port name as COM97,Baudrate as 9600 and Press " Receive Data " Button.you can now see the string "Hello From Arduino" in the " Received Data" TextBox as well as "Log" TextBox.
Here "Simple Serial " program running on the PC sends few ASCII charcters ( 'q ' and ' w ' ) to the Arduino Board .
The Arduino board receives the characters send by the PC and light up the LED connected to Pin13 .
- If it receives the character "q" LED will blink once.
- If it receives the character "w" LED will blink twice.
Upload the "Serial_Receive.ino" sketch from from Arduino-TX-RX-Code directory to your development board (Arduino Uno).
Now compile and run the "Simple Serial" C# code.
Type "q" into the Data TextBox and Press the " Transmit " Button.You can now see the LED on Pin13 of Arduino blinking once.Try it out with the (small) letter " w " too.
You can also use "Simple Serial" C# Program to communicate with other microcontrollers like MSP430,8051,PIC,LPC2148 etc.When you are communicating with other microcontrollers from PC ,You will require a USB to Serial Converter like USB2SERIAL to convert the USB signals to TTL serial.
The below figure shows the interfacing diagram for connecting MSP430 with PC using USB to SERIAL Converter.
Please note that MSP430 IO pins are 3.3V tolerant so your USB to Serial converter should be able generate 3.3V TTL signals.
In USB2SERIAL you can easily change between 3.3V and 5V logic levels using the build in jumpers.The converter also supports USB to RS232 and USB to RS485 conversions.To know more about USB2SERIAL Please use the below Link.
In the below figure we are interfacing a MSP430 Launchpad with PC using USB2SERIAL.
Please let me know about your opinions in the comment box below or you can use our contact form