Versions:
Visual Basic 2005 Express Edition
DotNet 2.0
Windows XP SP 2
Problem:
In writing an app that communicates with a machine via the serial port I've encountered a conceptual problem, I use an event handler to catch response but the is port slow so I wrote the function CheckInput() to wait a few seconds for the machine to respond with the right string, checking each loop for matching input in a buffer filled by the event reciever.
Unfortunately I don't seem to get any result from the event handler while inside the loop unless i use Application.DoEvents which seems to create exactly the same problem, it lets the rest of the form carry on processing and doesn't write to the buffer until I exit the loop at which point I've already returned false.
Hope that makes sense, below is my code edited for clarity and brevity.
Thanks,
Nick.
Code:
Imports System.Text Imports System.IO.Ports Imports System.Xml Public Class Form1 Dim WithEvents Port As New SerialPort Delegate Sub SetTextCallback(ByVal [text] As String)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Port Configuration
Port.PortName = Me.cmbSerialPort.SelectedItem
Port.Encoding = ASCIIEncoding.ASCII
Port.BaudRate = 38400
Port.DataBits = 8
Port.Parity = Parity.None
Port.StopBits = StopBits.One
Port.RtsEnable = True
End Sub
'Waits tWait seconds for the machine to respond with checkVal
'either in the whole buffer or the last line.
Function CheckInput(ByVal checkVal As String, ByVal tWait As Double, _
ByVal type As String)
Dim start, finish As Double
start = Microsoft.VisualBasic.Timer
finish = start + tWait
Do While (Microsoft.VisualBasic.Timer < finish)
Application.DoEvents()
Dim Lines() As String = Me.txtStatus.Lines
If Lines(Lines.Length - 1).Contains(checkVal) Then
Return True
End If
Loop
Return False
End Function
'Sends Data to a serial Port
Private Sub SendData(ByVal data As String)
If Not Port.IsOpen Then
Try
Port.Open()
Catch ex As Exception
MessageBox.Show("Error Opening Port:" & Port.PortName)
Exit Sub
End Try
End If
Try
Port.Write(data)
Catch ex As Exception
MessageBox.Show("Error writing to Port: " & Port.PortName, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
'Threadsafe call to txtStatus
Private Sub DisplayText(ByVal [text] As String)
If Me.txtStatus.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf DisplayText)
Me.Invoke(d, New Object() {[text]})
Else
Me.txtStatus.AppendText([text])
End If
End Sub
'Event handler for Serial Port
Private Sub port_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles Port.DataReceived
If e.EventType <> SerialData.Chars Then Exit Sub
Dim inData As String = Port.ReadExisting
DisplayText(inData)
End Sub
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
If Port.IsOpen Then
SendData("quit" & vbLf)
Port.Close()
Port.Dispose()
Else
Port.Dispose()
End If
End Sub
End Class

Handling data from a Serial Port event
Dave Biggins
Maybe you should let the port_DataReceived subroutine use the SetTextCallBack delegate to send an event to the display routine instead of calling the display routine directly.
We have a small sample program on the knowledge base on our web site, which shows how this may be done. The whole project incl. source code may be downloaded from:
http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm
Good luck.
Innovatic
Carsten Kanstrup
Jimbo M
hi,
Is your problem solved If yes, then can you please mark it as answer by clicking "Mark as Answer". If your problem still persists then please let us know so that someone can respond.
Thank you,
Bhanu.