COM-Port zeilenweise einlesen



  • Hallo,

    kann ich Daten von einem COM-Port zeilenweise einlesen, wenn ja, wie?

    Momentan benutze ich

    ReadFile(hSerial, &empfange, sizeof(empfange), &dwBytesRead, NULL));
    

    Der Block "empfange" mit den zu übertragenden Zeichen besteht aus mehreren Zeilen.
    Die Zeilen sind leider unterschiedlich lang.
    Deshalb möchte ich zeilenweise einlesen, die Zeile auswerten und danach die nächste Zeile einlesen usw.

    Vielen Dank für Tipps oder Beispiele.

    newey



  • Die serielle Schnittstelle kennt kennt keine Zeilen, für die Einhaltung/Umsetzung eines Text Protokolls bist du verantwortlich:

    1. Daten empfangen
    2. Daten an Empfangspuffer anhängen
    3. Daten auf Zeilenende prüfen, falls unvollständig zurück zu 1.
    4. Zeile aus Empfangspuffer extrahieren
    5. Zeile behandeln
    6. Zeile aus Empfangspuffer löschen
    7. Weiter bei 3.



  • Okay, vielen Dank für die Antwort.

    Das wird dann richtig viel Arbeit.

    Um mir diesen Punkt etwas zu vereinfachen:

    Ist es möglich, den Lese-Status zu prüfen / abzurufen, wenn ja wie?

    Also ich meine, ob ich alle Daten eingelesen habe oder noch einige Zeichen gelesen werden müssen.

    Hier komme ich nicht umhin jedes Zeichen einzeln einzulesen und das Ende einer Zeile zu prüfen.

    Wie kann ich ein Zeilenende prüfen? (mit CR?)

    danke schön

    newey



  • Ich kenne mich mit der RS232 Kommunikation nicht wirklich gut aus, vielleicht findest du in der MSDN Hilfe ja etwas, das die weiterhilft.
    Das Problem wird wohl sein, dass du das Ganze asynchron handhaben musst, damit deine Anwendung bedienbar bleibt, während du an der seriellen Schnittstelle lauscht. Trivial ist das sicher nicht.



  • Ja, MSDN ist die wichtigste Quelle bei sowas.

    ReadFile hat im Zusammenhang mit seriellen Schnittstellen ein paar spezielle Eigenschaften: Mit der Funktion SetCommTimeouts legt man fest, wie lange ReadFile auf Daten von der Schnittstelle wartet.
    http://msdn.microsoft.com/de-de/library/windows/desktop/aa363437%28v=vs.85%29.aspx

    Ein übliches Vorgehen wäre z.B. einen Timer zu verwenden und darin ReadFile so aufzurufen, dass es sofort zurückkehrt. Die andere einen Thread zu verwenden, der ReadFile mit einer gewissen Wartezeit verwendet.

    In beiden Fällen schaut man dann wie viele Zeichen ReadFile gelesen hat, kopiert diese dann hinten an seinen Empfangpuffer (das kann z.B. ein std::string oder ein AnsiString sein) dran. Anschliessend sucht man vom Anfang des Puffers nach ganzen Zeilen. Hat man welche gefunden, entfernt man sie aus dem Puffer und verarbeitet sie. Die restlichen Zeichen bleiben im Puffer und werden beim nächsten Lesevorgang um den nächsten Output von ReadFile ergänzt.

    newey schrieb:

    Hier komme ich nicht umhin jedes Zeichen einzeln einzulesen und das Ende einer Zeile zu prüfen.

    Man kann mit ReadFile auch Zeichen für Zeichen aus der Schnittstelle lesen, das ist bei höheren Baudraten aber sehr ineffizient.

    newey schrieb:

    Also ich meine, ob ich alle Daten eingelesen habe oder noch einige Zeichen gelesen werden müssen.

    Das ständig abzufragen wäre auch sehr ineffizient. Es geht mit einem Seiteneffekt von dieser Funktion
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa363180%28v=vs.85%29.aspx
    nach deren Aufruf stehen in dieser Struktur auch Anzahl der Zeichen in Sende- und Empfangspuffer
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa363200%28v=vs.85%29.aspx

    newey schrieb:

    Wie kann ich ein Zeilenende prüfen? (mit CR?)

    Das must du wissen. Das hängt von dem Gerät ab, von dem du Daten empfängst.


Log in to reply