2010-12-27 9 views
1

Ich habe mit diesem Problem für einen Tag gekämpft und ich kann keine Antwort dafür finden. Ich versuche, Daten von GPS-Gerät über COM-Port in Compact Framework C# zu lesen. Ich benutze die SerialPort-Klasse (eigentlich meine eigene ComPort-Klasse, die SerialPort einpackt, aber es fügt nur zwei Felder hinzu, die ich brauche, nichts besonderes).SerialPort ReadLine() nach Thread.Sleep() geht verrückt

Wie auch immer, ich bin während while-Schleife in einem separaten Thread, der Zeile aus dem Port liest, analysieren NMEA-Daten, drucken sie, fangen alle Ausnahmen und dann ich Sleep (200) den Thread, weil ich CPU für andere Threads benötigen. .. Ohne Schlaf funktioniert es gut, aber 100% CPU verwendet. Wenn ich nach einigen Minuten nicht den Schlaf verwenden, sieht die Ausgabe von COM-Port so aus:

GPGSA, A, 3,09,12, 22,17,15,27 ,,,,,,, 2,6,1,6,2,1 * 3F
GSA, A, 3,09,12,22,17,15,27 ,,,,,,, 2,6,1,6 , 2,1 * 3F
A, A, 3,09,12,22,17,15,27 ,,,,,,, 2,6,1,6,2,1 * 3F
, 18,12,271,24,24,05,020, 24,14,04 326,25,11,03,023, * 76
A, 3,09,12,22,17,15,27 ,,,,,,, 2,6,1,6,2,1 * 3F
3,09,12, 22,17,15,27 ,,,,,,, 2,6,1,6,2,1 * 3F
09,12,22,17,15,27 ,,,,,,,, 2,6,1,6,2,1 * 3F
, 12,22,17,15,27 ,,,,,,, 2.6,1.6,2.1 * 3F

, wie Sie die gleiche Nachricht mehrmals gelesen wird sehen können, aber schneiden. Ich frage mich, was ich falsch mache ... Meine Port-Konfiguration:

port.ReadBufferSize = 4096; 
port.BaudRate = 4800; 
port.DataBits = 8; 
port.Parity = Parity.None; 
port.StopBits = StopBits.One; 
port.NewLine = "\r\n"; 
port.ReadTimeout = 1000; 
port.ReceivedBytesThreshold = 100000; 

Und meine Lesefunktion:

private void processGps(){ 
    while (!closing) 
    { 
     //reconnect if needed 
     try 
     { 
      string sentence = port.ReadLine(); 
      //here print the sentence 
      //analyze the sentence (this takes some time 50-100ms) 
     } 
     catch (TimeoutException) 
     { 
      Thread.Sleep(0); 
     } 
     catch (IOException ioex) 
     { 
      //handling IO exception (some info on the screen) 
     } 
    Thread.Sleep(200); 
    } 
} 

Es gibt einige weitere Sachen in dieser Funktion wie Wiederverbindung ist, wenn das Gerät verloren usw., aber es wird nicht aufgerufen, wenn das GPS richtig angeschlossen ist. Ich habe versucht,

port.DiscardInBuffer(); 

nach einigen Codeblöcken (in Timeout, nach dem Lesen.)

Hat jemand ähnliches Problem gehabt? Ich weiß wirklich nicht, was ich falsch mache. Der einzige Weg, es in Ordnung zu bringen, ist das Entfernen des letzten Schlafes.

+0

Haben Sie asynchrone Vorgänge in Erwägung gezogen, anstatt zu schlafen? – ongle

Antwort

1

Für alle, die ähnliche Probleme haben. Beim ersten Problem ging es um das Überlaufen des Puffers. Ich hatte 4096 Puffergröße und die Daten liefen einfach durch, so dass ich beschädigte Sätze las. Jetzt lese ich alle Puffer auf einmal und analysiere sie. Der erste Satz ist manchmal beschädigt, aber der Rest ist in Ordnung.
Die zweite Sache war das Geräteproblem. Tom Tom MkII verliert manchmal die Verbindung mit dem Gerät. Ich musste das GPS neu starten und es wieder in der BT-Geräteliste finden. Grüße

0

Es gibt nichts in Ihrer Post zu sagen, wie Sie Händeschütteln tun.

Normalerweise würden Sie Software- (XON/XOFF) oder Hardware- (z. B. RTS/CTS) Handshake verwenden, so dass der serielle Port das Senden anweist, zu stoppen, wenn keine weiteren Daten empfangen werden können. Die Handshake-Konfiguration muss (natürlich) mit der Konfiguration des sendenden Geräts übereinstimmen.

Wenn Sie das Handshaking nicht richtig konfigurieren, können Sie es schaffen, solange Sie die Daten schnell genug verarbeiten - aber wenn Sie einen Sleep haben, können Daten verloren gehen.