Forum: PC-Programmierung Serielle Schnittstelle C#


von Suchender (Gast)


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

von Sam .. (sam1994)


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.

von Juppi J. (juppiii)


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?

von Suchender (Gast)


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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Kein Wunder:

>  textBox1.AppendText(dataEmpf);

Was wohl bedeutet Append?

von Suchender (Gast)


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

von fz (Gast)


Lesenswert?

Hallo suchender,

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

fz

von Suchender (Gast)


Lesenswert?

hab ich schon probiert. funktioniert leider nicht

von Christian R. (mrrotzi)


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?

von Suchender (Gast)


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

von Christian R. (mrrotzi)


Lesenswert?

Vielleicht bekommst du 4x das serialPort1_DataReceived event?

setz mal einen Breakpoint und schau was da passiert!

von Sam .. (sam1994)


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];

von Suchender (Gast)


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?

von fz (Gast)


Lesenswert?

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

von Peter (Gast)


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,

von Christian R. (mrrotzi)


Angehängte Dateien:

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.
1
  public partial class Form1 : Form
2
  {
3
    public Form1()
4
    {
5
      InitializeComponent();
6
7
      // serial port öffnen
8
      this.serialPort1.Open();
9
    }
10
11
    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
12
    {
13
      // Daten auslesen und zwischen speichern...
14
      var data = this.serialPort1.ReadExisting();
15
16
      // trace vorbereiten und ausgeben...
17
      var dt = DateTime.Now;
18
      System.Diagnostics.Debug.WriteLine(string.Format("DataReceived: {0}:{1} EventType:{3} Data:'{2}'", dt.ToLongTimeString(), dt.Millisecond, data, e.EventType));
19
20
      // POST an den MainThread um die RichText Box zu befüllen!
21
      // POST (BeginInvoke) und nicht SEND (Invoke) um den SerialPort nicht unnötig aufzuhalten!!)      
22
      this.BeginInvoke((Action)delegate() {
23
        this.richTextBox1.Text += data; });
24
    }
25
26
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
27
    {
28
      // serial port zu machen
29
      this.serialPort1.Close();
30
    }
31
  }

Hoffe das hilft dir weiter!

Grüße aus Wien
Christian

von Suchender (Gast)


Lesenswert?

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.