Running on Win 7. The situation is: I have a hardware device sitting on a serial port and it accepts a set of string commands and returns a response string to each command. As a base, I used a set of code I found on the Web that uses a delegate and separate thread and it works just fine up to a point. The requirement is to be able to poll the device up to every 200 ms. with two commands and send other commands less frequently. The device runs at 57,600 bps.

I can send one of the commands every 200ms and receive the responses perfectly and that will run OK for many minutes. If I then add a second command to the sequence and read its response, responses to the first command are received OK for a short while but responses to the second command are never received. These commands are sent and responses read in a timer tick event. So, the sequence would be: send command 1, read response, send command 2, read response. The code includes the ability to send the commands individually under button control and both commands work just fine.

When running in the timer mode, the commands are being sent and responses to both commands are being received OK but the received data isn't there for the second command. I think the problem lies with possible misunderstanding of the delegate and threading on my part. Any suggestions greatly appreciated. Here's the code:

Code:
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.IO.Ports

Public Class frmMain
    Dim myPort As Array  'COM Ports detected on the system will be stored here
    Delegate Sub SetTextCallback(ByVal [text] As String) 'Added to prevent threading errors during receiving of data
    Dim interval As String

    ' The user can send a single ?AF or ?BF command with the SEND button.  Or, he can send the commands repeatedly
    ' by pressing the TIMED SEND button.  In that case, the tick event sends the ?AF, reads the response, and then
    ' sends the ?BF command and reads that response.  The responses to ?AF and ?BF should update the text boxes 
    ' labeled VFO A and VFO B with the values returned. 

    Private Sub frmMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        'When our form loads, auto detect all serial ports in the system and populate the cmbPort Combo box.
        myPort = IO.Ports.SerialPort.GetPortNames() 'Get all com ports available

        For i = 0 To UBound(myPort)
            cmbPort.Items.Add(myPort(i))
        Next
        cmbPort.Text = cmbPort.Items.Item(0)    'Set cmbPort text to the first COM port detected

        btnDisconnect.Enabled = False           'Initially Disconnect Button is Disabled

    End Sub

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

        SerialPort1.PortName = cmbPort.Text         'Set SerialPort1 to the selected COM port at startup
        SerialPort1.Open()

        btnConnect.Enabled = False          'Disable Connect button
        btnDisconnect.Enabled = True        'and Enable Disconnect button

    End Sub

    Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click

        SerialPort1.Close()             'Close our Serial Port
        btnConnect.Enabled = True
        btnDisconnect.Enabled = False
        Me.Close()

    End Sub

    Private Sub btnSend_Click(sender As System.Object, e As System.EventArgs) Handles btnSend.Click

        SerialPort1.Write(txtTransmit.Text & vbCr) 'The text contained in the txtText will be sent to the serial port as ascii
        'plus the carriage return (Enter Key) 

    End Sub

    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

        ReceivedText(SerialPort1.ReadExisting())    'Automatically called every time a data is received at the serialPort

    End Sub

    Private Sub ReceivedText(ByVal [text] As String)

        'compares the ID of the creating Thread to the ID of the calling Thread
        If Me.rtbReceived.InvokeRequired Then
            Dim x As New SetTextCallback(AddressOf ReceivedText)
            Me.Invoke(x, New Object() {(text)})
        Else
            Me.rtbReceived.Text &= [text]
        End If

    End Sub

    Private Sub cmbPort_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbPort.SelectedIndexChanged
        If SerialPort1.IsOpen = False Then
            SerialPort1.PortName = cmbPort.Text         'pop a message box to user if he is changing ports
        Else                                                                               'without disconnecting first.
            MsgBox("Valid only if port is Closed", vbCritical)
        End If
    End Sub

    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles tmrTimer1.Tick

        Dim freq As String

        'Each time tick occurs, we send a request to the Orion
        SerialPort1.Write("?AF" & vbCr) 'Requests current value of VFO-A along with carriage return

        'Response to the ?AF is a string like "@AF14236789 which will be displayed as: "14.236.789"
        If Me.rtbReceived.Text.StartsWith("@AF") Then
            freq = Mid(rtbReceived.Text, 4, 2) & "." & Mid(rtbReceived.Text, 6, 3) & "." & Mid(rtbReceived.Text, 9, 3)
            freq = freq.TrimStart("0")
            If freq.Length = 9 Then
                txtVFOA.Text = "  " & freq
            Else
                txtVFOA.Text = freq
            End If
            rtbReceived.Text = ""
        End If

        SerialPort1.Write("?BF" & vbCr) 'Requests current value of VFO-B along with carriage return

        'Response to the ?BF is a string like "@BF14236789 which will be displayed as: "14.236.789"
        If Me.rtbReceived.Text.StartsWith("@BF") Then
            freq = Mid(rtbReceived.Text, 4, 2) & "." & Mid(rtbReceived.Text, 6, 3) & "." & Mid(rtbReceived.Text, 9, 3)
            freq = freq.TrimStart("0")
            If freq.Length = 9 Then
                txtVFOB.Text = "  " & freq
            Else
                txtVFOB.Text = freq
            End If
            rtbReceived.Text = ""
        End If


    End Sub


    Private Sub btnTimerOn_Click(sender As System.Object, e As System.EventArgs) Handles btnTimerOn.Click

        tmrTimer1.Enabled = True
        tmrTimer1.Interval = CInt(cmbTimerInterval.Text)

    End Sub

    Private Sub btnStopTimedSend_Click(sender As System.Object, e As System.EventArgs) Handles btnStopTimedSend.Click

        tmrTimer1.Enabled = False

    End Sub

End Class