I am using the serial port to send & receive info.
When I send something I need to wait until something comes back (ONcomm event), or a timer timeout occurs (error-->no response), whichever happens first. Otherwise I wait in a while loop waiting for one or the other.
In order to respond to these events I think I must use a DoEvents....however this seems to open up to any event, whci causes bad things to happen.
Is there a way to limit the while loop to respond only to the Oncomm or timout (timer) event, rather than any event in the whole system? The main problem is that new things are getting sent out from various other timers & user clicks before the reception is complete.
Is it possible to wait for a reception or timer timeout, without using Doevents? Nothing else needs to happen during this lull in waiting.
You can set a Global variable in OnComm() and in Timer() events.
Public OnCommHappened as Boolean
Public TimeoutHappened as Boolean
OnCommHappened = True
TimeOutHappened = True
'in your loop
If TimeoutHappened or OnCommHappened then Exit While
The only problem I see, I think without the DoEvents no OnComm() event would be raised...
You would need to have something like a busy flag that is set to true when you start your wait and then in the events that you do not want to fire a check of that flag that will exit the event if busy. Or you could disable your form while busy which would stop the user from clicking any controls or entering data while you are waiting.
It sounds like you are saying I DO need DoEvents...but is there a way to limit them?
I only want to respond to a timeout (generate an error message) or an incoming MScomm message (data coming in). I really don't want to use doevents, but is there any other way. Doevents seems to allow other things to happen such as sending new messages before replies to old ones have been rcvd. Thus things get out of sync.
S=send R=recieve reply
instead of: SA RA SB RC SD RD SE RE....YOU MIGHT GET SA RA SB RB SC SD RC RD
creating quite a mess.
Well, you can poll the MSComm in your loop, then you do not need to use the OnComm().
dim a$, tmo&
tmo = 100000
if a$="" then tmo = tmo -1
loop until a$<>"" or tmo = 0
This loop will run until either a character arrived at the com port, or the counting down of tmo has reached 0.
After that loop you check if a$="" then we have timeout
This runs completely without DoEvents, but the timeout counting is not so elegant...
You'd have to work out the constant yourself. I only put tmo = 100000 just out of thin air. Maybe it is to short a timeout.
Ok, I shall look at it.
Here is how I would implement a timeout using gettickcount
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Const Max_TimeOutTicks = 5000 'approx. 5 seconds
Private Function GetComChar() As Long
Dim begin&, c$
begin = GetTickCount
c$ = MSComm.Input
Loop Until c$ <> "" Or GetTickCount - begin > Max_imeOutCount
If c$ <> "" Then GetComChar = Asc(c$) Else GetComChar = -1
The function would return -1 if timeout occured, otherwise it would return the Asc of the character received.
As the return value is a long you wouldn't get conflicts. You can (if it is not -1) convert it to chr$() without problem. -1 instead would indicate timeout.