Wait for serial port

  • Thread starter Thread starter kpg
  • Start date Start date
K

kpg

Hi all,

What is the 'best' way to wait for data from a serial port.

I'm using ,net 2.0 system.io.port, and I have a working class that listenes
to the serial port's data received event.

I want to implement a WaitForResponse method that will send a command to
the com port and wait for the completed reply (a CR terminates a reply).

I don't want to sit there and poll it in a loop, and sleeping seems
inefficient to me (how long to sleep?). Concerning the sleep, I'm assuming
here that the com port is running on a different thread so if I sleep my
thread it will continue - is that correct?

Here are the highlights of the serial port class:

_RXBuffer as string

Public Sub New()
AddHandler comPort.DataReceived, AddressOf myDataReceived
End Sub

Public Sub WriteData(ByVal buffer As String)
comPort.Write(buffer)
End Sub

Private Sub comPort_DataReceived(ByVal sender As Object, _
ByVal e As SerialDataReceivedEventArgs)
Dim buffer As String = comPort.ReadExisting()
_RXBuffer &= buffer
End Sub


I want to add:

Public Sub WaitForResponse(ByVal buffer As String)
comPort.Write(buffer)
'wait here until there is some data to inspect
'then test if data has a CR
'is so exit sub
End Sub


This code must have been written a million times by now. Either my google
skills are impaired or it's a closely guarded secret :0


Thanks,
kpg
 
could it be this simple????


Public Sub WaitForResponse(ByVal buffer As String)
comPort.WriteLine(buffer)
_RXBuffer = comPort.ReadLine()
End Sub
 
Probably it is not that simple.

The answer is, it depends. (IMO)

If this is a command/response protocol -- that is, you send a command and
wait for a response, then a loop is exactly what you want. This loop could
be in a background thread, but more frequently (and efficiently) you simply
wait in a loop for the response, often including a call to
Thread.Sleep(somenumberofmS) in the loop (an occasionally,
Application.DoEvents, though usually isn't needed). This allows you to time
out of the loop should you not receive the expected response within a
reasonable time. This same looping operation could be in a thread, with a
callback. This sort of this is appropriate for complex responses that may
take an extended period of time to be received. More commonly, a
command/response pair would take a second or so, and the extra expense, in
both performance and code, of creating the thread isn't warranted.

If the response is asynchronous -- that is, not generated by a specific
command, then the most common design pattern is to use the DataReceived
event.

In most cases, you don't want to use the ReadLine method, which only works
with strings, terminated specifically by the newline characters that are
defined. It is a blocking call, and these (IMO) should be avoided.

Dick

--
Richard Grier, Consultant, Hard & Software 12962 West Louisiana Avenue
Lakewood, CO 80228 303-986-2179 (voice) Homepage: www.hardandsoftware.net
Author of Visual Basic Programmer's Guide to Serial Communications, 4th
Edition ISBN 1-890422-28-2 (391 pages) published July 2004, Revised July
2006.
 
Thanks for the reply.

It is a simple command/response model, I expect responses back in less
than one second.

As far as the ReadLine I've learned that the Serial port class does
accept a user defined end of line character, and a read timeout can be
set, so on the surface it sounds like it could be used without the
danger of falling in a black hole.

As far as it being a blocking call, that's what I'm trying to implement
with my WaitForResponse. But, yes, I tend to agree perhaps a loop would
be best, Why give up control when there is no need.

From my VB6 days I've use DoEvents a lot and Sleep almost never. Evey
time I sleep in a VB6 program the thing I'm waiting also sleeps. Same
thread I suppose. Is there a dnager of losing com port data while my
thread is sleeping?


kpg
 
Back
Top