title: flow control during serial communications
body: <p>I have designed an application that communicates with an external device on my development box through a USB->serial adapter (Windows 7 64bit, VS2013, targeting .Net Framework 3.5 SP1).  I also have a test box setup with a native serial port with Windows XP SP3 and .Net Framework 3.5 SP1.  The external device communicates at 19200, N, 8, 1 and supports hardware flow control.  I know the flow control works because when I initiate a report on the device, set flow control to none and manually create a checkbox to turn DTR on and off the device will pause when DTR is toggled off.</p>
  
  <p>I'm having trouble making the hardware flow control work automatically through my Windows desktop application, however (Handshake.RequestToSend).  If I leave handshaking set to None, communication is "usually" successful.  Sometimes on the slower test box with the native serial port I believe the receive buffer is being overrun when requesting large amounts of data from the device, even though I've set a very large buffer and made the DataReceived routine as efficient as possible.  I've tried various flow control settings in the driver itself with no effect.  If I set handshaking to RequestToSend in my application communication appears to stall and the device never responds to my initial status request.  I've tried various combinations of True/False with DtrEnable and RtsEnable to no avail.  I've searched the internet for many hours and haven't seen anything that has so far helped.  Here's some of my code:</p>
  
  <pre><code>  Private sbReceive_Extract As New StringBuilder 'Receive buffer
  
    Private WithEvents comPort As SerialPort
  
    Private bReady as Boolean = False 'data ready flag
  
    Private bExtract as Boolean = False 'type of data request
  
    Public Sub Status_Request()
  
      sbReceive_Extract.Length = 0 'clear buffer
  
      If Open_Port() = True
  
        comPort.DiscardInBuffer()
        comPort.DiscardOutBuffer()
  
        'Send status request to external serial device
        comPort.Write(Chr(27) &amp; "?" &amp; Chr(13))
  
        bExtract = False 'Just get status header this time    
  
        'Loop until device responds to request
        bReady = False
        Do Until bReady = True
          Application.DoEvents()
          'update an onscreen status label as buffer fills
          lblStatus.Text = "Buffer read: " &amp; sbReceive_Extract.Length.ToString
        Loop
  
      End If
  
    End Sub
  
  
    Public Function Open_Port() As Boolean
  
        'return code for port open or closed
      Dim bReturnResult As Boolean = False
  
      If comPort Is Nothing Then
        comPort = New SerialPort
      End If
  
      Try
        With comPort
          .PortName = "COM1"       'comm port 1
          .BaudRate = 19200  'transfer speed
          .DataBits = 8       '8 bits
          .StopBits = StopBits.One
          .Parity = Parity.None
          .ReadBufferSize = 32768 '32768=size of buffer in bytes
          .ReadTimeout = SerialPort.InfiniteTimeout
          .Handshake = Handshake.RequestToSend 'works when set to none
          .DtrEnable = True 'tried both true/false
          .RtsEnable = True 'tried both true/false
          .Encoding = Encoding.Default
          .NewLine = Chr(13) '13=carriage return
          .ReceivedBytesThreshold = 1
        End With
  
        If comPort.IsOpen = False Then
          comPort.Open()
        End If
  
        If comPort.IsOpen = True Then
          bReturnResult = True
        Else
          bReturnResult = False
        End If
  
      Catch Ex As Exception
        bReturnResult = False
      End Try
  
      Return bReturnResult
  
    End Function
  </code></pre>
  
  <p>Private Sub comVoteExt_DataReceived(ByVal sender As SerialPort, 
      ByVal eArgs As SerialDataReceivedEventArgs) 
      Handles comVoteExt.DataReceived</p>
  
  <pre><code>Dim sData As Integer = 0 'integer to hold serial data
  
  Try
    Do
      sData = sender.ReadChar 'take one char off the stack
      sbReceive_Extract.Append(Chr(sData))
      If bExtract = True Then
        'Check for data
        If iLength = 0 Then
            'hex 04 is end of data on tally stream
          If Chr(sData) = Chr("&amp;H04") Then
            iLength = sbReceive_Extract.Length
          End If
        Else
             '6 bytes reserved for checksum and carriage return
          If sbReceive_Extract.Length &gt;= iLength + 6 Then
              'Meets checksum length. Ready for next stage.
            bReady = True
          End If
        End If
      Else
          '20 bytes of header information 
        If sbReceive_Extract.Length &gt; 20 Then
            'Data is ready for next stage. Minimum header length met.
          bReady = True
        End If
      End If
    Loop Until sender.BytesToRead = 0
  Catch exc As Exception
  End Try
  </code></pre>
  
  <p>End Sub</p>
  
  <p>Does anything look like it could be causing my handshaking problem?  Is there some way to "wake up" the device once the port is open so it starts communicating?  I've tried setting DTREnable to true after the port is open and it doesn't seem to matter.  I'm quite stumped.</p>