Re: Reading Serial Port
On Jan 30, 11:50 am, clinisbut <clinis...@gmail.com> wrote:
After reading a lot about threads, now I can understand the example
fromhttp://www.flounder.com/serial.htm.
I need to comunicate with a device that I tested and works OK, it just
sends frames at 9600 bauds (other programs receive their frames as
expected).
In my firsts attempts I was receiving corrupted frames, but I think I
corrected it adjusting the dcb to:
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = CBR_9600;
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
dcb.XonLim = 2048; //I think just a 0 will work,
so I have all flow controls at false
dcb.XoffLim = 512; //I think just a 0 will
work, so I have all flow controls at false
dcb.ByteSize = 8;
dcb.Parity = ODDPARITY;
dcb.StopBits = 0;
dcb.XonChar = 0;
dcb.XoffChar = 0;
dcb.ErrorChar = 0;
dcb.EofChar = 0;
dcb.EvtChar = 0;
Ok, mostly all corrupted bytes dissapeared.
This is the frame I should receive (16 bytes length):
af 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 b9
My first problem comes with a curious fact:
I always get the frame 16th cutted!!
Sometimes I just receive its last byte (b9), or some middle 0x00
ommited... other times af and 0a with some 0's...
Example:
af 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 b9 //15th frame
00 00 b9 //
16th frame
af 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 b9 //17th frame
What's wrong??? I found that 256/16 (bytes) = 16 frames. Is this
casual?? Note that this only happens in frame 16th, no error with
frame number 32 or other.
Here my reader handler where I read single bytes every loop:
void MyThread::OnReadData( WPARAM wParam, LPARAM )
{
BOOL reading = TRUE;
DWORD dwError = 0;
DWORD bytesRead;
COMSTAT comState;
HANDLE hArray[2]; //Un array de eventos
hArray[0] = ShutdownEvent;
hArray[1] = ovReader.hEvent;
//Extrae el estado del puerto y limpia el flag de error para
siguientes operaciones I/O
ClearCommError( hComm, &dwError, &comState );
while( reading )
{
unsigned char buffer;
BOOL ok = ::ReadFile( hComm, &buffer, 1, &bytesRead, &ovReader );
if( !ok ) //ERROR
{
DWORD err = GetLastError();
if( err!=ERROR_IO_PENDING )
{
TRACE("Error lectura.\n");
reading = FALSE;
continue; //Nos saltamos el switch
}
//Ahora esperamos a que ocurra Shutdown o ovReader
DWORD result = WaitForMultipleObjects( 2, hArray, FALSE,
INFINITE );
switch( result )
{
//Esperar
case WAIT_OBJECT_0: //Shutdown
TRACE("SHUTDOWN!\n");
reading = FALSE;
continue;
case WAIT_OBJECT_0+1: // I/O complete!
//TRACE("DATA RECEIVED!.\n");
ok = GetOverlappedResult( hComm, &ovReader, &bytesRead,
TRUE );
if(!ok )
{
TRACE( "ERROR getoverlapped result.\n");
reading = FALSE;
continue;
}
else
{
TRACE( "Received with delay: bytesRead:%d buffer:%d
\n",bytesRead, buffer);
}
break;
}
}
else
{
TRACE("\nOK==TRUE -->bytesRead:%d buffer:%d\n",bytesRead, buffer);
}
if( bytesRead>0 )
{
this->notificador->PostMessage(UWM_DATA_READ, (WPARAM)buffer);
}
else //Nothing readed
continue;
}
}
If you are wondering why I'm reading justa a byte each time when all
frames are 16 bytes length it's because this is just a test, in the
final version the device will send variable frame lengths.