2016-06-17 20 views
0

Ich habe ein C++ Programm läuft auf einem Intel Edison lesen einige GPS-Daten von einem seriellen Anschluss und echo es zurück zur Konsole.C++ Eclipse Konsole Kodierung Klartext als andere Zeichen

Dieser Teil funktioniert gut, aber wenn die Zeichenfolgen in der Konsole gelesen werden, haben sie Zeichen, die nicht dort sein sollten, wie "Ž". Ich vermute, dass etwas mit der Codierung in der Eclipse-Konsole/G ++ zu tun hat, und denkt, dass einige der Messwerte Zeichencodes sind.

Hier ist eine Ausgabe von der Eclipse-Konsole:

$GPVTG,,T,,M,0.041,N,0.075,K,A*24 
$GPGGA,225153.00,5206.75433,N,12206.88881,W,1,10,1.03,582.1,M,-15.6,M,,*6F 
$GPGSA,A,3,32,02,12,14,24,06,03,19,17,25,,,1.84,1.03,1.53*05 
$GPGSV,3,1,11,¬é­N 
-> 02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36*79 
$GPGSV,3,2,11,14,10,316,30,17,20,072,27,19,45,069,40,24,36,215,35*7E 
$GPGSV,3,3,11,25,29,301,28,29,05,254,,32,07,305,33*40 
$GPGLL,5206.75433,N,12206.88881,W,225153.00,A,A*78 
.53*05 
$GPGSV,3,1,11,¬é­N 

Und hier ist ein Teil der Ausgabe als direkt aus dem seriellen Anschluss an der Edison (cat /dev/ttyMFD1) lesen:

$GPVTG,,T,,M,0.048,N,0.090,K,A*26 
$GPGGA,225407.00,5206.75339,N,12206.88816,W,1,10,1.02,584.2,M,-15.6,M,,*6C 
$GPGSA,A,3,32,02,12,14,24,06,03,19,17,25,,,1.80,1.02,1.49*0B 
$GPGSV,3,1,11,02,52,176,15,03,10,026,20,06,59,086,29,12,69,295,41*76 
$GPGSV,3,2,11,14,09,316,29,17,19,072,29,19,44,070,34,24,35,215,32*74 
$GPGSV,3,3,11,25,30,301,29,29,06,254,,32,06,304,17*4C 
$GPGLL,5206.75339,N,12206.88816,W,225407.00,A,A*7F 
$GPRMC,225408.00,A,5206.75337,N,12206.88814,W,0.058,,170616,,,A*6F 

Ich habe versucht, Alle Kodierungsoptionen, die auf der Registerkarte "run configurations common" verfügbar sind, erzeugten jedoch alle seltsame Ergebnisse, sogar chinesische Zeichen!

Der entsprechende Code ist char array[255]; die Puffer zu initialisieren, und dann dazu die seriellen Daten in die Puffer und gibt es in die Konsole zu lesen:

while(true){ 
    dev->read(array,255); 
    std::cout<<"-> "<<array<<std::endl; 
} 
+0

Ich glaube nicht, dass dies eine Sonnenfinsternis ist. Sieht so aus, als ob du nach einer nicht abgeschlossenen Zeichenkette etwas Mist liest oder druckst. Die Token stehen alle nebeneinander. '$ GPGSV, 3,1,11, € N02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36 * 79' sieht aus wie es sein sollte' $ GPGSV, 3,1, 11,02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36 * 79 'und die Prüfsumme stimmt überein. – user4581301

+0

@ user4581301 Ich denke, dein Recht, es sieht so aus, als ob ich das Problem jetzt gefunden habe, nur noch ein paar Tests, um sicher zu sein –

Antwort

0

Stellt sich heraus, es war kein Problem mit Codierung. Ich begann zu erkennen, dass es etwas anderes war, als ich versuchte, dasselbe mit NodeJS zu machen, und die gleiche Ausgabe zurückbekam.

Ich habe vergessen, dass der korrekte Weg zum Lesen der Ausgabe von diesem GPS-Modul ist, die Zeichen einzeln zu lesen, bis Sie den Newline-Terminator am Ende der Linie treffen, und dann damit arbeiten/log es zu trösten.

Also mein Code dann wurde:

char array[255]; 
char c[1]; 
int i = 0; 

while(true){ 
    dev->read(c,1); 

    if(c[0] == '\n'){ 
     i = 0; 

     std::cout<<"-> "<<array<<std::endl; 

     char *begin = array; 
     char *end = begin + sizeof(array); 
     std::fill(begin, end, 0); 
    }else{ 
     array[i] = c[0]; 
     ++i; 
    } 
} 

Welche funktioniert jetzt perfekt :)

+1

Empfehlung: 'char c;' anstatt ein Array von 1, und dann 'dev-> lesen (& c, sizeof (c)); '' sizeof (c) ''ist ein bisschen pedantisch, erlaubt aber die Erweiterung auf große Zeichen. Kein Problem mit irgendeinem mir bekannten NMEA-Format. – user4581301

1

dieser Block Gegeben:

-> 02,51,176,30,03,10,027,17,06,60,088,33,12,68,295,36*79 
$GPGSV,3,2,11,14,10,316,30,17,20,072,27,19,45,069,40,24,36,215,35*7E 
$GPGSV,3,3,11,25,29,301,28,29,05,254,,32,07,305,33*40 
$GPGLL,5206.75433,N,12206.88881,W,225153.00,A,A*78 
.53*05 
$GPGSV,3,1,11,¬é­N 

rn Addition der beiden Zeichen des CRLF zu repräsentieren, endet eine Zeile von NMEA-Daten, und dann nur die Anzahl der Zeichen zwischen dem Müll zu zählen, ich bekomme

ABCDEF 
0 02,51,176,30,03, 
1 10,027,17,06,60, 
2 088,33,12,68,295 
3 ,36*79rn$GPGSV,3 
4 ,2,11,14,10,316, 
5 30,17,20,072,27, 
6 19,45,069,40,24, 
7 36,215,35*7Ern$G 
8 PGSV,3,3,11,25,2 
9 9,301,28,29,05,2 
A 54,,32,07,305,33 
B *40rn$GPGLL,5206 
C .75433,N,12206.8 
D 8881,W,225153.00 
E ,A,A*78rn.53*05r 
F n$GPGSV,3,1,11, 

255 Zeichen

genau eines dieser:

dev->read(array,255); 

Günstige Hack zu

char array[256]; 

und dann

dev->read(array,sizeof(array)-1); 
array[sizeof(array)-1] = '\0'; 

Aber ich denke, Sie besser dran mit etwas Sache wie folgt aus:

int len = receiveUntil(array,sizeof(array), "\r\n") 
if (len >= 0) 
{ 
    // checksum and parse 
} 
discardUntil ("$"); 

wo

receiveUntil des eingehenden Stroms in array liest, bis sie das Ende des NMEA Satz beendet array null findet dann und gibt die Anzahl der gelesenen Bytes oder array ist überzulaufen, In diesem Fall gibt es -1 zurück.

discardUntil wirft alles weg, bis er den NMEA Startzeichen ‚$‘

Bonuspunkte findet receiveUntil mit einer Funktion für den Ersatz, die array zurücksetzt, wenn es eine $ findet so verpassen Sie keine Nachrichten, die nicht waren schon korrupt.