C# Serialport liefert vorherige Daten.

-Rayz-

Lieutenant
Registriert
Okt. 2010
Beiträge
897
Hallo,

ich habe das Problem, dass ab und an mein Serialport die Daten vom vorherigen Objekt ausgibt und nicht die aktuellen. Als ich das Lesen der bytes asynchron gemacht hatte, war es sogar alle 2-3mal passiert. Sonst passiert es ca nach dem 10ten Scan, dass die Daten vom vorherigen Opjekt und nicht vom aktuellen Objekt gelesen werden.

Normal macht man es denke ich so:

Code:
 if (sp.Bytes > 0)
                {
                    buffer = new byte[sp.Bytes ];
                    sp.Read(buffer, 0, sp.Bytes );

oder als While-Schleife.. wie auch immer.
Nun habe ich folgendes getestet:
Code:
public static void spScanner_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = sender as SerialPort;
            System.Threading.Thread.Sleep(1000);
            int bAvailable = sp.Bytes ;            
            sData.buffer = new byte[bAvailable ];
            sData.buffer2 = new char[bAvailable ];
            try
            {
                sp.Read(sData.buffer2, 0, bytesAvailable);         

                if (sp.Bytes == 0)
                {
                    sp.DiscardInBuffer();
                }
            }
}

        private struct serialData
        {
            public byte[] buffer;
            public char[] cbuffer;   
        }

        private static serialData sData = new serialData();

Aber auch mit diversen Thread.Sleep und Discards konnte ich das Problem bisher nicht lösen. Dabei ist es auch egal, ob ich die Daten als string oder byte auslese.

Woran kann das liegen, dass ich Daten vom vorherigen Scan bekomme?
Mir fallen langsam keine Möglichkeiten mehr ein die ich testen könnte...


MfG
 
Zuletzt bearbeitet:
Hast du schonmal mit einem anderen Programm getestet ob die Daten die vom "Scanner" (ich vermute Barcodescanner?!?) geschickt werden auch korrekt sind?

Ich teste das immer mit dem HyperTerminal wenns Probleme gibt.
 
Ja habe ich getestet und zwar mit dem Programm HTerm. Da gibt es keine solche Fehler.
BytesToRead gibt an, wieviel bytes gelesen werden. Daraus mache ich mir ja dann meinen buffer:

//buffer = new byte[sp.BytesToRead];
//sp.Read(buffer, 0, sp.BytesToRead);

anschließend stehen die Daten dann im buffer drin.
Ob ich mit einer While schleife auf sp.Readexisting > 0 überprüfe ändert übrigens auch nichts daran, dass ich ab und an falsche/vorherige Werte bekomme.
 
diese ganzen Read Funktionen habe ich bereits durchgetestet. Ob byte char oder string ist dabei vollkommen egal. Das Ergebnis bleibt unbefriedigend :(
Ergänzung ()

Keiner noch eine Idee was ich noch testen könnte?
 
Hattest du mal geguckt, ob in dem Try Block Exceptions geworfen werden? Das ist das einzige, was mir noch in den Sinn käme.
 
Mir fiele da nur noch ein Fehler in der Portkonfiguration ein. Dass da etwas nicht zusammenpasst.
Aber ohne genaueren Quellcode ist sowas schwer zu sagen.

Ich würde vorschlagen den Scanner (ich vermute immer noch Barcodescanner?!?) durch ein schnell geschriebenes Sendeprogramm zu ersetzen und das Empfangsprogramm über diese kontrollierte Datenquelle zu füttern und so zu schauen ob der Empfänger richtig arbeitet.

Das müsste ich auch mal machen und habe so einen Wackelkontakt des seriellen Kabels als Ursache für Datensalat ausfindig gemacht.
 
In deinem Code steht nirgends wo du die Daten auch verwendest, also feststellst, dass die doppelt reinkommen. Ich nehme mal an, du greift in einem separaten Thread auf sData zu, ohne was zu synchronisieren.
 
JA stimmt schon, ihr hättet mehr Informationen über den Ablauf bekommen müssen. Das Problem war auch etwas ganz anderes und zwar ist das Prozedere folgendermaßen:
Ich lege Daten auf den Scanner, Schicke dem Scanner zwei Befehle zu damit er seinen Modus wechselt und hier liegt auch schon der Fehler, die Anzahl der Befehle wurde so schnell übermittelt so dass gar nicht alles ankam bzw. fehlerhaft war. Ist ein Kommando falsch, bekomme ich 05 als Rückgabewert. Sonst wenn alles richtig ist 06.

Code:
if (Port.IsOpen == true)
                            {
                                abc.b_ready = true;
                                
                                while (b_check_command != true && counter <10)
                                {
                                    Port.Write(send1, 0, send1.Length);
                                    Thread.Sleep(50);
                                    c++;
                                }
                                c= 0;
                                abc.b_ready = false;
                                bcommand = false;

                                Port.Write(sendnew, 0, sendnew.Length);

Hier die Methode welche getriggert wird, wenn der Scanner Daten schickt:
Code:
public static void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            
            SerialPort sp = (SerialPort)sender;
            char[] Trim = { '\r', '\n' };
          
            try{      
                
                if (sp.Bytes > 0)
                {
                    buffer = new byte[sp.Bytes];
                    sp.Read(buffer, 0, sp.Bytes);

                    if (b_ready == true)
                    {
                        string strhex = BitConverter.ToString(buffer);
                        if (strhex.Contains("05"))
                        {
                            cdf.bcommand = false;
                        }
                        else
                        {
                            cdf.bcommand = true;
                        }
                    }

Die Lösung gefällt mir noch nicht so ganz... sieht so "dirty" aus -_-. Vor allem mag ich diese Thread.Sleeps nicht aber ansonsten läuft es halt zu schnell durch. Sollte das zu sendene Kommando dauerhaft fehlerhaft sein, habe ich einen Counter welchen ich hochzähle und spätestens bei 10 Versuchen den Vorgang abbreche.
Evtl. fällt mir ja noch etwas anderes ein wie ich das schöner lösen kann.

MfG
 
Zuletzt bearbeitet:
Zurück
Oben