Problem reading the serial port

Hi,
I'm trying to read from the serial port and print on the screen. In order to test the program I use a GPS. The program (win32 console application, single threaded - see source at the end of the post) runs well for a while and then it runs crazy (see output below).
Can you please give a clue about what's happening?
Thanks!

Here is (part of) the output:

$GPGSV,3,1,09,05,10,139,00,06,75,034,00,07,27,278,00,10,25,062,00*73
$GPGSV,3,2,09,16,17,310,00,18,02,168,00,21,50,205,48,25,32,270,00*78
$GPGSV,3,3,09,30,47,144,49,,,,,,,,,,,,*4C
$PGRME,,M,,M,,M*00
$GPGLL,,,,,182542,*58
$PGRMZ,,,*7E
$PGRMM,User*58
$GPBOD,,T,,M,,*47
$GPWPL,4425.924,N,02608.319,E,T017*26
$GPRMC,182543,V,,,,,,,040906,,*33
$GPRMB,V,,,,,,,,,,,,V*66
$GPGGA,182543,,,,,0,00,,,M,,M,,*6F
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,09,05,10,139,00,06,75,034,00,07,27,278,00,10,25,062,00*73
L,25SV,3,2,09,16,17,310,00,18,02,168,00,21,50,2047,277SV9,14,,,,PG,,0
$G,,,,2116$G82,,095
L,25,,,M69$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,4315$G82,,097
L,25,,,M6B$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,4514$G82,,099
L,25,,,M65$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,3613$G82,,090
L,25,,,M6C$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,0812$G82,,092
L,25,,,M6E$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,7511$G82,,094
L,25,,,M68$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0
$G,,,,1210$G82,,096
L,25,,,M6A$G,1,,,*$G,1,100,0078,250*PG,07,,168,547,277SV9,14,,,,PG,,0


and here is the source:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

HANDLE hCom = CreateFile( "COM2",
GENERIC_READ,
0, // exclusive access
NULL, // no security attributes
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);

if (hCom == INVALID_HANDLE_VALUE)
{
// Handle the error.
}

// Set the event mask.
BOOL fSuccess;
fSuccess = SetCommMask(hCom, EV_RXCHAR);

if (!fSuccess)
{
// Handle the error.
}

//now we need to set baud rate etc,
DCB dcb = {0};
dcb.DCBlength = sizeof(DCB);

if (!::GetCommState (hCom, &dcb))
{
TRACE ( "Failed to Get Comm State Reason: %d",GetLastError());
return E_FAIL;
}

dcb.BaudRate = CBR_4800;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;

if (!::SetCommState (hCom,&dcb))
{
ASSERT(0);
TRACE ( "Failed to Set Comm State Reason: %d",GetLastError());
return E_FAIL;
}

//now set the timeouts ( we control the timeout overselves using WaitForXXX()
COMMTIMEOUTS timeouts;

timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;

if (!SetCommTimeouts(hCom, &timeouts))
{
ASSERT(0);
TRACE ( "Error setting time-outs. %d",GetLastError());
return E_FAIL;
}

// Create an event object for use in WaitCommEvent.
OVERLAPPED o;
memset(&o, 0, sizeof(o));
o.hEvent = CreateEvent(
NULL, // no security attributes
FALSE, // auto reset event
FALSE, // not signaled
NULL // no name
);

assert(o.hEvent);
bool abContinue = true;

DWORD dwEvtMask = EV_RXCHAR;
while ( abContinue )
{
BOOL abRet = ::WaitCommEvent(hCom, &dwEvtMask, &o);
if (!abRet)
{
DWORD x = GetLastError();
//cout << "Status=" << x << endl;
ASSERT( x == ERROR_IO_PENDING);

}

HANDLE arHandles[] = {o.hEvent};

DWORD dwWait = WaitForMultipleObjects (1, arHandles, FALSE, INFINITE);

switch ( dwWait )
{
case WAIT_OBJECT_0:
{
if (dwEvtMask & EV_RXCHAR)
{
try
{
std::string szDebug;
std::string m_szInternalBuffer;
BOOL abRet = false;

DWORD dwBytesRead = 0;
OVERLAPPED ovRead;
memset(&ovRead,0,sizeof(ovRead));
ovRead.hEvent = CreateEvent( 0,true,0,0);

do
{
ResetEvent( ovRead.hEvent );
char szTmp[1];
int iSize = sizeof ( szTmp );
memset(szTmp,0,sizeof szTmp);
abRet = ::ReadFile(hCom, szTmp, sizeof(szTmp), &dwBytesRead, &ovRead);
if (!abRet )
{
abContinue = FALSE;
DWORD x = GetLastError();
cout << endl << endl << "Status=" << x << endl;
break;
}
if ( dwBytesRead > 0 )
{
printf("%c", szTmp[0]);
}
} while (0);
CloseHandle(ovRead.hEvent);
}
catch(...)
{
ASSERT(0);
}
}
ResetEvent ( o.hEvent );
}
break;
}
}
return nRetCode;
}
[5389 byte] By [oti] at [2007-11-20 1:11:37]
# 1 Re: Problem reading the serial port
Have you tried reading in the data line-by line rather than character-by character?

It seems like things are getting backed up.

In this example the number if characters in a line is 68, so you could use:

unsigned NumToRead = 68;
unsigned char Buff[100];
unsigned long NumBytesRead = 0;

CString StringRead = "";
memset(Buff,0,sizeof Buff);

if(!ReadFile(comhandle, Buff, NumToRead, &NumBytesRead, NULL))
//Read Failed

for(j=0;j<NumBytesRead;j++)
StringRead += Buff[j];

perhaps printing each character after reading in the next one is slowing things down too much and creating a backup in the data.
denno at 2007-11-10 23:19:13 >
# 2 Re: Problem reading the serial port
Very, very good ideea. It works perfectly now.

Thank you very, very much.
oti at 2007-11-10 23:20:09 >