Laden...

Discardbuffer? RS232....kenn micht nicht mehr aus

Erstellt von bruzzler vor 17 Jahren Letzter Beitrag vor 17 Jahren 1.549 Views
B
bruzzler Themenstarter:in
31 Beiträge seit 2006
vor 17 Jahren
Discardbuffer? RS232....kenn micht nicht mehr aus

hallo!!

ich bekomme im (ca.) sekundentakt daten (in 4 Byte paketen) von meinem µC auf meine Serielle Schnittstelle geschickt. Folgendes Problem - eigentlich sollte ja, wenn ich ein READ() mache, die Daten aus dem Eingangsbuffer der Seriellen Schnittstelle gelöscht werden?! genau das passiert nicht!!! ich bekomme immer die selben (aber richtien) Daten(4Byte), obwohl der µC was anderes schickt!

Funktioniern tut es (zum teil) wenn ich ein DiscardBuffer aufrufe, nachdem ich die 4 Byte Daten (die ich brauche) ausgelesen habe - ABER dann kann es passieren (und passiert auch) das ich mit einigen Datenpacketen durcheinander komme, oder mir Datenpackete einfach verlorgen gehen!

habt ihr einen idee zu der lösung??

code:


 if (serialBTPort.BytesToRead > 0)
                {
                    try
                    {
                        //Auslesen der ersten Bytes:
                        serialBTPort.Read(Buffer, 0, 1);
                        i = Convert.ToInt32(Buffer[0]);

                         while ((i & 192) != 0)
                        {
                           //solange auslesen, bis das erste byte  wirklich das erste byte eines 4byte paketes ist
                            serialBTPort.Read(Buffer, 0, 1);
                            i = Convert.ToInt32(Buffer[0]);
                            
                        }
                         //die drei restlichen(direct auf das erste folgenden) bytes auslesen
                        buffer[0] = i;
                        serialBTPort.Read(Buffer, 0, 1);
                        i = Convert.ToInt32(Buffer[0]);
                        buffer[1] = i;
                        serialBTPort.Read(Buffer, 0, 1);
                        i = Convert.ToInt32(Buffer[0]);
                        buffer[2] = i;
                        serialBTPort.Read(Buffer, 0, 1);
                        i = Convert.ToInt32(Buffer[0]);
                        buffer[3] = i;

                        Decode4Byte(buffer[0], buffer[1], buffer[2], buffer[3], ref Kanal, ref Wert);
//hier sollte sich beispielsweise der Wert ändern den der µC schickt (zb.: ein zähler der raufzählt....) passiert aber nicht!! :(

                      //serialBTPort.DiscardInBuffer(); --> sollte man eigentlich nicht brauchen!
                     }
                    catch (Exception BTE)
                    {
                        txtMessage.Text = BTE.Message;
                    }
                }        

B
1.529 Beiträge seit 2006
vor 17 Jahren

Vielleicht funktioniert es besser, wenn du SerialPort.BaseStream.ReadByte() verwendest?

B
bruzzler Themenstarter:in
31 Beiträge seit 2006
vor 17 Jahren

nö hat nix gebracht 🙁 sonst noch jemand ideen? bin schon ziemlich verzweifelt.... brauchst nämlich drignend...

U
1 Beiträge seit 2005
vor 17 Jahren

Hallo bruzzler,

mit Readbyte sollte es auf funktionieren, dein Problem ist nach meiner Meinung,
das wenn noch nicht alle 4 Byte im Empfangspuffer angekommen sind, deine Routine
if (serialBTPort.BytesToRead > 0)
das erste Byte ausliest und nach int convertiert.
Sind aber die restlichen Bytes noch nicht im Buffer müßte er mit einer Exception kommen.
Versuche mal if (serialBTPort.BytesToRead ≥ 4)

B
bruzzler Themenstarter:in
31 Beiträge seit 2006
vor 17 Jahren

ich bin mri jetzt nicht sicher wie du das meinst...... wenn ich das if(....>4) einbaue dann dauert es eben am anfang länger bis der buffer gefüllt ist - danach geht es normal weiter...der buffer wird nicht wirklich gelöscht befürchte ich!!

würd mich über andere lösungen noch freuen!!! 🙂 danke!

B
1.529 Beiträge seit 2006
vor 17 Jahren
  1. Ersetze while-do durch do-while
// aus 
serialBTPort.Read(Buffer, 0, 1);
i = Convert.ToInt32(Buffer[0]);
while ((i & 192) != 0)
{
   serialBTPort.Read(Buffer, 0, 1);
   i = Convert.ToInt32(Buffer[0]);
}
// wird 
do
{
   serialBTPort.Read(Buffer, 0, 1);
   i = Buffer[0];
} while( (i & 192) != 0)
  1. Ich würde die komplette Struktur ändern. Eine eigene Klasse beinhaltet den SerialPort und lässt sich von diesem per DataReceived benachrichtigen, sobald ein Byte eingetroffen ist (ReceivedBytesThreshold).
    Ist diese ein Startbyte, wandert es in einen Puffer, der mit den folgenden drei Bytes aufgefüllt wird. Sobald der Puffer voll ist, löst die Klasse wiederum ein Event aus und gibt die Daten weiter.