Using the Serial Port in .NET 2.0

Every now and then I think it is good for us to venture back to the desktop to develop a useful Client Application.  Lately I have been developing and testing a little application to read Magnetic Stripe readers through the serial port.  The kind similar to what I use at the gym to sign in.  In this case it is a time and attendance application for student ticket distribution at North Carolina State University (Go Wolfpack! Class of '94).  A little background on the application, the card readers need to be portable, so they run off a 9 volt battery.  I then need to be able to get the Student Ids off and the time the cards were swiped.  I then use this information to determine how long a student was at a non-revenue game so they can get better seating for Football and Basketball games.

Now to the good stuff.  Back when I was a strapping young guy at NC State I had to write a couple of applications to read the serial port to collect data for my research work.  I had a blast.  This lead me to several other cool applications that read external devices and computers via TCP/IP, Modbus, etc.  I had forgotten how much fun this stuff could be, and also how frustrating things could be.

First, talking to the Serial Port in .NET 2.0 is a snap.  The Framework has a great little class that wraps everything up for us.  You should declare a reference to it in you Form definition (I really hate dealing with console applications).

Dim WithEvents serialPort As New IO.Ports.SerialPort

The WithEvents part will come into play in a little bit.  We will need to open the port before we do any communications, so we need to tell the serialPort object what port to use.  The framework provides us with a quick way to get a list of all the available ports.  Just to be on the safe side I go ahead and set a fall back to 'COM1'.

Private Sub OpenPort()

Dim sPort As String = 'COM1'

If String.IsNullOrEmpty(cbbCOMPorts.Text) = False Then

sPort = cbbCOMPorts.Text

End If

If serialPort.IsOpen Then

serialPort.Close()

End If

Try

With serialPort

.PortName = sPort

.BaudRate = 9600

.Parity = IO.Ports.Parity.None

.DataBits = 8

.StopBits = IO.Ports.StopBits.One

End With

serialPort.Open()

Catch ex As Exception

MsgBox(ex.ToString)

End Try

End Sub

This looks like pretty stnadard stuff if you have ever done any serial communications.  Now lets look at the Port Enumeration.  I am droping the values in a drop-down list box.

Private Sub Form1_Load( _

ByVal sender As System.Object, _

ByVal e As System.EventArgs) _

Handles MyBase.Load

For i As Integer = 0 To _

My.Computer.Ports.SerialPortNames.Count - 1

cbbCOMPorts.Items.Add( _

My.Computer.Ports.SerialPortNames(i))

cbbCOMPorts.Select(1, 1)

Next

End Sub

Now let's send some data to our serial device.  First I make sure the serialPort is Open, if not I go and open the communications.  To send the data you just use the 'Write' method and pass it a string.  The device I am using looks for a NewLine characted, hence the trailing vbCr.  Check with your devices command set to see what you should pass.

Private Sub WriteCommand(ByVal sCmd As String)

If serialPort.IsOpen = False Then

OpenPort()

End If

serialPort.Write(sCmd & vbCr)

End Sub

This is great, but hwo to we read from our device?  We have to set up a delegate, which is why we declared our serialPort object withEvents.  txtDataReceived is a RichTexBox I have declared on the form.  I hate to admit it, but I am just not very good at explaining delegates, but just know this works.  If I get a better way to explain it I will, but for now it is a black box that works.

Private Sub DataReceived( _

ByVal sender As Object, _

ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) _

Handles serialPort.DataReceived

txtDataReceived.Invoke(New _

myDelegate(AddressOf updateTextBox), _

New Object() {})

End Sub

The updateTextBox method.

Public Delegate Sub myDelegate()

Public Sub updateTextBox()

With txtDataReceived

sRecv = sRecv & serialPort.ReadExisting

.Font = New Font('Arial', 11.0!, FontStyle.Bold)

.SelectionColor = Color.Red

.ScrollToCaret()

.AppendText(sRecv & vbLf)

End With

End Sub

OK here I have to point out something sort of funny.  As I was debuggin my application I noticed that most of the records were being read in two event responses.  I think this had to do with me using the Event Callback structure.  I think if I would have just done what I call an inlince method of send the data then read the response on the next line of code I would not have experienced this.  So much for KISS, since I did not think about this until this afternoon.  Anyway, I put my resopnse buffer, sRecv, as an application variable and concatonate it until I get the full record, then empty it.  So if you choose to be 'fancy' like I did, be aware of this situation.  I tried the ReadLine method, but the application just seemed to hang.

So talking to the serial port and a device is pretty simple with .NET 2.0, just follow my guidance and you should be up an running in no time.

 

Share This Article With Your Friends!