Wie ende einer seriellen Übertragung (RS232) feststellen? (Unter verwendung System.io.ports)



  • Hallo zusammen,

    Ich habe hier folgendes Programmierproblem:

    Es muss ein Datenstrom ausgewertet werden der über die Serielle Schnittstelle hereinkommt. Auf den Aufbau des Datenstroms habe ich keinen Einfluss da ich diesen direkt in einem bereits vorhandenen Multiprozessorsystem abgreife.

    Der Datenstrom kann zwischen 2 und 100 Byte lang sein. Es befinden sich interne Steuerdaten des Gerätes und ASCII Texte in dem Datenstream die ich auswerten muss. Ausserdem einige weitere Daten welche nur verworfen werden müssen. Die Nutzdaten können aber vom ersten bis zum letzten Byte gehen.
    Es findet KEINE irgendwie geartete Steuerung des Signalflusses statt. insbesondere kein Steuerzeichen für Übertragungsende.

    Für meine spätere Weiterverarbeitung ist es aber unerlässlich das mir diese Daten als zusammenhängender Stream zur Verfügung stehen, da mir die Unterscheidung was ich nun geau vor mir habe nur durch die Kombination mehrere Bytes in folge gelingt. Im Moment wird alles in ein Array eingelesen und dann durch vergleich die interessanten Sequenzen herausgelesen. Es können beliebig viele Übertragungen während der Laufzeit vorkommen die alle ausgewertet werden. Zwischen zwei Übertragungen liegen aber immer mindestens 500ms.

    Im Moment habe ich das Problem in der Q&D Version folgendermaßen gelöst:

    void _Empfangen(){
    
    	int BR,BR1,NZ1,NZ2,NO1,NSB,Laenge,a = 0;
    	HexAusgabe = "";
    	array<Byte>^ Status = {0x80,0x00};
    
    	do {                                     // Schleife um zu Prüfen ob die Übertragung beendet ist.
    		BR = sPort->BytesToRead;        // 1 Abfragen des Lesepuffers
    			double warte = 1;
    			while(warte<=1500000000) {
    			warte++;
    			}
    		BR1 = sPort->BytesToRead;        // 2 Abfrage desLesepuffers    
    	}while (!(BR==BR1)) ;    // Sind die beiden Abfragen identisch ist die Übertragung wohl beendet
    
    		array<Byte> ^bites;               
    		bites = gcnew array<Byte>(BR);   // 
    		sPort->Read(bites,0,BR);      // jetzt wird endlich gelesen
    
    ...Weiterverarbeitung...
    

    Dies funktioniert bei mir auch relativ gut... Nur soll das Programm nicht nur bei mir auf meinem Proggi-Laptop laufen.
    Die Crux liegt aber an der Zeitschleife. Ist der Wert zu groß, dann ist die Verzögerung ebendfalls zu hoch und wirkt damit unakzeptabel. Bei zu kleinem Wert wird evtl. der Lesepuffer ausgelesen ohne das die Übertragung abgeschlossen ist. Damit steht mir nicht der ganze Stream zur Verfügung und es kommt zu Datenverlust. Leider ist die mit dem Fixwert erreichte Verzögerung stark von der zur verfügung stehenden Rechenleistung abhängig und damit sowohl vom CPU des Rechners (Dies könnte man ja noch durch eine Einstellbare Verzögerung lösen) wie auch der Systemauslastung die ja variabel ist.

    Daher meine Frage:
    Wie würde man dieses Problem der Erkennung des Übertragungsendes geschickter lösen?
    Oder wenn es keine geschicktere Lösung für als eine Verzögerung gibt, wie bekomme ich Systemunabhängig eine Verzögerung von ca.4-8 ms hin?

    Falls jemand einen völlig anderen Lösungsansatz für dieses Problem hat, währe ich natürlich auch dafür offen. (z.b. im Rahmen der Weiterverarbeitung.)

    Gruß
    Carsten



  • Das "Warte" würde ich halt durch Thread::Sleep ersetzen...
    Aber 4-8 ms wirst Du unter NT nie zuverlässig hinbekommen!

    Ich würde eher die 500 ms "Abstand" als Ende-Markierung verwenden!


Anmelden zum Antworten