Receiving Text with a Delegate.

Receiving  Text with a Delegate.

The serial port has some special  requirements in .Net.  This snippet shows how to implement a serial input  text receiving routine using a delegate to enable updating of GUI objects.

Create a form with a listbox (“lstPorts”),  a textbox (“txtReceived”), a button (“btnStart”) and a serial port  (“SerialPort1”).  Adjust the textbox so that Multiline is True.  Add  the following code for the form load event to initialize the listbox with the  available serial ports.

Private Sub  Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles  MyBase.Load
  For Each s In System.IO.Ports.SerialPort.GetPortNames()
    lstPorts.Items.Add(s)
  Next s
End Sub

Add the following code for the btnStart  Click command to initialize and open the serial port.  Note that these  values are appropriate for a standard GPS device. Your serial device may require  different values.

Private Sub  btnStart_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs)  Handles btnStart.Click
  If lstPorts.SelectedIndex = -1 Then
    MsgBox("Please select a port")
    Exit Sub
  Else
    SerialPort1.BaudRate = 4800
    SerialPort1.DataBits = 7
    SerialPort1.Parity = IO.Ports.Parity.None
    SerialPort1.StopBits = IO.Ports.StopBits.One
    SerialPort1.PortName = lstPorts.SelectedItem.ToString
    SerialPort1.Open()
  End If
End Sub

The problem that has to be addressed with  using the serial port is that the serial port runs on a different thread than  the main GUI loop.  Therefore, GUI controls cannot be referenced directly  from the data received event – the data must be passed over in a way that avoids  threading issues.  In this example we will use delegates.

Delegates are a Type that can  refer to a method (a Sub or Function).  It is, basically, the address in  memory of the Sub or Function.  But it also contains information about the  argument list of a Sub or Function, and the return type of a Function.   Therefore, before you can create a delegate, you need to create a Type that  indicates the exact form of the Sub or Function it will refer to.   That means it is a three-step process to create the delegate – create the type,  then create a variable to use for the object of that type, then create the  object and assign it to the variable.  Add the following lines at the form level:

'1. Define (create) the delegate type we  want to use. It will be 
'   a SUB with one argument (a string)
Delegate Sub SetReceivedText(ByVal ReceivedData As String)
'2. Declare a variable of the correct type
Dim d As SetReceivedText

Now, at the form level, create the Sub that  we will reference from the delegate variable we have just created.  And in  the form load event, assign (the address of) that Sub to the variable (step 3 in  creating the delegate). Note that this is a general form of this sub that will  work with any GUI object with a text property.

Private Sub SetText(ByVal myData As  String)
  If Me.txtReceived.InvokeRequired Then 
    Me.Invoke(d, New Object() {myData})
  Else
    Me.txtReceived.Text &= myData
  End If
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As  System.EventArgs) Handles MyBase.Load
  '3. Assign an object to the delegate variable
  d = New SetReceivedText(AddressOf SetText)

  '...

Finally, in the data received event, pass  the received data to the Sub that has been delegated.

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

And, for safety, add a second button (btnClose) that will  close the serial port before the form is closed.

Private Sub  btnStop_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs)  Handles btnStop.Click
  SerialPort1.Close()
End Sub

 

  1. #1 by A Zwiefel on March 17, 2014 - 10:36 pm

    This works great, but I’m running into a threading issue which causes my interface to lock-up intermittently any guidence on how to address this?

    Thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s