.NET Serial Port Hilfe erforderlich ist, vor allem mit Daten in mehreren „Pakete“ empfangen

StackOverflow https://stackoverflow.com/questions/891475

  •  23-08-2019
  •  | 
  •  

Frage

Ich bin sehr neue Daten über eine serielle Schnittstelle durch .net zu senden und ich habe nach der Implementierung ein TCP-Gegenstücks bemerkt, dass ich es nicht bekommen so einfach mit den Serien!

So an der Spitze zu beginnen, ich bin fast da mit meiner seriellen bidirektionalen Kommunikation Implementierung ich nur auf ein paar Dinge stecke immer: -

  1. My liest über mehrere Nachrichten aufgeteilt werden oder als fragmentierte Antwort über den COM-Port empfangen und ich weiß nicht, welche Einstellungen ich könnte brauchen, oder wie ich den Code schreiben sollte anders dieses Problem zu beheben. Was könnte die Ursache sein? Ich bin die Nachricht an einem Haltepunkt auf SerialPort_DataReceived. Inspektion

Grundsätzlich sollten die Daten als gesendet werden:

01: LS|DA090521|TI111043|q
02: PS|RN102|PTC|TA1040000|P#0|DA090521|TI111429|j

, aber es wird geteilt (an zufälligen Positionen auf jeder Lese Verlangte)

01: LS|DA090521|TI111
02: 043|q
03: PS|RN102|PTC|TA1
04: 0000|P#0|DA090521|TI111429|j

- Frage 1 beantwortet wurde, dank Chris W. und andere! Ich habe jetzt die Botschaft, die ich nach und nach von Fragmenten gebaut erwarten (der Suche nach STX, {msg body}, ETX) und dann eine Aktion ausgeführt, wenn die Nachricht vollständig erstellt wurde, und bekam es mit einem Thread-sichere Warteschlange gehen, sehr glücklich .

. 2. Ich erhalte ein „|“ Symbol durch meine Lese fast jeden Zyklus, ist dies aufgrund eines Befehls ich falsch irgendwie festgelegt haben, ein Artefakt der seriellen Kommunikation, oder etwas das Gerät mir sendet? (Ich glaube nicht obwohl, wie Hyperkonnektivität dieser Charakter offenbart nicht kontinuierlich gesendet werden.)

. 3. Können Sie bestätigen, ich lese und Schreiben von Daten korrekt in den jeweiligen Methoden.

Danke Jungs für zu bei meinen anderen beiden Fragen suchen.

Relevante Code wie folgt:

...
    //                          COM3,    9600,     None,   8,        One
    SerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBits);
    if (SerialPort.IsOpen) SerialPort.Close();
    // SerialPort.RtsEnable = true; // Request-to-send
    // SerialPort.DtrEnable = true; // Data-terminal-ready
    SerialPort.ReadTimeout = 150; // tried this, but didn't help
    SerialPort.WriteTimeout = 150; // tried this, but didn't help
    SerialPort.Open();

    SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
}

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    // Process received data
    SerialPort sp = (SerialPort)sender;
    byte[] buffer = new byte[sp.BytesToRead];
    int bytesRead = sp.Read(buffer, 0, buffer.Length);

    // message has successfully been received
    message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
}

public bool SendMessage(string text)
{
    // Only send message if a client is connected
    if (SerialPort != null && SerialPort.IsOpen)
    {
        byte[] buffer = Encoding.ASCII.GetBytes(text);
        SerialPort.Write(buffer, 0, buffer.Length);
    }
}
War es hilfreich?

Lösung

  

Meine liest werden über mehrere Nachrichten aufgeteilt

Das ist normal, erwartet, unvermeidlich Verhalten. Es kann auch mit Daten-over-TCP geschehen. Um die serielle Schnittstelle ist es nur ein endloser Strom von Bytes. Es ist Ihre Anwendung in der Verantwortung, diese Bytes in Pakete zu verpacken.

Wenn der Ort der Paketgrenzen ist wichtig, und wenn man nicht sagen kann, wo die Paketgrenzen sollen von sein bei den empfangenen Daten suchen, dann müssen Sie möglicherweise das Format der Daten zu überdenken, so dass Sie em < > können sagen, wo die Paketgrenzen sind.

  

Ich erhalte ein „|“ Symbol durch meine Lese fast jeder Zyklus

Was ist der Hex-Wert dieses Zeichens? Prüfen Sie, ob die Handshake Eigenschaft auf XOnXOff oder RequestToSendXOnXOff verbessert die Situation.

Andere Tipps

Auf der unteren Ebene kann die serielle Schnittstelle entscheiden, wann die Daten empfangen Ereignis auszulösen. Es könnte sich entscheiden, das zu tun, bevor die „voll“ Paket angekommen ist. Aber es sieht aus wie Sie ein Terminator Zeichen in Ihrem erwarteten Datensatz haben. Wenn so Sie tun können, die folgenden (beachten Sie, ich habe Ihre Serialport-Zuordnung geändert Syntax um Verwirrung zu vermeiden:

        p = new SerialPort(PortName, BaudRate, Prty, DataBits, SBits);
        p.NewLine = Terminator;

wo Terminator ist eine Zeichenfolge, Ihre Abschlusszeichen (e) enthalten. Dann können Sie SerialPort.ReadLine () (und SerialPort.WriteLine (), wenn das gilt) verwenden. Dies könnte zumindest helfen Sie mit Ihrer ersten Ausgabe.

Ich habe eine Menge von Win32 serieller Schnittstelle Programmierung getan, aber nur ein wenig mit .NET, so nehmen Sie meinen Rat mit einem Körnchen Salz.

  

Meine liest aufgeteilt werden über mehrere Nachrichten oder als fragmentierte Antwort über den COM-Port empfangen, und ich weiß nicht, welche Einstellungen ich könnte brauchen, oder wie soll ich den Code schreiben anders dieses Problem zu beheben.

Wie schon andere gesagt haben, ist dies völlig normal. Je nachdem, welche Art von Geräten auf der DCE-Seite ist, müssen Sie selbst tun Umpacken. Ich bin mir nicht sicher, welche Art von Geräten sind Sie süchtig zu, so kann ich nicht wirklich sagen, viel mehr.

Wenn Sie mehr Daten zu erhalten, können Sie versuchen, die folgenden:

  • die System.Int32 ReceivedBytesThreshold Eigenschaft Einstellung
  • mit synchroner E / A und eine feste Anzahl von Bytes spezifiziert, anstatt ereignisbasierten Empfang lesen
  

Ich erhalte ein „|“ Symbol durch meine Lese fast jedem Zyklus ist   dies aufgrund eines Befehls I gesetzt haben   falsch irgendwie, ein Artefakt der Serien   Kommunikation, oder etwas das Gerät   sendet mir? (Ich glaube nicht   obwohl, wie Hyperkonnektivität   dieser Charakter offenbart wird, nicht in der   gesendet kontinuierlich.)

Wenn Sie neugierig sind, was über die Linie geht Besuche PortMon von SysInternals , eine kostenlose App, die Ihr cOM-Port schnüffeln, während Sie Daten über die Leitung sind zu übertragen. Es scheint, technisch, aber wirklich einfach am IRP_MJ_WRITE aussehen müssen und IRP_MJ_READ Befehle und auf der Linie werden Sie die Länge in Bytes und die Daten über das Netzwerk gesendet sehen. Damit sollten Sie in der Lage sein zu sagen, ob das Problem in dem .NET Serialport-Objekt ist oder wenn das Gerät tatsächlich sendet „|“ über die Linie.

  

Können Sie bestätigen, ich lese und   Schreiben von Daten korrekt in der   entsprechende Verfahren.

Es sieht die richtige für die ereignisbasierte Methode, um Daten zu empfangen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top