Receive NMEA0183 data from COM PORT C ++

Hello to all!

I wrote a small gps application in simple C ++ that toggles protocoll, send command to gps chip ... etc. GPS port recording works well. But when I try to read the port (to check the commands received) I get a lot of stupid characters. Typically, a NMEA output message looks like this:

$GPGLL,4916.45,N,12311.12,W,225444,A

      

And I got something like this:

1C0CFC14

      

I don't know what happened ... This part of my code is as follows:

LPCVOID buffer[100];
ReadFile(hSerial, buffer, 100, 0, 0);

      

Or another one to log some data:

LPCVOID buffer[100];
ReadFile(hSerial, buffer, 100, 0, 0);
ofstream log ("log.txt");
log << buffer;
log.close();

      

Of course, Hserial has been announced earlier and it works well for the record. When Im declared HANDLE, I opened the hSerial file for reading and writing. The target platform is Windows Mobile 5.0 and 6.0. What's wrong? Many thanks for the help!

+3


source to share


1 answer


Reading data from a GPS port or any other data from a port is not an easy matter.

You need to make sure there is some pending data and that the COM port does not see any previous errors before trying to read. Then, if the read is successful, you need to ensure that the data is correctly completed and contains the complete NMEA sentence. Sometimes you can run the next NMEA sentence, or even a few backwards in the same reading, so you'll have to deal with that.

Leave it all for another day and concentrate on the reading itself.

The 4th parameter ReadFile must be a pointer to a DWORD that will store the number of bytes actually read. You should use this to make sure you have real data. You should also check the return value for errors.



This is how I do it by checking that there is actually some data waiting to be read.

/**

  Read data from port

  @param[in] buffer pointer to location to store data
  @param[in] limit  maximum number of bytes to read

  @return  0 if error

*/
int cSerial::ReadData( void *buffer, int limit )
{

    if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

    BOOL bReadStatus;
    DWORD dwBytesRead, dwErrorFlags;
    COMSTAT ComStat;

    ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
    if( !ComStat.cbInQue ) return( 0 );

    dwBytesRead = (DWORD) ComStat.cbInQue;
    if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

    bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
    if( !bReadStatus ){
        if( ::GetLastError() == ERROR_IO_PENDING ){
            WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
            return( (int) dwBytesRead );
            }
        return( 0 );
        }

    return( (int) dwBytesRead );

}

      

Everything seems to be very complicated, but everything in the above code turned out to be necessary. Without this, your application can work for a while, but at some time it will either freeze or give you dimensions. You can leave some of these checks, but then you will have to spend many hours trying to debug what went wrong with your application - as it was during the development of this code.

+2


source







All Articles