From: bicoman on


"bicoman" wrote:

> I'm having a problem with my serial port routines that does not make any
> sense to me.
> I originally wrote the code to use non-overlapped serial port reading and
> writing. It works great. (the serial port anyway). The problem is the
> waitcommevent method hangs the program and it quits responding. Now for the
> weird part. When I go to overlapped io in CreateFile with
> FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung
> anymore, and the connected device is definetly transmitting the appropriate
> bytes, the waitCommEvent function just quits seeing them. I know that
> WaitCommEvent is timing out because I checked. I've been fighting with this
> problem all day and am at my wits end. Has anyone ever had a similar problem?
"Stops Reading" means the data is arriving, I can see it on my o'scope.
WaitCommEvent never returns true, it just times out. So the loop that grabs
the data from the Serial port isa never entered, the program just sits there
spinning its wheels until I left click to abort the process. When CreateFile
is opened without FILE_FLAG_OVERLAPPED, the data is read properly. However,
WaitCommEvent blocks and my controls go dumb.
From: Ian Semmel on
There are too many variables involved. You need to post some code.

Why are you using WaitCommEvent ?

bicoman wrote:
> I'm having a problem with my serial port routines that does not make any
> sense to me.
> I originally wrote the code to use non-overlapped serial port reading and
> writing. It works great. (the serial port anyway). The problem is the
> waitcommevent method hangs the program and it quits responding. Now for the
> weird part. When I go to overlapped io in CreateFile with
> FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung
> anymore, and the connected device is definetly transmitting the appropriate
> bytes, the waitCommEvent function just quits seeing them. I know that
> WaitCommEvent is timing out because I checked. I've been fighting with this
> problem all day and am at my wits end. Has anyone ever had a similar problem?
From: bicoman on


"Ian Semmel" wrote:

> There are too many variables involved. You need to post some code.
>
> Why are you using WaitCommEvent ?
>
> bicoman wrote:
> > I'm having a problem with my serial port routines that does not make any
> > sense to me.
> > I originally wrote the code to use non-overlapped serial port reading and
> > writing. It works great. (the serial port anyway). The problem is the
> > waitcommevent method hangs the program and it quits responding. Now for the
> > weird part. When I go to overlapped io in CreateFile with
> > FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung
> > anymore, and the connected device is definetly transmitting the appropriate
> > bytes, the waitCommEvent function just quits seeing them. I know that
> > WaitCommEvent is timing out because I checked. I've been fighting with this
> > problem all day and am at my wits end. Has anyone ever had a similar problem?
>
Ian,
Thanks for taking the time to respond to this. Here is my code
From: bicoman on


"bicoman" wrote:

>
>
> "Ian Semmel" wrote:
>
> > There are too many variables involved. You need to post some code.
> >
> > Why are you using WaitCommEvent ?
> >
> > bicoman wrote:
> > > I'm having a problem with my serial port routines that does not make any
> > > sense to me.
> > > I originally wrote the code to use non-overlapped serial port reading and
> > > writing. It works great. (the serial port anyway). The problem is the
> > > waitcommevent method hangs the program and it quits responding. Now for the
> > > weird part. When I go to overlapped io in CreateFile with
> > > FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung
> > > anymore, and the connected device is definetly transmitting the appropriate
> > > bytes, the waitCommEvent function just quits seeing them. I know that
> > > WaitCommEvent is timing out because I checked. I've been fighting with this
> > > problem all day and am at my wits end. Has anyone ever had a similar problem?
> >
> Ian,
> Thanks for taking the time to respond to this. Here is my code


bool PickDialog::waitForAnswer(CString* answer){

BicoOutput* bco = new BicoOutput();
OVERLAPPED overlapped;
DWORD dwEventMask;
DWORD iBytesRead;
bool success = TRUE;
char inChar;
MSG msg;
HANDLE hCom;

ddata.getCommDefaults(&cp); //Get comm settings
commPort = sp.openPort(cp); //openPort with FILE_FLAG_OVERLAPPED
sp.clearCommErrors(commPort);

if(!SetCommMask(commPort,EV_RXCHAR))
AfxMessageBox("Failed to Set Communication Mask");

overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
overlapped.Internal = 0;
overlapped.InternalHigh = 0;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
assert(overlapped.hEvent);
inChar = 'n'; //something other than carriage return
*answer = "";
while(inChar != 0x0d ){
success = WaitCommEvent(commPort,&dwEventMask,&overlapped);
if(success){
if(dwEventMask & EV_RXCHAR){
inChar = sp.getOneChar(commPort,&overlapped);
*answer += inChar;
}
}
PeekMessage(&msg,NULL,0,0,PM_REMOVE);
if(msg.message == WM_LBUTTONDOWN){
AfxMessageBox("Exiting Pick");
pickOngoing = FALSE;
inChar = 0x0d;
}
if(!SetCommMask(commPort,EV_RXCHAR))
AfxMessageBox("Failed to Set Communication Mask");
overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
overlapped.Internal = 0;
overlapped.InternalHigh = 0;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
assert(overlapped.hEvent);
}
sp.closePort(commPort);
ddata.~DefaultData();
return success;


}


HANDLE serialPort::openPort(DefaultData::commPortType cpType){

char* cptr;
char cptrArray[32];
HANDLE sPort;
COMMTIMEOUTS commTimeouts;
unsigned long* buff;
DWORD buf;
LPSTR lpszFunction;

FillMemory(&commTimeouts,sizeof(commTimeouts),0);
FillMemory(&dcb,sizeof(dcb),0);
dcb.DCBlength = sizeof(dcb);
lpszFunction = (LPSTR)malloc(sizeof(LPSTR));
buff = &buf;
cptr = &cptrArray[0];
sPort = CreateFile(cpType.comPort,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);

if(!SetupComm(sPort,4096,4096)){
AfxMessageBox("Serial Port Error - Setup Communications Port Failed");
return(0);
}
if(!GetCommState(sPort,&dcb)){
AfxMessageBox("Serial Port Error - Retrieval of Communications State
Failed");
return(0);
}


if(!BuildCommDCB("9600,n,8,1",&dcb)){
AfxMessageBox("Serial Port Error - Build of DCB Failed");
}

if(SetCommState(sPort,&dcb)){
// AfxMessageBox("Success");
}
else{
CHAR szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
wsprintf(szBuf,"%s failed with error %d: %s",lpszFunction, dw,
lpMsgBuf);

MessageBox(NULL, szBuf, "Error", MB_OK);

LocalFree(lpMsgBuf);
ExitProcess(dw);
}
if(!GetCommTimeouts(sPort,&commTimeouts)){
AfxMessageBox("Serial Port Error - Get Communications Timeouts Failed");
}
else{
commTimeouts.ReadIntervalTimeout = 1;
commTimeouts.ReadTotalTimeoutMultiplier = 10;
commTimeouts.ReadTotalTimeoutConstant = 50;
commTimeouts.WriteTotalTimeoutMultiplier = 10;
commTimeouts.WriteTotalTimeoutConstant = 100;
if(!SetCommTimeouts(sPort,&commTimeouts)){
AfxMessageBox("Serial Port Error - Setting of Communications Timeouts
Failed");
}
}
return(sPort);
}

From: Scott McPhillips [MVP] on
bicoman wrote:
>>>>I'm having a problem with my serial port routines that does not make any
>>>>sense to me.
>>>>I originally wrote the code to use non-overlapped serial port reading and
>>>>writing. It works great. (the serial port anyway). The problem is the
>>>>waitcommevent method hangs the program and it quits responding. Now for the
>>>>weird part. When I go to overlapped io in CreateFile with
>>>>FILE_FLAG_OVERLAPPED, my serial port stops reading. The program isn't hung
>>>>anymore, and the connected device is definetly transmitting the appropriate
>>>>bytes, the waitCommEvent function just quits seeing them. I know that
>>>>WaitCommEvent is timing out because I checked. I've been fighting with this
>>>>problem all day and am at my wits end. Has anyone ever had a similar problem?
>>>
>>Ian,
>>Thanks for taking the time to respond to this. Here is my code
>>...

The basic problem is that you don't understand what overlapped I/O does.
When you use it WaitCommEvent is supposed to "fail" and return
quickly, with ERROR_IO_PENDING. This means the operation is continuing
in the background. The purpose is to let your code do other things
while waiting. But you are not doing "other things." Later, when the
background operation has completed, the event in the overlapped struct
will be signaled. But your code is not checking this event.

It is also very inefficient and slow to wait for one character to be
signaled, then call ReadFile to get the one character. The characters
can arrive faster than an awkward program like this can process them.
Instead, you can simply call ReadFile and it will return when it has the
requested number of characters.

Either of these approaches will, however, block the GUI thread, so the
port should be read in a separate thread. I suggest you use the code
from the MTTTY sample in MSDN. It shows how to very efficiently input
from the serial port and send the results back to the main thread.

--
Scott McPhillips [VC++ MVP]