Ich habe zwei Geräte, die ich über eine serielle Schnittstelle verbinden möchte, aber sie haben inkompatible Verbindungen. Um dieses Problem zu umgehen, habe ich beide mit meinem PC verbunden und arbeite an einem C# -Programm, das den Verkehr von COM-Port X zu COM-Port Y und umgekehrt leitet.C# SerialPort - Probleme beim Mischen von Ports mit unterschiedlichen Baudraten
Das Programm verbindet sich mit zwei COM-Ports. Im Datenempfangs-Handler lese ich eingehende Daten ein und schreibe sie an den anderen COM-Port. Um dies zu tun, ich habe den folgenden Code:
private void HandleDataReceived(SerialPort inPort, SerialPort outPort)
{
byte[] data = new byte[1];
while (inPort.BytesToRead > 0)
{
// Read the data
data[0] = (byte)inPort.ReadByte();
// Write the data
if (outPort.IsOpen)
{
outPort.Write(data, 0, 1);
}
}
}
Dieser Code funktioniert gut, solange der scheidende COM-Port mit einer höheren Baudrate als die eingehenden COM-Port betrieben. Wenn der eingehende COM-Port schneller als der ausgehende COM-Port war, begann ich Daten zu verpassen. Ich musste den Code wie folgt korrigieren:
private void HandleDataReceived(SerialPort inPort, SerialPort outPort)
{
byte[] data = new byte[1];
while (inPort.BytesToRead > 0)
{
// Read the data
data[0] = (byte)inPort.ReadByte();
// Write the data
if (outPort.IsOpen)
{
outPort.Write(data, 0, 1);
while (outPort.BytesToWrite > 0); //<-- Change to fix problem
}
}
}
Ich verstehe nicht, warum ich diesen Fix brauche. Ich bin neu in C# (das ist mein erstes Programm), also frage ich mich, ob ich etwas vermisse. Der SerialPort verwendet standardmäßig einen Schreibpuffer von 2048 Byte, und meine Befehle sind kleiner als zehn Byte. Der Schreibpuffer sollte die Möglichkeit haben, die Daten zu puffern, bis sie in einen langsameren COM-Port geschrieben werden können.
Zusammenfassend erhalte ich Daten über COM X und schreibe die Daten an COM Y. COM X ist mit einer höheren Baudrate als COM Y verbunden. Warum behandelt die Pufferung im Schreibpuffer diesen Unterschied nicht? Warum scheint es, dass ich auf den Schreibpuffer warten muss, um Datenverlust zu vermeiden?
Danke!
* Update *
Wie bereits erwähnt, kann dieser Code sehr leicht in einen Überlaufzustand läuft mit großen und/oder schnell eingehenden Datenübertragungen. Ich hätte mehr über meinen Datenstrom schreiben sollen. Ich erwarte < 10-Byte-Befehle (mit < 10-Byte-Antworten) bei 10 Hz. Außerdem sehe ich Fehler beim ersten Befehl.
Also während ich weiß, dass dieser Code nicht skaliert und weniger als optimal ist, frage ich mich, warum die 2-4K Lese-/Schreibpuffer nicht einmal den ersten Befehl verarbeiten konnten. Ich frage mich, ob es einen Fehler beim Schreiben eines einzelnen Bytes von Daten oder etwas mit dem Ereignishandler gibt, die ich nicht verstehe. Vielen Dank.
* Update *
Hier ist ein Beispiel für das Scheitern:
Sagen wir, mein Befehl vier Bytes ist: 0x01 0x02 0x3 0x4. Das Gerät auf COM X sendet den Befehl. Ich kann sehen, dass das C# -Programm vier Bytes empfängt und sie an das Gerät an COM Y sendet. Das Gerät an COM Y empfängt zwei Bytes: 0x01 0x03. Ich weiß, dass das Gerät auf COM Y zuverlässig ist, also frage ich mich, wie die zwei Bytes fallen gelassen wurden.
Übrigens, kann mich jemand wissen lassen, ob es besser ist, Antworten mit Kommentaren zu beantworten oder ob ich die ursprüngliche Frage weiter bearbeiten soll? Was ist hilfreicher?
Ja, Sie haben Recht, dass dieser Code ist wie aus einem Feuerwehrschlauch trinken. Leider hätte ich mehr über den mit diesem Code verbundenen Schlauch schreiben sollen. Ich sende <10 Byte Befehle (mit <10 Byte Antworten) bei 10 Hz. Ich würde 2-4K lesen/schreiben Puffer für mich mehr als ausreichend erwarten. Außerdem sehe ich Fehler beim ersten Befehl. Obwohl ich weiß, dass dieser Code nicht auf größere/schnellere Datenübertragungen skaliert, bin ich neugierig, warum es nicht mit kleinen/langsamen Übertragungen funktioniert hat. Tut mir leid, dass ich nicht klarer bin. – GrandAdmiral
Okay, sollte funktionieren. Bitte sei explizit "Ich sehe Fehler". –
Sicher. Nehmen wir an, mein Befehl besteht aus vier Bytes: 0x01 0x02 0x3 0x4. Das Gerät auf COM X sendet den Befehl. Ich kann sehen, dass das C# -Programm vier Bytes empfängt und sie an das Gerät an COM Y sendet. Das Gerät an COM Y empfängt zwei Bytes: 0x01 0x03. Ich weiß, dass das Gerät auf COM Y zuverlässig ist, also frage ich mich, wie die zwei Bytes fallen gelassen wurden. – GrandAdmiral