Serial Port BytesToRead und readbuffer
Ich versuche Daten von einem seriellen port ständig in eine sehr schnelle Geschwindigkeit. Die Baudrate ist 230400
.
Wenn ich drucken Sie die Daten, Zeitstempel und auch BytesToRead
in einer Datei, bemerkte ich ein 200ms Verzögerung passiert immer dann, wenn BytesToRead
Tropfen auf eine einzige Stelle und readLine()
ist nicht das Lesen etwas in dieser 200ms. Nach der Verzögerung BytesToRead
geht zurück bis etwa 3000, und dieser Prozess geschieht immer wieder. Im wesentlichen bin ich nicht immer kontinuierlich die Daten.
Dachte ich, vielleicht lese ich schneller als die Geschwindigkeit der Daten die sich im buffer-also habe ich versucht, die änderung readBuffer Größe und dieser thread 1ms, damit Puffer halten die Geschwindigkeit, die ich bin, zu Lesen. Keiner von Ihnen arbeitete. Es gibt noch einige Verzögerungen.
Jede Meinung ist willkommen.
private void dostuff()//The thread I created after the port is opened
{
var startTime = DateTime.Now;
var stopwatch = Stopwatch.StartNew();
while (serialPortEncoder.IsOpen)
{
if (serialPortEncoder.BytesToRead > 210)
{
try
{
var line = serialPortEncoder.ReadLine();
var timestamp = (startTime + stopwatch.Elapsed);
var lineString = string.Format("{0} ----{1}",
line,
timestamp.ToString("HH:mm:ss:fff") + " "+serialPortEncoder.BytesToRead+"\r\n");
richTextBoxEncoderData.BeginInvoke(new MethodInvoker(delegate()
{
richTextBoxEncoderData.Text = line;//update UI
}));
}
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}}
- Ist die Verzögerung bei der Synchronisierung mit der Garbage Collection?
- Haben Sie versucht, Sie vorübergehend deaktivieren Sie das richtextbox-Steuerelement aufrufen?
- Dies ist eine Fortsetzung von stackoverflow.com/questions/14309249/.... Das ist ok, aber was hast du versucht um das problem genauer diagnostizieren? Bist du sicher, dass das board nicht verursacht die Verzögerungen?
- meinst du den encoder selbst?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sei denn, es gibt einen Zeilenvorschub jeden 210 bytes, Ihre ReadLine () - Funktion ist wahrscheinlich das timing und der Rückkehr nichts. ReadLine() liest den Eingabepuffer, bis auf ein newline-Wert, dann Rückkehr was auch immer die Daten vorher war es. http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readline.aspx
Welche Art von Informationen kommen über den port? Wenn Sie Lesen wollen, eine bestimmte Größe Puffer, verwenden Sie einfach die
Read
Methode. Wenn Sie Lesen müssen, bis es einen Zeilenvorschub, die Verwendung mit ReadLine (), und überprüfen Sie alle so oft zu sehen, wenn Sie eine Zeichenfolge zurückgibt.Read()
, nichtReadLine()
Dein code ist ziemlich grundlegend falsch, es leidet unter der "hot-wait-loop" - bug. Ihre Schleife ist das brennen 100% - core, wenn die serielle Schnittstelle nicht genügend Daten. Das wird Windows setzen Sie Ihren thread in ein Haus Hund für eine Weile nach Ihr brannte das quantum, was die anderen threads eine chance zu laufen. In dieser Hundehütte für 200 msec ist ein bisschen lang, aber sicherlich nicht ungewöhnlich.
Sollten Sie tun anders, Sie sollten geben Sie Windows eine chance zum aufwachen, wenn es tatsächlich um Daten aus dem seriellen port. Es begünstigt threads, hatte eine I/O abgeschlossen, wenn es sieht für den nächsten thread zu planen. Das ist sehr einfach zu tun, entfernen Sie einfach die BytesToRead test. Die ReadLine () - Aufruf ist ein blockierender Aufruf, der nicht zurückkehren, bis ein Zeilenumbruch empfangen wird. Dein thread wird jetzt verbrauchen die Nähe der 0% cpu-Zyklen.
Werden Sie immer noch verlieren, beliebige Mengen an Zeit, wenn die Maschine schwer beladen wird oder der garbage collector ausgeführt wird. Und Nein, das ist nicht gut genug, um zuverlässig zu Lesen, einen encoder und schließen Sie eine feedback-Schleife. Tut zuverlässig, benötigt einen mikrocontroller mit vorhersagbarem echtzeitverhalten. Leicht zugänglich von Industrie-Elektronik-Lieferanten.
Nachdem einige endlose recherche im Internet fand ich die Ursache der Verzögerung. Geräte-Manager--->Port---->advance----> ändern Sie die Latenz auf 1ms wird das problem lösen. Nun, jedes mal, wenn der buffer sinkt auf null, es muss nur 2ms max um wieder normal zu bekommen. Ich bin jetzt polling-Daten über einen separaten thread. Es funktioniert sehr gut.
Aber wie Hans Passant sagte, ich bin versucht, herauszufinden, einen besseren Weg zu gestalten.