Saturday, December 20, 2008

Reading Serial Port with C#

Couple days ago my junior in college called. He was asking about how to read data from Serial Port. He is currently working with his final project to pursue his Bachelor Degree in Electrical Engineering.

In general, his project is creating an RFID reader which can be used to read the RFID tag. The data then will be sent to a PC through RS232 Serial Port. This unique ID then will used as primary key to save data to database.

Hmm... this is a kind of a new thing for me, because I'm never done it before. To give you a better overview of the project, you may want to read these sources before continue:
Ok, let's get back to our main focus of how to read data from Serial Port.

According to MSDN, starting from .NET 2.0, there is a class which can be used to read and write data from Serial Port easily. You can read the documentation here. By using this class, working with serial port is no more a nightmare. The class make us able to work with serial port, as if we were working with file. In sort, you just need to specify the port object, instantiate it, open it, and start working with it (read or write data).

Specifically to create a port reader, SerialPort has an event which will be trigerred when there is a data being sent to the port. The event handler is called DataReceived. What you need to do is creating a method to be executed when the event raised, and attach the method with a SerialDataReceivedEventHandler delegate to the event handler. Let's look at the class that I've created, I call it PortReader class.

This class has three properties which are Name - name of the port which will be read, Error - to hold error occured during the operation (if any), and Message - to hold the message from the port.



private string _name = string.Empty;
private string _error = string.Empty;
private string _msg = string.Empty;

...

public string Name
{
get { return _name; }
set { _port.PortName = value; }
}

public string Message
{
get { return _msg; }
set { _msg = value; }
}

public string Error
{
get { return _error; }
}


You need to specify several attributes of the port such as BaudRate, Parity, DataBits, and StopBits (and other properties as necessary). In this class I specify it in the constructor.



public PortReader()
{
_port = new SerialPort();

_port.BaudRate = 9600;
_port.Parity = Parity.None;
_port.DataBits = 8;
_port.StopBits = StopBits.One;
_port.DataReceived += new SerialDataReceivedEventHandler(PortReader_SerialDataReceived);

}


You may notice that I also specify a new instance of SerialDataReceivedEventHandler which then attached to DataReceived event of the object. I also create a new event for my class which wrap the DataReceived event - EndReadEvent. The codes is as the following:



public delegate void PortReaderEventHandler();
public event PortReaderEventHandler EndReadEvent;

...

private void PortReader_SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!_port.IsOpen)
{
_error = "Can't read. Port is closed.";
return;
}

_msg = _port.ReadExisting();

//raise end read event
if (EndReadEvent != null) EndReadEvent();

}


PortReader_SerialDataReceived is a method which is used to handle the DataReceived event. It's simply read the port data and hold it in _msg variable. The method then raise its own EndReadEvent. This will allow user to do necessary action after the read operation.

Other methods are the DoOpen and DoClose method, which are as the following:




public bool DoOpen()
{
if (_port.PortName == "")
{
_error = "Please supply port name!";
return false;
}

if (_port.IsOpen)
{
_port.Close();
}

_port.Open();
return true;
}

public bool DoClose()
{
if (!_port.IsOpen)
{
_error = "Can't close port that is not in open state.";
return false;
}

_port.Close();
return true;
}


That's it. The complete codes of this class is as the following:



public class PortReader
{
private SerialPort _port;
private string _name = string.Empty;
private string _error = string.Empty;
private string _msg = string.Empty;

public delegate void PortReaderEventHandler();
public event PortReaderEventHandler EndReadEvent;

public string Name
{
get { return _name; }
set { _port.PortName = value; }
}

public string Message
{
get { return _msg; }
set { _msg = value; }
}

public string Error
{
get { return _error; }
}

public PortReader()
{
_port = new SerialPort();

_port.BaudRate = 9600;
_port.Parity = Parity.None;
_port.DataBits = 8;
_port.StopBits = StopBits.One;
_port.DataReceived += new SerialDataReceivedEventHandler(PortReader_SerialDataReceived);

}

private void PortReader_SerialDataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (!_port.IsOpen)
{
_error = "Can't read. Port is closed.";
return;
}

_msg = _port.ReadExisting();

//raise end read event
if (EndReadEvent != null) EndReadEvent();

}

public bool DoOpen()
{
if (_port.PortName == "")
{
_error = "Please supply port name!";
return false;
}

if (_port.IsOpen)
{
_port.Close();
}

_port.Open();
return true;
}

public bool DoClose()
{
if (!_port.IsOpen)
{
_error = "Can't close port that is not in open state.";
return false;
}

_port.Close();
return true;
}

}


Now to use the class, you only need to instantiate the object, specify the port name, open the port, and specifying the action when any read event occurred. Just place your action in OnPortReader_EndRead (you may change it with your own method). A simple example may look like the following:



PortReader myPort = new PortReader();
myPort.Name = "COM1";
myPort.EndReadEvent += new PortReader.PortReaderEventHandler(OnPortReader_EndRead);
myPort.DoOpen();


To test the application you might want to use a Virtual Serial Port Emulator. I use Virtual Serial Port Emulator form Softpedia. It's a nice application - very easy to use, very helpful, and it's free. The application will allow you to create a virtual ports as many as you want up to 255 ports.

Ok, that's all. Happy playing with the port. Any input, please welcome. :D

Friday, December 5, 2008

Even Code Comments, Are Very Important!

The story was started by this email:
All,

Please, allow me to share a little bit.

I have just read the Programming Standards.doc, and I found out something interesting in the document about code comments (all of you might have known this). I have highlighted some statements that might important to be concerned when writing our codes.

You can find the complete standard in Programming Standards.doc.

... Some paragraphs has been deleted...

By reading this, I become more realized that even comments in code have a standard for our client. Overall, I think to follow this standard there is no other way except trying to follow them when writing our codes in each task (And I am still trying to do so).

Any input, please welcome.

Regards,

-imsuryawan-
Above, was my email a couple days ago to all team members about code comments. Yes, I know this is an old topics for the one who have been involved in Programming for long years. But, still... for a newcomers, this is a very good stuff to know.

I remember when I was at the first time involved in a professional team who worked as an outsourced Software Engineers for a well known company in Australia, that code comments is very important. My senior who was being my code reviewer, writes a huge bunch notes about my comments. That time I was thinking, "Man, this is just a comment. The compiler will never care about them! So, what's wrong with this?". Hahaha... Please understand, I was still a Junior SE that time. :D

Now, I am a senior programmer in a different outsourced team for the same client. After reading the Programming Standard I become more realized that event code comments are a very important thing to be concerned, so they write them in the document.

I am sorry that I can not tell you what the rules in the document are. Overall, most of the item written in the document is a common rule when writing code comment. There are so many articles on the net about how to write a good code comment. This one is a good reference for you. Other source maybe by reading Code Complete by Steve McConnel - which discussing how to create a self documenting codes in chapter 32.

So, let's start to write a good comments in our codes. :D