Sunday, June 17, 2012

VB.net Serial Port Interface

Now that we know how to use the UART of our 8051, lets make a simple PC interface to demonstrate sending and receiving of data. Visual Basic dotNET 2010 will be used in this tutorial.

The goal of this tutorial is to write a simple application that can send data to be written to a port on the microcontroller, and received data from the status of a port  on the microcontroller.

Create a new project and add the following controls inside your form
  •  Groupbox
  • Three (3) labels
  •  Two (2) buttons
  • Combo box
  • Horizontal scroll bar
  • Textbox
  • Serial Port

Figure 1: The VB.net Serial Interface main form
Arrange the controls accordingly like the above image. The two buttons will be named as btnConnect and btnDisconnect , the combo box as cboCOMPorts, the horizontal scroll bar as ScrollData, the second label as lblDataValue which will indicate the value that is currently written on the serial port, and the textbox as txtRxData which will contain the received data from the 8051.

Let's start coding!

First add a reference to System.IO.Ports and System.Text so we can use the SerialPort namespace to get port names and stringbuilder by adding the following to your code.

Figure2: Import namespace

Declare an array that will hold the data to be sent out, in this tutorial we are only a single byte will be sent by the microcontroller so the array contains only 1 element.

           Dim outData As Byte() = New Byte(0) {}

Before going further, we type in the subroutines that are useful in different areas.

GetCOMPortList 
    It will get all the available serial port installed and populate the combo box so that we can select on what COM port to connect. This will be called during start up so we can get all the COM ports available, it can be also called by a timer to continuously scan for COM ports specially when using USB-to-Serial cables.

    Private Sub GetCOMPortList()
        Dim i As Integer
        Dim foundDifference = False

          'Search all the entrire serial port object and see if there are new serial ports from the last time
          'it was check, and update the list if any difference occurred.

        If cboCOMPorts.Items.Count = SerialPort.GetPortNames().Length Then
            For Each s As String In SerialPort.GetPortNames()
                If cboCOMPorts.Items(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)).Equals(s) = False Then
                    foundDifference = True
                End If
            Next
        Else
            foundDifference = True
        End If


        If foundDifference = False Then
            Return
        End If

        cboCOMPorts.Items.Clear()

        For Each s As String In SerialPort.GetPortNames()
            cboCOMPorts.Items.Add(s)
        Next
        cboCOMPorts.SelectedIndex = 0

    End Sub



By default VB.net only supports reading and writing in ascii form, so we need a way to convert data to binary form and back to ascii for display in our GUI.

HexToByte
  This routine will convert the ascii hex data to binary form.

    Private Function HextoByte(ByVal msg As String) As Byte()
        msg = msg.Replace(" ", "")

        Dim combuffer As Byte() = New Byte(msg.Length \ 2 - 1) {}
        For i As Integer = 0 To msg.Length - 1 Step 2
            combuffer(i \ 2) = CByte(Convert.ToByte(msg.Substring(i, 2), 16))
        Next

        Return combuffer
    End Function


ByteToHex
   This routine will convert binary data to ascii hex

    Private Function BytetoHex(ByVal comByte As Byte()) As String
        Dim builder As New StringBuilder(comByte.Length * 3)
        For Each data As Byte In comByte
            builder.Append((Convert.ToString(data, 16).PadLeft(2, "0")))
        Next
        Return builder.ToString().ToUpper()
    End Function


Form Load Event
   During startup, we set default values for our controls and get the list of serial ports

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblDataValue.Text = ScrollData.Value.ToString()
        ScrollData.Enabled = False
        ScrollData.Maximum = 255
        ScrollData.LargeChange = 1
        btnDisconnect.Enabled = False
        txtRxData.Text = "00"


        GetCOMPortList()
    End Sub

The Connect Button
   As the name implies, it will open the serial port selected, add the following to the Click event

    Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click

        outData(0) = Convert.ToByte(lblDataValue.Text)

        Try
            SerialPort1.PortName = cboCOMPorts.Items(cboCOMPorts.SelectedIndex).ToString()
            SerialPort1.BaudRate = 9600
            SerialPort1.Open()
            SerialPort1.Write(outData, 0, 1)
            btnDisconnect.Enabled = True
            ScrollData.Enabled = True
            btnConnect.Enabled = False
        Catch ex As Exception
            btnDisconnect.PerformClick()
        End Try
    End Sub

The Disconnect Button
   Used to close the current connection, add the following to the Click event

    Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
        Try
            SerialPort1.DiscardInBuffer()
            SerialPort1.DiscardOutBuffer()
            SerialPort1.Close()
            ScrollData.Value = 0
            ScrollData.Enabled = False
            btnConnect.Enabled = True
            btnDisconnect.Enabled = False
        Catch ex As Exception

        End Try
    End Sub


The Scroll Bar
   The scrollbar has a maximum value of 255 or 0xFF which means data that can be sent out covers the whole value of a PORT in the 8051, every time the scroll bar changes value, it will be reflected on the label beside it and will be sent out to the serial port.

    Private Sub ScrollData_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles ScrollData.Scroll
        lblDataValue.Text = ScrollData.Value.ToString("X")

        outData(0) = Convert.ToByte(ScrollData.Value)
        SerialPort1.Write(outData, 0, 1)
    End Sub


Receiving data from the Microcontroller
   The received data from the microcontroller will be displayed to the textbox by the following code. This routine is called everytime data is received.

    Private Delegate Sub DisplayDelegate(ByVal displayChar As String)

    Private Sub DisplayCharacter(ByVal displayChar As String)
        txtRxData.Text = displayChar
    End Sub


Remember, we added a serial port component, on its Data Received event put the following code.

    Private Sub serialPort1_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim rx As Integer
        rx = SerialPort1.BytesToRead
        Dim comBuff As Byte() = New Byte(rx - 1) {}
        SerialPort1.Read(comBuff, 0, rx)
        txtRxData.Invoke(New DisplayDelegate(AddressOf DisplayCharacter), New Object() {BytetoHex(comBuff)})
    End Sub



The Project file of this tutorial can be downloaded from THIS LINK

3 comments:

  1. thanx for the tutorial
    very helpful indeed.
    finally a working code

    ReplyDelete
  2. that link is not working can u send it by email - amitkhanna.lim@gmail.com

    ReplyDelete
  3. m looking for sending and receiving data from MPU using .net, anyone can help me my email id amitkhanna.lim@gmail.com

    ReplyDelete