2012-04-04 12 views
3

Hy alle!Empfange NMEA0183-Daten von COM PORT C++

Ich schrieb eine kleine GPS-Anwendung in einfachen C++, was das Protokoll wechseln, Befehl an den GPS-Chip senden ... etc. Das Schreiben in den GPS-Port funktioniert gut. Aber wenn ich versuche, den Port zu lesen (um die akzeptierten Befehle zu überprüfen), erhalte ich viele dumme Zeichen. Normalerweise ist eine NMEA Ausgangsmeldung etwas wie folgt aus:

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

Und ich erhielt ähnlich:

1C0CFC14 

Ich weiß nicht, was falsch ... Dieser Teil meines Codes ist der nächste:

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

Oder ein anderes für log einige Daten:

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

Natürlich ist das Hserial vorher deklariert und es funktioniert gut zum Schreiben. Wenn ich den GRIFF deklariert habe, habe ich die hSerial-Datei auch zum Lesen und Schreiben geöffnet. Die Zielplattform ist Windows Mobile 5.0 und 6.0. Was ist los? Vielen Dank für die Hilfe!

+0

Sind diese Zeichen immer im Bereich 0-9 und A-F? Wenn ja, sind sie hexadezimale Ziffern, verwenden Sie einen Hex-Viewer? Du sagst, dass es gut für das Schreiben ist, was sind deine Hinweise, das zu sagen? Nur versuchen, das Problem zu isolieren ,,, –

Antwort

1

Das Lesen von Daten von einem GPS-Port oder andere Daten von einem Port ist nicht gerade eine einfache Sache.

Sie müssen sicherstellen, dass einige Daten warten und dass der COM-Port keine vorherigen Fehler enthält, bevor Sie versuchen, zu lesen. Wenn das Lesen erfolgreich ist, müssen Sie sicherstellen, dass die Daten ordnungsgemäß beendet werden und einen vollständigen NMEA-Satz enthalten. Manchmal kannst du den Anfang des nächsten NMEA-Satzes oder sogar mehrere hintereinander in einem Lesevorgang gattieren, also musst du damit umgehen.

Lassen wir das alles für einen anderen Tag und konzentrieren uns auf das Lesen selbst.

Der 4. Parameter von ReadFile sollte ein Zeiger auf ein DWORD sein, das die Anzahl der tatsächlich gelesenen Bytes speichert. Sie sollten dies verwenden, um sicherzustellen, dass Sie echte Daten erhalten. Sie sollten auch den Rückgabewert auf Fehler prüfen.

Hier ist, wie ich es tue, nach der Überprüfung, dass tatsächlich einige Daten warten, um gelesen zu werden.

/** 

    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); 

} 

Es scheint alles sehr kompliziert, aber alles in dem oben genannten Code ist notwendig. Ohne sie kann Ihre App für eine Weile laufen, aber irgendwann wird sie entweder hängen bleiben oder Sie werden verzerrt. Sie können einige dieser Überprüfungen auslassen, aber dann müssen Sie viele Stunden damit verbringen, zu debuggen, was bei Ihrer App schief gelaufen ist - wie bei der Entwicklung dieses Codes.

+0

Vielen Dank Ihre schnelle Antwort! Ich versuche deinen Code zu verstehen, aber es ist zu schwierig für meinen Hobbyentwickler. Kennen Sie einen einfacheren Weg? – Luther

+0

Ich habe deine Lösung versucht, aber es funktioniert nicht. Das Problem ist das gleiche. Ich bekomme nur blöde Charaktere ... – Luther