Sending Serial Strings With Visual Studio 2010

image

Yesterday I had to write a program that let me test a serial data path between two electronic designs.  We use Visual Basic around here since it’s quick and easy. The current version of the software we have is Visual Studio 2010.

We probably should to upgrade to Visual Studio 2012, but it were not really “power users” so I don’t think we’d get much more efficient than if we stick with the 2010 version.   Maybe we’ll switch in another year or two.

The serial test program was a pretty simple project.  And its only for internal use, so just hammering away at a solution works, and I was able to get this done and tested in a couple of hours.

The first thing I needed to do was select two COM ports on a computer.  I used a “listbox” control for displaying and selecting the COM port.  The code below is modified from my program in that it only shows a single listbox that gets filled with available COM ports.  In the image above it is the left hand listbox.  I also have the routine  display an error message if there are no ports.  And I  make sure that if there is a listbox item selected when this routine is called its index is stored and then re-selected at the end of the routine when ports are displayed.  To add the second COM port listbox you just copy and paste the code below into the same routine and rename the variables so there is a set for each port you will be selecting.

   Public Sub GetSerialPortNames()

        Dim SelectedCom As Integer
        If ListBoxCOM.Items.Count <> 0 Then
            SelectedCom = ListBoxCOM.SelectedIndex
        End If

        ListBoxCOM.Items.Clear()

        For Each sp As String In My.Computer.Ports.SerialPortNames
            ListBoxCOM.Items.Add(sp)
        Next

        If ListBoxCOM.Items.Count = 0 Then
            ListBoxCOM.Enabled = False
            labellistboxCOM.Text = "No Ports"
            labellistboxCOM.ForeColor = Color.Crimson
        Else
            ListBoxCOM.Enabled = True
            ListBoxCOM.SelectedIndex = SelectedCom
            labellistboxCOM.Text = ""
        End If

    End Sub

Serial data can go two directions in my program.  It can go from port1 to port2, or from port2 to port1.  These are two different electrical paths, so they both need to be tested.  The routine below sends data in one direction.  I have another routine not shown that sends it the other. Since I’m just checking that the each path works I can send/receive strings.  These are much easier to send in VS2010 than byte arrays.

When I call the serial communication routine the first thing I do is update the baud rate (by testing some radio button states on the form).  It might be nice to have this software cycle through baud rates so it tests communication across a variety range of speeds).  However, there are 4 or 5 different devices that need to be tested with this software, and it probably takes more time to come up with the best way to implement an automatic system than just sticking radio buttons on the form.

After baud rate selection I open the receiving port (determined by the port selected in the ListboxCOM2 control) and then open the transmitting port (ListboxCOM control) .  With both ports open I use the WrtieLine and ReadLine functions to send and receive a string of data with the two ports.  The string I send is in a textbox on the form.  That way I can easily change the data if necessary.

   Private Sub Port1_to_Port2_Serial_Communication()

        Dim BaudRate As Integer = 9600
        If RadioButton_Baud2400.Checked = True Then
            BaudRate = 2400
        ElseIf RadioButton_Baud9600.Checked = True Then
            BaudRate = 9600
        ElseIf RadioButton_Baud19200.Checked = True Then
            BaudRate = 19200
        ElseIf RadioButton_Baud38400.Checked = True Then
            BaudRate = 38400
        ElseIf RadioButton_Baud57600.Checked = True Then
            BaudRate = 57600
        End If

        Dim port2 As IO.Ports.SerialPort = Nothing
        Try
            port2 = My.Computer.Ports.OpenSerialPort(ListBoxCOM2.SelectedItem)
            port2.BaudRate = BaudRate
            port2.ReadTimeout = 100

            Using port1 As IO.Ports.SerialPort = _
              My.Computer.Ports.OpenSerialPort(ListBoxCOM.SelectedItem)
                port1.BaudRate = BaudRate
                port1.WriteLine(TextBox_Port1_transmit.Text)
                port1.Close()
            End Using

            Dim Incoming As String = port2.ReadLine()
            If Incoming Is Nothing Then
                TextBox_Port2_receive.Text = ""
            Else
                TextBox_Port2_receive.Text = Incoming
            End If

        Catch ex As TimeoutException
            Label_CommStatus.Text = "READ TIMEOUT"
            Label_CommStatus.BackColor = Color.Red
        Finally
            If port2 IsNot Nothing Then port2.Close()
        End Try

    End Sub

 

To tie all of this together I run a timer that checks various flags to determine if a test has been activated.  The flags are set with button presses that are not shown here.   For example, I have a button that sets the flag Command_SerialSend_1to2.  When this flag is set I call the Port1_to_Port2_Serial_Communication()  function inside my timer routine.  After being called the timer code tests to see if my transmit textbox is the same as my receive textbox.   If they match then the serial data transfer was successful.  I’ve also included a checkbox control associated with each function that prevents the command flag from being cleared.  By selecting the checkbox I can make the test program send  strings continuously.  This is helpful when you need to probe around on a circuit with your oscilloscope to find out where a serial data path is broken.

I even added a couple of visual indicator that tell me if I had good or bad data transfer.  When the data is sent and received correctly I turn the background of the receive textbox green and append the number of good data packets sent/received.  I have good and bad packet counters that help determine if there are intermittent failures.  We might run a system for a day or two to see if communication is error free, and these counters can help do that.

A second command I have is called “fast ping pong”.   It’s not very fast, but is named after the fact that I use it to send 16 strings alternating from port 1->2 then port 2->1.  It’s a fast test for me to see if the modules I’m testing are working.  When I press the Fast Ping Pong button I get repeated communication attempts in both directions for a couple of seconds.  So a single button press does all of my testing, and that makes life easier.

  Private Sub TimerRead_Tick_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerRead.Tick

        TimerRead.Enabled = False

        Label_CommStatus.Text = "COM OK"
        Label_CommStatus.BackColor = Color.LightSteelBlue

        'Do fast Ping
        If Command_SerialSend_Ping = True Then
            Command_SerialSend_1to2 = True
            Command_SerialSend_2to1 = True
            PingCount = PingCount - 1
            If PingCount = 0 Then
                Command_SerialSend_Ping = False
            End If
        End If

        'Update COM port
        If Command_ChangePort = True Then
            Command_ChangePort = False
            GetSerialPortNames()
        End If

        If Command_SerialSend_1to2 = True Then
            If CheckBox_Repeat_1to2.Checked = False Then
                Command_SerialSend_1to2 = False
            End If
            Port1_to_Port2_Serial_Communication()
            If TextBox_Port1_transmit.Text = TextBox_Port2_receive.Text Then
                SerialTest_GoodCount = SerialTest_GoodCount + 1
                TextBox_Port2_receive.Text = TextBox_Port2_receive.Text & " " & SerialTest_GoodCount
                TextBox_Port2_receive.BackColor = Color.LightGreen
            Else
                SerialTest_BadCount = SerialTest_BadCount + 1
                TextBox_Port2_receive.Text = TextBox_Port2_receive.Text & " " & SerialTest_GoodCount
                TextBox_Port2_receive.BackColor = Color.LightPink
            End If
        End If

        If Command_SerialSend_2to1 = True Then
            If CheckBox_Repeat_2to1.Checked = False Then
                Command_SerialSend_2to1 = False
            End If
            Port2_to_Port1_Serial_Communication()
            If TextBox_Port2_transmit.Text = TextBox_Port1_receive.Text Then
                SerialTest_GoodCount = SerialTest_GoodCount + 1
                TextBox_Port1_receive.Text = TextBox_Port1_receive.Text & " " & SerialTest_GoodCount
                TextBox_Port1_receive.BackColor = Color.LightGreen
            Else
                SerialTest_BadCount = SerialTest_BadCount + 1
                TextBox_Port1_receive.Text = TextBox_Port1_receive.Text & " " & SerialTest_GoodCount
                TextBox_Port1_receive.BackColor = Color.LightPink
            End If
        End If

        Label_BadCount.Text = SerialTest_BadCount
        Label_GoodCount.Text = SerialTest_GoodCount

        TimerRead.Enabled = True

    End Sub

Speak Your Mind

*