mikrocontroller.net

Forum: PC-Programmierung Serielle Schnittstelle C#


Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich hätte eine Frage zum Auslesen der Seriellen Schnittstelle mit 
C#. Es funktioniert alles wunderbar und alle Werte werden in einer 
Textbox ausgegeben. Nur habe ich ein Problem:
Meine Werte werden alle unendlichfach ausgegeben. Ich möchte allerdings, 
dass mir der Wert nur ein einziges Mal an die Textbox übergeben wird.

Mit diesem Befehl fügt er mir den Wert immer und immer wieder hinzu:

this.Invoke(new EventHandler(DisplayText));

In DisplayText steht "textBox1.AppendText(dataEmpf);" drinnen. 
Allerdings möchte ich, dass er mir alles nur einmal an die Textbox 
übergibt. Könnte mir jemand einen Tipp geben wie das funktionieren 
könnte?

Vielen Dank im Vorraus

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ICh versteh dein Prob irgendwie nicht richtig.
Wenn du den Wert immer aktualisieren willst, dann überschreib die 
Textbox doch einfach immer.

Poste vielleicht mal ein bisschen code.

Autor: Juppi J. (juppiii)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Suchender schrieb:
> "textBox1.AppendText(dataEmpf)

Hier hängst du doch standig neue Zeichen an.

Vielleicht so     textBox1.Text=dataEmpf
Kenne dein Cod aber nicht?

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also hier hab ich mal den Teil des betroffenen Codes:

 private void DisplayText(object sender, EventArgs e)
        {
            textBox1.AppendText(dataEmpf);
        }

        private void serialPort1_DataReceived(object sender, 
System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            dataEmpf = serialPort1.ReadExisting();
            this.Invoke(new EventHandler(DisplayText));
        }

Mit dem Code hängt er mir die Daten immer wieder hinten dran. Ich möchte 
allerdings, dass er mir die Daten nur ein einziges mal in die Textbox 
schreibt. d.h.: wenn ein neuer Wert kommt, dann soll er den alten in der 
Textbox überschreiben und dann soll (wenn die Daten zb "Hallo" wären) 
nur einmal in die Textbox "Hallo" schreiben.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kein Wunder:

>  textBox1.AppendText(dataEmpf);

Was wohl bedeutet Append?

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es heißt hinzufügen. doch ich weiß den befehl nicht, damit er es nur 
einmal hinausschreibt. Wenn mir da bitte jemand helfen könnte

Autor: fz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo suchender,

wenn du den Text ersetzen willst verwende einfach die Eigenschaft .Text

fz

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab ich schon probiert. funktioniert leider nicht

Autor: Christian R. (mrrotzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
private void DisplayText(object sender, EventArgs e)
{
    textBox1.Text = dataEmpf;
}

wobei das kein schöner Code ist ... so ... nein nein ...

was machst du da überhaupt?
Welche Applikation? WinForms? WPF?

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich mache eine WinForm und will die serielle schnittstelle auslesen.
Wenn ich es mit .text schreibe hört er zwar gleich auf, aber schreibt 
mir die daten trotzdem 4mal hinaus. Ich möchte es aber nur einmal haben

Autor: Christian R. (mrrotzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht bekommst du 4x das serialPort1_DataReceived event?

setz mal einen Breakpoint und schau was da passiert!

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian R. schrieb:
> setz mal einen Breakpoint und schau was da passiert!

Einen Breakpoint in Echtzeit... lol

Wenn du textbox1.Text = xyz; machst wird immer xyz drinstehen, aber nie 
4*xyz. Die einzigste möglichkeit wäre das xyz 4*die gewollten Daten 
enthält. Dann musst du sie splitten: textBox1.Text = 
xyz.Split('|')[xyz.Split('|').Lenght - 1];

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, das serialPort1_DataReceived Signal kommt nur ein einziges mal. 
Allerdings bin ich mal in Einzelschritten alles durchgegangen und hab 
gemerkt, dass mein Signal dataEmpf schon von vornherein um die 4mal das 
Signal liefert. Kann es sein, dass mein µC (von dem das Signal kommt) zu 
schnell für mein Programm ist?

Autor: fz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja das ist möglich, du kannst ja in größeren zeitabständen senden vom µc

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Suchender schrieb:
> this.Invoke(new EventHandler(DisplayText));

sieht mir ein wenig merkwürdig aus, es könnte sein das du jedes mal 
einen neuen Eventhandl anlegst und damit die vervielfachung bekommst,

Autor: Christian R. (mrrotzi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Suchender: Dein Problem ist "Invoke"
Wenn du Invoke verwendest, wird zwar in den MainThread synchronisiert - 
dein Thread in dem der Eventhandler aufgerufen steht aber so lange, bis 
Invoke wieder zurück ist. Invoke entspricht einem "SEND".
Was du machen musst ist ein POST oder ein BeginInvoke. Das ist die 
Asynchrone Variante. Du darfst auch auf keinen Fall eine Membervariable 
(dataEmpf) für den Transport verwenden. Weil die dann jedes Mal 
überschrieben werden "könnte" !!

Multithreading ist so eine Sache ...

Ich hab mal auf die Schnelle eine kleine TestApp gebastelt.
Eine Form mit einem serialPort1 und einer RichTextbox.
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();

      // serial port öffnen
      this.serialPort1.Open();
    }

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
      // Daten auslesen und zwischen speichern...
      var data = this.serialPort1.ReadExisting();

      // trace vorbereiten und ausgeben...
      var dt = DateTime.Now;
      System.Diagnostics.Debug.WriteLine(string.Format("DataReceived: {0}:{1} EventType:{3} Data:'{2}'", dt.ToLongTimeString(), dt.Millisecond, data, e.EventType));

      // POST an den MainThread um die RichText Box zu befüllen!
      // POST (BeginInvoke) und nicht SEND (Invoke) um den SerialPort nicht unnötig aufzuhalten!!)      
      this.BeginInvoke((Action)delegate() {
        this.richTextBox1.Text += data; });
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
      // serial port zu machen
      this.serialPort1.Close();
    }
  }

Hoffe das hilft dir weiter!

Grüße aus Wien
Christian

Autor: Suchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, jetzt funktioniert alles. Das Problem war wirklich das "invoke".
Danke für eure Hilfe :)

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.