Click here to Skip to main content
Click here to Skip to main content

Serial Communication using C# and Whidbey

By , 20 Oct 2004
 

Introduction

In this article, I will give you an introduction on how to do serial port communication on .NET platform using C#. The .NET framework version 2.0 (beta) provides features for serial communication. The framework provides System.IO.Ports namespace. The new framework provides classes with the ability to access the serial ports on a computer, and to communicate with serial I/O devices. We will be using RS 232 C standard for communication between PCs. In full duplex mode, here I am not going to use any handshaking or flow control, I will use null modem connection for communication.

The Namespace

The System.IO.Ports namespace contains classes for controlling serial ports. The most important class is the SerialPort class.

The SerialPort Class

SerialPort class provides a framework for synchronous and event-driven I/O, access to pin and break states, and access to serial driver properties. It can be used to wrap Stream objects, allowing the serial port to be accessed by classes that use streams. That is, SerialPort class represents a serial port resource.

Creating SerialPort Object

By creating an object of this type, we will be able to programmatically control all aspects of serial communication.

The methods of SerialPort class that we will use are:

  • ReadLine(): Reads up to the NewLine value in the input buffer. If a New Line is not found before timeout, this method returns a null value.
  • WriteLine(string): Writes the specified string and the New Line value to the output buffer. The written output includes the New Line string.
  • Open(): Opens a new serial port connection.
  • Close(): Closes the port connection.

To create a SerialPort object, all we need to do is:

//create a Serial Port object
SerialPort sp = new SerialPort ();

In all, there are seven public constructors for creating SerialPort. But I am using the parameter less constructor, the constructor uses default property values. For example, the value of DataBits defaults to 8, and StopBits defaults to 1. The default communication port will be COM1.

The public properties of SerialPort class that we will use are:

  • BaudRate: Gets or sets the serial baud rate.
  • StopBits: Gets or sets the standard number of stopbits per byte.
  • ReadTimeout: Gets or sets the number of milliseconds before a timeout occurs when a read operation does not finish.

There are many public properties, but except these three, all properties will have default values.

About Serial Port (Hardware)

The serial port on your PC is a full-duplex device meaning that it can send and receive data at the same time. In order to be able to do this, it uses separate lines for transmitting and receiving data. Some types of serial devices support only one-way communication, and therefore, use only two wires in the cable - the transmit line and the signal ground.

Data Transfer

In serial communication, a byte of data is transferred through a single wire one bit at a time. The packets contain a start bit, data, and stop bit. Once the start bit has been sent, the transmitter sends the actual data bits. There may either be 5, 6, 7, or 8 data bits, depending on the number you have selected. Both receiver and the transmitter must agree on the number of data bits, as well as the baud rate.

Null Modem

A Null Modem cable simply crosses the receive and transmit lines so that transmit on one end is connected to receive on the other end and vice versa. In addition to transmit and receive, DTR & DSR, as well as RTS & CTS are also crossed in a Null Modem connection.

Here is the pin diagram:

Sample screenshot

As we are not using any handshake, we will use three wire connections in which we will connect pin 2 of one connector to pin 3 of the other. For both the connectors, connect pin 5 (ground) of both the connectors with each other (common ground).

If you want, you can use only one PC as both transmitter and receiver for this communication. Then, just take a DB 9 connector and a small wire, and connect pin no 2 and 3 using the wire that will connect a loop back. That is, whatever you will send, the same data you will be receiving.

The Example Application

The main form:

Sample screenshot

Here, if you want to work with default values for the public properties, then press Save Status. If you want to change the value for specified properties, then press Property.

Then the following dialog will pop:

Screenshot - fig2.JPG

Here, you can select values for baud rate and stop bit. To save these changes, press OK.

If you directly press save status or save the changed values for properties, the following form will be displayed:

Sample screenshot

Which will display the values for some of the properties.

For starting communication, press Start Comm. As soon as you press the button, the following form will be displayed:

Screenshot - fig4.JPG

Type data in textbox which is to be transferred, followed by a new line, and press Send button. As soon as you press the button, the data will be send to the send buffer and later to the COM port.

For reading the data form COM port, press Read button. If there is any data in read buffer, it will be displayed in the textbox. If there no data to be read for 500 ms, then an error message will be displayed informing the same.

Here is a code example for the above application:

Code for the Main app

#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO.Ports;
 
#endregion
 
namespace Serialexpample
{
    partial class Form1 : Form
    {
        //create instance of property page
        //property page is used to set values for stop bits and 
        //baud rate

        PropertyPage pp = new PropertyPage();

        //create an Serial Port object
        SerialPort sp = new SerialPort();

        public Form1()
        {
            InitializeComponent();
        }
            
        private void propertyButton_Click(object sender, EventArgs e)
        {
            //show property dialog
            pp.ShowDialog();

            propertyButton.Hide();
        }

        private void sendButton_Click(object sender, EventArgs e)
        {
            try
            {
                //write line to serial port
                sp.WriteLine(textBox.Text);
                //clear the text box
                textBox.Text = "";
            }
            catch (System.Exception ex)
            {
                baudRatelLabel.Text = ex.Message;
            }

        }

        private void ReadButton_Click(object sender, EventArgs e)
        {
            try
            {
                //clear the text box
                textBox.Text = "";
                //read serial port and displayed the data in text box
                textBox.Text = sp.ReadLine();
            }
            catch(System.Exception ex)
            {
                baudRatelLabel.Text = ex.Message;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            MessageBox.Show("Do u want to Close the App");
            sp.Close();
        }

        private void startCommButton_Click(object sender, EventArgs e)
        {
            startCommButton.Hide();
            sendButton.Show();
            readButton.Show();
            textBox.Show();
        }

        //when we want to save the status(value)
        private void saveStatusButton_Click_1(object sender, EventArgs e)
        {
            //display values
            //if no property is set the default values
            if (pp.bRate == "" && pp.sBits == "")
            {
                dataBitLabel.Text = "BaudRate = " + sp.BaudRate.ToString();
                readTimeOutLabel.Text = "StopBits = " + sp.StopBits.ToString();
            }
            else
            {
                dataBitLabel.Text = "BaudRate = " + pp.bRate;
                readTimeOutLabel.Text = "StopBits = " + pp.sBits;
            }

            parityLabel.Text = "DataBits = " + sp.DataBits.ToString();
            stopBitLabel.Text = "Parity = " + sp.Parity.ToString();
            readTimeOutLabel.Text = "ReadTimeout = " + 
                      sp.ReadTimeout.ToString();

            if (propertyButton.Visible == true)
                propertyButton.Hide();
            saveStatusButton.Hide();
            startCommButton.Show();

            try
            {
                //open serial port
                sp.Open();
                //set read time out to 500 ms
                sp.ReadTimeout = 500;
            }
            catch (System.Exception ex)
            {
                baudRatelLabel.Text = ex.Message;
            }
        }
    }
}

Code for Property Dialog

#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
#endregion
 
namespace Serialexpample
{
    partial class PropertyPage : Form
    {
        //variables for storing values of baud rate and stop bits
        private string baudR="";
        private string stopB="";

        //property for setting and getting baud rate and stop bits
        public string bRate
        {
            get
            {
                return baudR;
            }
            set
            {
                baudR = value;
            }
        }

        public string sBits
        {
            get
            {
                return stopB;
            }
            set
            {
                stopB = value;
            }
        }

        public PropertyPage()
        {
            InitializeComponent();
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            this.bRate = "";
            this.sBits = "";
            //close form
            this.Close();
        }

        private void okButton_Click_1(object sender, EventArgs e)
        {
            //here we set the value for stop bits and baud rate.
            this.bRate = BaudRateComboBox.Text;
            this.sBits = stopBitComboBox.Text;
            //
            this.Close();

        }
    }
}

Note:

  • Both receiver and the transmitter must agree on the number of data bits, as well as the baud rate.
  • All the connection for the DB 9 connector should be done accordingly.
  • The article is based on pre-released documentation (.NET Framework 2.0 Beta) and is subject to change in future release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Tapan Dantre
Web Developer
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 1memberayad0net21 Feb '13 - 3:40 
ؤ
SuggestionA simple way to Perform Serial Communication using C# ProjectmemberLuzan Baral18 Feb '13 - 18:05 
Here, I have include a simple way to perform serial communication using C#. get some ideas from here too.http://thecomputerstudents.com/programming/c-sharp/serial-port-communications-in-c-sharp-with-example/
Software Engineering Students
#programming #SEO #WordPress
Find me on twitter @nazulb @tcsweb

Questionan electric pulse of 5 volts to unlockmemberThyago Analista29 Jan '13 - 3:02 
Great post, as a friend would be there in the code to send some electric pulse in the case to unlock a turnstile. The manufacturer said that the need to give an electric pulse of 5 volts to unlock it knows how to do? Could you help me?
I'm new in this issue do not know how!
QuestionTranslating input data to another custom application.memberxp2k2k3sss1 Aug '12 - 9:23 
I'm trying to translate the input data from COM port to a custom software running on pc. The above coding shows how to read and write back to the COM port attached device. How do I take input from the device and translate to a custom data format, then sends back to the application running on PC? So basically the device and the running application doesn't know the existence of the translation software running in the middle. I could find easily the coding which does write to the device, but not writing to 3rd application.
AnswerRe: Translating input data to another custom application.memberTapan Dantre1 Aug '12 - 19:25 
Hi,
 
What i can get from your question is one application will read data from the port do some formating and provide data to a third application. Now my question is this third application need the data through serial port and reside on a different machine? if yes then your data collecting application will act as both reveicer and sender.
 
If your third app doesnt need data through serial port then there are many ways to share the data with third app, you can use file/data base/TCP etc to store the formated data that can be used by thrid app.
 
If you can provide more details of your need i may help you
 
Thanks,
 
Tapan Dantre
GeneralMy vote of 4memberNarendra_uit201023 Mar '12 - 22:58 
fdsfsdf
Questionserial port openmemberketakee18 Mar '12 - 21:57 
if i have in a component class create object of serial port and checka condition
if(port.open)
{
str=0*0A;
port.write("write on buffer");
port.read("read from buffer");
}
else
{
messagebox("port is not open");
}
plz help me how to write that plz give example like that.
QuestionHow to show the received signal in Hex?memberMember 835129818 Mar '12 - 6:30 
Thanks so much for posting this project. It is easy to follow. But, I have question: How to show the received signal in Hex? In your project, the received signal is shown as text format. When I try to test a RS232, I cannot see in form text.
 
Thanks!
 
Thanh Nguyen
 
Student
GeneralMy vote of 5membermanoj kumar choubey13 Feb '12 - 0:18 
Name
Questionport namememberketakee2 Feb '12 - 20:24 
hi i am doing project for that i need in a text box how add port number of pc and its name plz help me.
Questionhow to change the defalut com port com1 to other com7membersatyasankar0931 Jan '12 - 7:28 
Dear sir ,
i am using usb to serial converter, so my com port no is com7 so i wanto chage its to com7 or i want a option to enter com port no in property page, how can i do that, plz help....
Questionhow to scale to simple console application ...memberbakrmyounis8 Nov '11 - 18:06 
thanks for the article,
 
I was trying to read through the various blogs on how to accomplish the same serial IO using a simple console application with C#. I am using .net 4.0 express. I have seen similar code being posted in multiple boards, and they are all form based which is great, but there seems to be a lacking of explaining that its NOT that trivial to read from serial in windows environment since the read data is on a different thread. I would really appreciate somebody looking at this code below and tell me what am I doing wrong.
 
CODE START ....


using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Timers;
using System.Threading;
 
namespace SM3_serial_getADCcounts
{
    class Program
    {
        static SerialPort sm3_MM_serial = new SerialPort ();
        static System.Timers.Timer temp_timer = new System.Timers.Timer();       
        static int count=0;
        static string temp; // top level buffer to hold the serial data
        delegate void SetTextDeleg(); // delegate initialization to steer the received data from 
                                      // ReadExisting() method to another method that updates buffer
        
        static void Main(string[] args)
        {
 
            // com port intitialization move to a method later on
            ... removed port initialization stuff 
             
            // register event handler for recieved data
            sm3_MM_serial.DataReceived += new SerialDataReceivedEventHandler(read_bytes);
            temp_timer.Elapsed += new ElapsedEventHandler(temp_timer_Elapsed);
            temp_timer.Interval = 10;
            temp_timer.Start();
 
            
            Console.WriteLine("Port Initialized");
            // tries 10 times in 10 seconds to open the port and quits afterwards (not tested yet)
            while (count < 10)
            {
                //time_delay(1000, temp_timer);
                //temp_timer.Stop();
                try
                {
                    if (sm3_MM_serial.IsOpen == false)
                    sm3_MM_serial.Open();
                    Console.WriteLine("port is open");
                    break;
                }
 
                catch (IOException e)
                {
                    if (count == 9 && sm3_MM_serial.IsOpen == false)
                    {
                        Console.WriteLine(e.Message);
                        Console.WriteLine("done trying bye");
                        break;
                    }
               }
                count++;
            }            
            //port assumed to be open and is open (tested)  
         
           Console.WriteLine("Serial OUT = " + temp); //display the read data from serial 
                                                      // from the main thread. (doesnt display any data in temp     
           Console.ReadKey();                             
                       
        }
       private static void read_bytes(
                        object sender,
                        SerialDataReceivedEventArgs e)
        {
            //Thread.Sleep(500);
            temp = sm3_MM_serial.ReadExisting (); // updating the global buffer
            // attempt to send the data to main thread by means of a delegate (tested)
            SetTextDeleg _delegate = new SetTextDeleg(si_DataReceived);
            //_delegate(data);
            //temp = data;         
         }
 
        private static void si_DataReceived() {
 
           //Console.WriteLine("did we get data");
            Console.WriteLine(temp.Trim()); // this does print the data from the port successfully
            //temp = data;
        }
 
        #region timer_tick // delay stuff. 

        public static void temp_timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (count < 10)
                count++;
            else
            {
                count = 0;
                temp_timer.Stop();
            }
 
        } 
       
        public static void time_delay(int delayMS, System.Timers.Timer msTimer)
        {
            msTimer.Interval = delayMS;
            msTimer.AutoReset = true;
            msTimer.Start();
        }
        #endregion
 
    }
}
 
the main section of this code does execute, and the serial thread does return the data to console but I cannot seem to figure out a way to use that data back in the main thread. basically the main is executing on its own regardless if I ask to print whats been read from the other thread.
 

obviously the aim in NOT this simple example, but to eventually run a state machine off of these serial data commands, and unless I figure out away to transfer the data from serial thread to main and/or any thread for that maters then is a useless effort on my part.
 
really appreciate if somebody can explain the serial threads and how to communicate between that and main, I think if this article had this explanation it would get a 7 and not a mere 5 Smile | :)
 
Confused | :confused: Confused | :confused: Confused | :confused:
AnswerRe: how to scale to simple console application ...memberTapan Dantre9 Nov '11 - 16:37 
Hi,
 
I think what need to have is inter thread communication, please go through the link http://social.msdn.microsoft.com/Forums/da-DK/clr/thread/6d091f04-41aa-495a-9e26-ca0c42240cde
 
this might help.
 
Thanks,
 
Tapan Dantre
QuestionSerial portmembershivashankar.y.s30 Oct '11 - 21:59 
Dear sir

Thanks for Serial Communication programing, It is working fine.But I want to read data continiously without clicking Read button. How to make it?

With warm regards

Shivashankar
AnswerRe: Serial portmemberTapan Dantre31 Oct '11 - 18:55 
Hi Shivashankar,
 
use the readline/read function of the serial port in a loop for continous read. In the code example the readline function is present in side the button click event so you need to click the button whenever you want to read the data out of the port.
 
Thanks,
 
Tapan Dantre
GeneralMy vote of 3memberHabeeballah Hasnoddin13 Jun '11 - 1:13 
Explanation is OK but no good example and steps are not explained properly if this is a tutorial.
GeneralMy vote of 4membervikx15 Feb '11 - 0:50 
basic and good enough to understand
GeneralSerial Port Readingmembersnevil7 Jan '11 - 19:58 
Hello,
My code is as follow:-
 
Serial port = new SerialPort();
 
then I have set portname,baudrates and all that stuff.
 
Then I am using port.ReadLine() to read the data but in this I am able to read alternate string from the port. I do not understand the problem. Please if somebody can help me out.
GeneralAny Serial PortmemberOrhan Albay21 Oct '10 - 1:59 
Hello everybody,
 
I have developed a serial port programming language.
 
It is a handy, simple serial port programming language specially designed to simplify the development of RS232 based applications. It makes it easy not only to communicate with the serial port but also data parsing and extraction.
 
It is opensource and I appreciate if you test and let me know your thoughts.
 
You can download the application from the following link:
 
http://sourceforge.net/projects/anyserialport/[^]
 
And here is the user guide link:
 
http://www.anyserialport.com/help[^]
 
Thank you for taking your time.
 
Orhan
GeneralMy vote of 4memberHimanshuJain12 Oct '10 - 23:28 
Article looks excellent but I am not able to see source code for download here
GeneralMy vote of 5membersrinivasks3311 Oct '10 - 5:23 
good one
GeneralMy vote of 1memberSerja Ru9 Jul '10 - 20:48 
Bad!
GeneralDevice not respondingmemberRiho Pihlak2 Apr '10 - 13:31 
How to detect if the device does not respond to a sent message? Are there any examples?
Generalprinting problemsmemberyogeshptl14 Dec '09 - 21:02 
sir my printer leave spaces while printing?
GeneralMy vote of 2memberfunnydaredevil26 Oct '09 - 5:28 
so simple things in so laborious code

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 20 Oct 2004
Article Copyright 2004 by Tapan Dantre
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid