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
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.
Suchender schrieb: > "textBox1.AppendText(dataEmpf) Hier hängst du doch standig neue Zeichen an. Vielleicht so textBox1.Text=dataEmpf Kenne dein Cod aber nicht?
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.
Kein Wunder:
> textBox1.AppendText(dataEmpf);
Was wohl bedeutet Append?
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
Hallo suchender, wenn du den Text ersetzen willst verwende einfach die Eigenschaft .Text fz
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?
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
Vielleicht bekommst du 4x das serialPort1_DataReceived event? setz mal einen Breakpoint und schau was da passiert!
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];
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?
ja das ist möglich, du kannst ja in größeren zeitabständen senden vom µc
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,
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.