mikrocontroller.net

Forum: PC-Programmierung Problem mit SerialPort Read Event C#


Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Freunde,
habe schon wieder ein Problem wo ich keinen Rat weiß!
Ich habefolgenden Code in in meinem Read Event stehen!

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            byte[] array = new byte[100];
            serialPort1.Read(array, 0, 100);
            PrintStart(array);
        }



Aber ob ich nun 10 Byte  oder 30 Byte an mein Program sende (Serielle)
ich empfange laut Debugger immer zuerst 7 Und danach gleich nochmal den 
rest der gesendeten Byts !!
Was mach ich Falsch ????

Danke für Eure Hilfe


Peter

Autor: Oliver R. (superberti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du machst nix falsch. Die Stückelung, in der die Events ausgelöst 
werden, hängt von der Hardware, den Treibern, vom .NET-Framework und der 
Größe der ganzen Puffer dazwischen ab. Also nicht vorhersehbar.
Wichtig ist nur, dass alle Daten ankommen, zusammensetzen musst Du sie 
selbst.

Gruß,

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver R. schrieb:
> Du machst nix falsch. Die Stückelung, in der die Events ausgelöst
> werden, hängt von der Hardware, den Treibern, vom .NET-Framework und der
> Größe der ganzen Puffer dazwischen ab. Also nicht vorhersehbar.

Fast, man kann einstellen (ReceivedBytesThreshold) wie viele Bytes 
mindestens angekommen sein müssen, bevor DataReceived ausgelöst wird.

> Wichtig ist nur, dass alle Daten ankommen, zusammensetzen musst Du sie
> selbst.
>
> Gruß,

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für Eure Antworten auch wenn ich zugeben muß mir wäre lieber 
gewesen ich hätte einen Fehler gemacht !!!

Dann werd ich mir gedanken machen wie ich mein Problem löse!!

Danke Gruß

Peter

Autor: Hannes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi, geht mir genauso. mir wäre es am liebsten, wenn nach jedem 
empfangenen byte eine art interrupt ausgelöst werden würde. wer mal die 
serielle schnittstelle in visual basic 6.0 angesprochen hat, und dann 
auf .net umgestiegen ist wird mich verstehen. in vb 6.0 war es 
wesentlich einfacher die daten zu empfangen. ich bleibe weiterhin daran, 
mich mit mittlerweile .net 3.5 anzufreunden und die schnittstelle 
vernüftig zum laufen zu bekommen. gerade wenn man mit dem compact 
framework zu tun hat. im normalen .net framework kann man ja immer noch 
das gute alte ocx steuerelement von vb einbinden und damit arbeiten.

mfg hannes

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich glaub ich habe eine lösung bin grad beim testen!!

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So scheint zu funktioniren

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            byte[] array = new byte[100];
            int i=0;
            do
            {
                array[i] = (byte)serialPort1.ReadByte();
                i++;
            }
            while ((i != 80)&&(tick!=100));
            PrintStart(array);
        }


Wenn jemand eine bessere lösung hat ich bin immer Neugirig !!

Gruß
Peter

Autor: Oliver R. (superberti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ihr müßt mal grundsätzlich unterscheiden zwischen eventgesteuertem 
Empfang der seriellen Daten und (blockierendem) Lesen mit Timeout.
Oftmals ist das Lesen mit Timeout die einfachere und auch zweckmäßigere 
Variante, aber genau das wird mit der SerialPort-Klasse gerade NICHT 
unterstützt (zumindest bis .NET2.0).
Das Windows-API kann das natürlich alles und ich habe mir seinerzeit 
tatsächlich eine Klasse extra dafür geschrieben. Macht aber nicht 
wirklich Spaß den ganzen Win32-API-Kram zu kapseln, man bekommt 
ziemliche Probleme mit der Abbildung der alten API-Structs (z.B. der DCB 
als gepackte Struktur) in .NET.
Alternativ kann man natürlich eine State-Machine entwerfen, die in dem 
Empfangsevent die Daten zwischenspeichert und erst ab einer bestimmten 
Gesamtmenge irgendetwas auslöst. Scheint mir hier einfacher und 
zweckmäßiger.

Gruß,

Autor: Pier S. (bigpier)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver R.
Was sagst du zum obigen Code ???

Gruß
Peter

Autor: Oliver R. (superberti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

obigen Code halte ich für sehr problematisch, da der Event (wie Du ja 
schon festgestellt hast) mehr als einmal pro Sendung aufgerufen wird. Du 
liest aber jedesmal SYNCHRON eine bestimmte Anzahl an Bytes, spätestens 
beim zweiten Event gibt's nix mehr zu Lesen.
Die Alternative habe ich ja schon geschrieben: In den Events so lange 
die Daten sammeln, bis Du alle Deine Bytes zusammen hast. Z.B.

Member-Vars:
private byte[] array=new byte[1024];
private int TotalRead=0;

private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
{
  TotalRead+=serialPort1.Read(array, TotalRead, 100);
  if (TotalRead>=AnzahlMeinerBytesDieIchLesenWill)
  {
    PrintStart(array);
    // Falls Rest vorhanden an den Anfang von Array kopieren
    // TotalRead=Restgröße
  }
}

ODER Du verwendest gar keine Events und liest einfach Byte für Byte mit 
SerialPort.ReadByte() und setzt das ReadTimeout entsprechend. Nicht sehr 
effizient aber eventuell für Deine Zwecke vollkommen ausreichend.

Gruß,

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.