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

Tuesday, September 23, 2008

Hello Again!

Huah... after couple months of hiatus, now I'm back. Yeap... It has been a busy months lately. Some personal stuffs has made me busy. And ofcourse, the project is getting crazy.

Yeah, whatever!

Btw, I just want to update my blog. No particular topic in this post. Because I was too busy to write an article. hahaha... I know, you may call it lazy. Hehehe... It's tight related each other, though!

Btw, I was starting to use Linux again. I used to use Fedora last year. But, Fedora is not for a newbie like me - because to many things to do to make it works as smooth as W*****s, so I uninstalled it from my PC! After searching for several opinions from internet, most of the review told me to use Ubuntu! So, this Ubuntu thing is in my PC right now!

Oh yeah! About my project, I'm learning new thing right now. It's called Service Oriented Architecture. This thing has made me so busy for a couple of week. I hope I can write something about this architecture lately. Just ask uncle Google if you want to know about this stuff. I guess this link is a good start! Just check it out.

Allright then! Enough for now... Hello again all!

Saturday, June 14, 2008

For Delphi's Scanline Property, in .NET We Use LockBits

When I was in college, I used Delphi to do my assignment in Digital Image Processing subject. No particular reason though. It just because Delphi is the most popular tools to be used when working with image manipulation. My senior told me that those tools are quite good to use, because we can do an image manipulation in bit level and accessing the pointer. Since Delphi using Pascal as the core language, and Pascal do support pointer, I think the statement is right. CMIIW.

The most important one is that Delphi has a very powerful method to work with image. The method called Scanline. For a brief explanation of this method, just read it here.

Once, a friend asked me about how to implement Delphi's ScanLine when working in .NET. Hmm... that's new to me. As far as I now, there is no such method which have same ability with
Delphi's ScanLine. Common methods used to work with Image (specifically Bitmap) is Bitmap.GetPixel and Bitmap.SetPixel method. But these methods are extremely slow to be used when working with a huge image.

After browsing through uncle Google for a while, I found out that there is a method which can be used when we want to work directly accessing image data in memory. The method is Lockbits. Please refer to this article for the explanation. The writer has just explain the method in very detail and good way, so I believe you'll understand quickly.

Here is an example to do a Grayscale operation with
Bitmap.GetPixel and Bitmap.SetPixel method.


///
/// Grayscale method
///

public void Grayscale()
{
int width = _bmp.Size.Width;
int height = _bmp.Size.Height;

for (int heightIdx = 0; heightIdx < height; heightIdx++)
{
for (int widthIdx = 0; widthIdx < width; widthIdx++)
{
Color objImgColor;
objImgColor = _bmp.GetPixel(widthIdx, heightIdx);

int grayScaleBase = (int)((objImgColor.R + objImgColor.G + objImgColor.B) / 3);
Color grayScaleColor;
grayScaleColor = Color.FromArgb(grayScaleBase, grayScaleBase, grayScaleBase);

_bmp.SetPixel(widthIdx, heightIdx, grayScaleColor);
}
}
}



When woring with a large image, the method above is extremely slow. Just try it If you don't believe me. And here is how we implement Lockbits method to do a Grayscale operation on image.


///
/// Grayscale method by using pointer access
///

public void SpeedGrayscale()
{

// Specify width, height, anf pixel format
int imgWidth = _bmp.Width;
int imgHeight = _bmp.Height;
PixelFormat imgPixFormat = _bmp.PixelFormat;

// Create BitmapData and Rectangle object, which will be used
// in Lockbits method
BitmapData bmpData = null;
Rectangle rct = new Rectangle(0, 0, imgWidth, imgHeight);

try
{
// We use unsafe keyword, because this is a pointer operation
unsafe
{

//Lockbits = lock bitmap data to memory
bmpData = _bmp.LockBits(rct, ImageLockMode.ReadWrite, imgPixFormat);

byte* row; // Pointer for a bitmap row
byte* rowElement; // Pointer for a pixel
int intGrayscaleValue; // grayscale value for one pixel

// Loop based on image height (y)
for (int y = 0; y < bmpData.Height; y++)
{
// Find starting memory pointer address for each row
row = (byte*)bmpData.Scan0 + (y * bmpData.Stride);

// Loop through the row (x)
for (int x = 0; x < bmpData.Width; x++)
{
rowElement = row + (x * 3); // find the pixel pointer address

intGrayscaleValue = (rowElement[0] + rowElement[1] + rowElement[2]) / 3;

// assign grayscale value for each pixel element
rowElement[0] = (byte)intGrayscaleValue;
rowElement[1] = (byte)intGrayscaleValue;
rowElement[2] = (byte)intGrayscaleValue;
}
}

// Unlock the bitmap from memory
_bmp.UnlockBits(bmpData);
}

}
catch (Exception ex)
{
throw ex;
}
}

Friday, May 16, 2008

Other Old Articles Written By Me

It's been almost a month, and I haven't updated this blog yet. Huh! There was a busy month. A lot of work in the office with a huge bunch of tasks with complex specification.

Btw, I just want to share links from my primary blog. Yeah! I have written some articles, and putted in my primary blog. Nothing important, but they might helpful for some of you. The articles are:
I wrote those articles when I was in Induction Training. The topics may not interest you but, for some people who are really need it, I believe it can give a brighter light. Hopefully! hehehe...

So please enjoy.

Sunday, April 27, 2008

Use DateSerial Function To Avoid Regional Settings Problem In VB.NET

This is based on my experience. I used to construct a date type with from string. The sample code is as follow:


Dim dt As Date = CDate("2/3/2008")
MessageBox.Show(dt.ToLongDateString)

Hell yeah! I realized now that this is not a good way. When you execute the code above by using Regional Options set to English US - which Short date format in this setting is "mm/dd/yyyy" - you'll get a message box with message "Sunday, February 03, 2008". Comparing the result with Regional Options set to English (Australia) - which the format is "dd/mm/yyyy" - we'll get a message box with message "Sunday, 2 March 2008". Whew! So which date do the code means?

Oh, I means February 03, 2008! It's just a date, we can fix it just by changing it, it's not a big deal! Hell yeah! You can just simply change it when we are talking about one or two variable, and a simple program like those "Hello World Style" like above. When we're talking about an enterprise application like e-banking which all reports are based on transaction date, believe me that this style of code will bring you to hell.

The simple way to avoid this Regional Options problem, is just get yourself used to construct the datetime variable value by define its day, month, and year value specifically. In .NET you can use DateSerial function.

According to msdn this function returns a Date value representing a specified year, month, and day, with the time information set to midnight (00:00:00). The format of this function is as follow:


Public Function DateSerial( _
ByVal [Year] As Integer, _
ByVal [Month] As Integer, _
ByVal [Day] As Integer _
) As DateTime

So, when you means February 03, 2008, the code above will be as follow:


Dim dt As Date = DateSerial(2008, 2, 3)
MessageBox.Show(dt.ToLongDateString)

The code above will give you February 03, 2008 in any Regional Options you use!

This is a very simple thing to do, but not all realized it's effectiveness (including me, was). But, just by using this kind of simple code behavior will avoid you from a lot of problem caused by Regional Options different from miscalculating reports to unpredictable error in your application.

Tuesday, April 15, 2008

MozillaCacheView to Sneak Into Your Mozilla Cache Folder

If you are a Mozilla Firefox user, have you ever check the cache directory. Aha... you might asking, why should you check this directory. Well sometimes you might want to get some files (for example a picture) from a website you've visited but you forget the address. You can check the cache folder, because usually the files you've browsed will stay in this folder for a while (as long as you don't delete them).

But, when you look at the folder you might surprised (or maybe get confused), because this folder only contain files, without extension on it. And the file name didn't look like a filename. See the screen shot below.

Well, MozillaCacheView might help you to sneak at this folder. By using this tool you can read files located at this cache folder. It''s really simple. Just open the tool, and it'll work for you. Very exciting. You can also, copy file(s) you want into certain location.

This is the screen shot of this tool.

This tool works for Firefox/Mozilla/Netscape Web browsers. And also the great news is this tools is freeware, so you can download it free. I''m sorry I don't remember the location (and also because this is not an ads), but I believe Uncle Google will tell you better than me! :D

Btw, this is the location of cache folder for several browser.


The cache folder of Mozilla Firefox is located under C:\Documents and Settings\[User Name]\Local Settings\Application Data\Mozilla\Firefox\Profiles\[Profile Name]\Cache

The cache folder of SeaMonkey is located under C:\Documents and Settings\[User Name]\Local Settings\Application Data\Mozilla\Profiles\[Profile Name]\Cache

For other variants of Mozilla, you may find the cache folder under C:\Documents and Settings\[User Name]\Application Data\Mozilla\Profiles\[Profile Name]\Cache

Saturday, April 12, 2008

Spock Beta, The People Search Engine

Nowday, internet growing so fast. People from around the world are now connected in this virtual world. People can share and gather information each other in internet through a huge number of service. From social networking, blogs, and many others services.

Regarding to this situation, there is a need to find people in internet. For this purpose, we need a good people search engine which can give us a valid information about person we would like to search.

Spock is a new unique search engine where you can search people by adding their name, email, or even a tag which related to the people you search. When you use this people search engine, Spock will personalize your results to include information about friends and colleagues. You can also add and modify information that Spock finds about you on the internet.

As I visited this people search engine, it is still in beta version. The layout of the index page is very simple. It only contain a text box which allow you include your search term in it. Spock also give you ability to advance your search. In advance mode you can specify your search by adding Name or Email, Gender, Age, Tags, and even Location. Very Interesting!

So why not visiting this exciting people search engine and try it?

Thursday, April 10, 2008

String Manipulation In .NET

I've just realized a fact about string manipulation in .NET framework after read "MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework 2.0 Application Development Foundation" by Tony Northrup, Shawn Wildermuth and Bill Ryan.

For you who are an expert in .NET, this might look a common stuff. But, this is new to me. Well, I believe programming is not just about logic and algorithm, but also about knowing the boundaries. So you need to wide your boundaries if you want to solve various problem.

Back to the topic, the book said that
Strings of type System.String are immutable in .NET. That means any change to a string causes the runtime to create a new string and abandon the old one.
So when you want to construct a string as follows (this source is taken from the book too):


string s;

s = "wombat"; // "wombat"
s += " kangaroo"; // "wombat kangaroo"
s += " wallaby"; // "wombat kangaroo wallaby"
s += " koala"; // "wombat kangaroo wallaby koala"

Console.WriteLine(s);


In the end you'll get "wombat kangaroo wallaby koala" printed in the console, but in fact the compiler will create the "temporary strings" in memory before give the result string to you.

For a application which only a little string manipulation processes this will not give much trouble. But for application which use a bunch of string manipulations in it, this should be a concern because it can affect perfomance.

For the solution, the book suggested us to use StringBuilder. So, the code above will be as follow:


System.Text.StringBuilder sb = new System.Text.StringBuilder(30);

sb.Append("wombat"); // Build string.
sb.Append(" kangaroo");
sb.Append(" wallaby");
sb.Append(" koala");

string s = sb.ToString(); // Copy result to string.
Console.WriteLine(s);

Hmm...

Monday, April 7, 2008

Wordpress.com Engine Updated

Today, I opened my blog at wordpress.com. The blog is my personal blog at wordpress, but I moved it to my personal domain blog. When I logged in, I was very excited with the new look of its dashboard. Very cool design.


According into various news I found on the internet, the version of this engine is 2.5. For now, I have no comments for any functionalities its has, because I just want to check if my blog in Wordpress still have visitors (and fortunately it still have visitors, and there was a comment left to be moderated). Huhuhuhu...

Hmm... now I'm planning to upgrade my WP engine at my primary blog. :D I hope I can review them when I got it updated. Hopefully... :D

Thursday, April 3, 2008

What is This Code Means?

I was trying to update my blogger template and get this kind of error code bX-xxxxxx. the small x is a random alphabets. As I looked for the answer through Google Search there are no specific answer for this code.

Any answer I search only referred me to Google groups discussion which has no answer at all. The discussion only show questions from people who get same problem. And there were no answer at all. I very disappointed.

Hah... Google is a great search engine for me, the greatest thought! But why did it failed to give me the correct answer of what exactly was happening. No Idea...

Wednesday, April 2, 2008

Bookmark this blog at Mister Wong

I've just add this blog to mister-wong.com. It's a social bookmarking website. Some people said that we can increase traffic to our blog by adding our blog/website in a social bookmarking website or blog directory.

I've registered my primary blog into some blog directories. As my experience, this gave the blog a some traffic. Although it wasn't that significant but for me it was enough.

To get your blog registered in blog directory, sometimes they will ask you to give dem a reciprocal link, and usually it's can be done by adding some code which will show small banner in your web. So, if your blog is registered in a lot of this kind of blog directory, your blog will be fulled by these small banners. But, you can hide them in your footer for example. :D

Back to mister-wong. This is a nice social bookmarking site. And because this is a social bookmarking so we don't need to add a reciprocal link in our blog. Just registered yourself and bookmark your blog, and it's all done.

The site have a good layout. I love it. And the cool think is you can share your bookmarks with others in a group. You can join any group you want. Very excited.

Well, I think I'll try another social bookmarking for now. See yaaaa...

Monday, March 31, 2008

Bidvertiser Code Can't Be Added To Wordpress

I've just tried to add an Bidvertiser ads code to my blog in wordpress. But it failed. After googling for I while, I found that WP doesn't accept any ads code on its page. Too bad, since WP is one of most blog engines used widely.

I joined bidvertiser about a week ago. Still a newbie. No specific reason why I choose this ads program. Hmm... One reason is I want to try this online earning world. Some people says that we can get an unlimited earning from it. But I'm not too obsessed with this. I think this is a part of blogging, and because I really like any kind activities related to blog, so I thought there will not gonna be a big deal to try it.

The most feature which I like most from this program is because of its low limit earning can be transfered. Bidvertiser will transfer your money, when your earning reach a minimum $10. Really interesting, when compared with another program which give a relatively higher boundaries.

So if you are interesting with this program why not start to be a publisher with them. Why don't take a chance to Monetize your Website or Blog with BidVertiser, just by visiting their website and get yourself registered.

Wednesday, March 26, 2008

Hello World Again!

After adding a post indicating this blog is obselete, now I'm come back to my first home. Yup, this is my first home, but I've been far away from home for a long time since last year. Such a long time thought!

Hello world again...




However I have my primary blog at http://imsuryawan.net. Visit it if have time. But, those is written in Bahasa Indonesia (my mother language), so for you who are not Indonesian it will be difficult to understand the articles.

So why do I decided to post here again? Well, the main consideration is because I want to have an english blog, so I can interact with blogger from other country. Another reason? Don't know yet! Hehehehe...

Alright then, please just enjoy my blog. Leave your comment if you like it, and give me some backlink. Hehehe...

Cheers...