Schönen Abend! Nachdem ich jetzt mal mein Dev Board fertig habe und ein bisschen herumspiele möchte ich Daten von meinem uC empfangen und Ausgeben. z.B. Temperatur in Feld 1 und Luftfeuchte in Feld 2. Dazu nutze ich SerialPort.ReadLine() von Visual C# (Ich kenne mich nicht so aus in C#). Kann mir das nur jemand erklären wie das genau abläuft? Die Daten werden ja im Puffer abgelegt und von dort werden dann die Daten gelesen oder? Nur wieviel Daten liest der Befehl ein? Wie kann ich diese Auswerten? Wie macht man das normalerweise? Vielleicht kann mir das jemand in einfachen Worten erklären. BG Andreas
ReadLine() liest so viel ein bis eine neue Zeile beginnt. Ich glaub für den c# Serialport ist ein Return CR-LF also Dezimal 13 - 10. Das musst du dann senden. Ich würde allerdings eher das Ereignis DataReceived zum empfangen nehmen. In meinem Terminalprog hab ich das so gemacht:
1 | static void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) |
2 | {
|
3 | if (!pause) |
4 | {
|
5 | Console.ForegroundColor = ConsoleColor.Green; |
6 | if (show == false) |
7 | Console.Write(sp.ReadExisting()); |
8 | else
|
9 | {
|
10 | string temp = sp.ReadExisting(); |
11 | foreach (char c in temp) |
12 | Console.Write(c.ToString() +"[" +((int)c)+"]"); |
13 | }
|
14 | Console.ResetColor(); |
15 | }
|
16 | }
|
Mit ReadExisting kannst du dann auslesen, was empfangen wurde, also im Puffer liegt.
Andreas Riegebauer schrieb: > Vielleicht kann mir das jemand in einfachen Worten erklären. Nein! Weil das ist nicht einfach. Ich nehme mal an, du willst die Werte in einer WindowsForms-Anwendung in einer Textbox ausgeben. Und jetzt beginnt dein Problem: Andreas Riegebauer schrieb: > (Ich kenne mich nicht so aus in C#). Deine Applikation, das WindowsForms-Fenster, ist ein Thread. Und mit der Instanziierung der Serialport-Klasse wird ein weiterer Thread angelegt. Nun ist aber .Net threadsicher. D.h. man kann keine Daten direkt von einem in einen anderen Thread schreiben. Das lässt der Compiler zwar durchgehen, das Programm stürzt aber ab. Das heisst natürlich nicht, daß man keine Daten, die mit serialport empfangen wurden, in eine Textbox schreiben kann. Auch auf das Risiko hin, daß mir wieder einer vorwirft, ich mache hier auf dicke Hose, solltes du folgende Fragen mit ja beantworten können: Ich weiss... ...was ein delegate ist ...wie man einen event anlegt und abfeuert ...was invokerequired bedeutet ...wie man ein callback anlegt und abfeuert Dann können wir hier gerne weitermachen. Ansonsten wird das nichts. mfg.
Hallo! Hmhm... Ich weiß nicht ob ich die Sachen Verstehe aber ich habe bereits ein Programm das mir Daten von der Seriellen einließt und in eine TextBox ausgibt. Ich habe nur das Problem das mir anscheinend Daten verschluckt werden. Also er macht 3 mal ein Update von Feld 1, 1 mal von Feld 2 und 5 mal von Feld 3. Mein Programmcode kommt gleich und ein Bild von der Oberfläche ist auch dabei. Vorher nur kurz zur Funktion des Puffers. Funktioniert das so wie im angehängten PDF? Hier jetzt der Programcode den ich mir zusammengebastelt habe:
1 | using System.Collections.Generic; |
2 | using System.ComponentModel; |
3 | using System.Data; |
4 | using System.Drawing; |
5 | using System.Linq; |
6 | using System.Text; |
7 | using System.Windows.Forms; |
8 | using System.IO.Ports; |
9 | |
10 | namespace SimpleSerial_mit_EventHandler |
11 | { |
12 | public partial class Form1 : Form |
13 | { |
14 | SerialPort sp = new SerialPort("com4", 9600, Parity.None, 8, StopBits.One); |
15 | string test2; |
16 | |
17 | public Form1() |
18 | { |
19 | InitializeComponent(); |
20 | } |
21 | |
22 | /******************************************** |
23 | * |
24 | * Start des Empfangs |
25 | * |
26 | *******************************************/ |
27 | private void button1_Click(object sender, EventArgs e) |
28 | { |
29 | try |
30 | { |
31 | sp.Open(); |
32 | sp.DataReceived += new SerialDataReceivedEventHandler(sp_datareceived); |
33 | button1.Enabled = false; |
34 | button2.Enabled = true; |
35 | } |
36 | catch (Exception ex) |
37 | { MessageBox.Show(ex.ToString()); } |
38 | |
39 | } |
40 | |
41 | /******************************************** |
42 | * |
43 | * Auslesen des Puffers |
44 | * |
45 | *******************************************/ |
46 | private void sp_datareceived(object sender, SerialDataReceivedEventArgs args) |
47 | { |
48 | test2 = sp.ReadLine(); |
49 | sp.DiscardInBuffer(); |
50 | this.Invoke(new EventHandler(DisplayText)); |
51 | } |
52 | |
53 | |
54 | /******************************************** |
55 | * |
56 | * Auswertung und Ausgabe der Messwerte |
57 | * |
58 | *******************************************/ |
59 | private void DisplayText(object sender, EventArgs e) |
60 | { |
61 | if (test2.IndexOf("CH5") != -1) |
62 | { |
63 | int c = 0; |
64 | test2 = test2.Remove(0, 3); |
65 | try |
66 | { |
67 | c = Convert.ToInt32(test2.Trim()); |
68 | textBoxCH1.Text = String.Format("{0,7:0.00}", c / 1000.0); |
69 | } |
70 | catch (OverflowException) |
71 | { |
72 | MessageBox.Show("{0} is outside the range of the Int32 type." + test2); |
73 | } |
74 | catch (FormatException) |
75 | { |
76 | MessageBox.Show("The {0} value '{1}' is not in a recognizable format." + |
77 | test2.GetType().Name + test2); |
78 | } |
79 | } |
80 | |
81 | if (test2.IndexOf("CH6") != -1) |
82 | { |
83 | int c = 0; |
84 | test2 = test2.Remove(0, 3); |
85 | try |
86 | { |
87 | c = Convert.ToInt32(test2.Trim()); |
88 | textBoxCH2.Text = String.Format("{0,7:0.00}", c / 1000.0); |
89 | } |
90 | catch (OverflowException) |
91 | { |
92 | MessageBox.Show("{0} is outside the range of the Int32 type." + test2); |
93 | } |
94 | catch (FormatException) |
95 | { |
96 | MessageBox.Show("The {0} value '{1}' is not in a recognizable format." + |
97 | test2.GetType().Name + test2); |
98 | } |
99 | } |
100 | if (test2.IndexOf("CH7") != -1) |
101 | { |
102 | int c = 0; |
103 | test2 = test2.Remove(0, 3); |
104 | try |
105 | { |
106 | c = Convert.ToInt32(test2.Trim()); |
107 | textBoxCH3.Text = String.Format("{0,7:0.00}", c / 1000.0); |
108 | } |
109 | catch (OverflowException) |
110 | { |
111 | MessageBox.Show("{0} is outside the range of the Int32 type." + test2); |
112 | } |
113 | catch (FormatException) |
114 | { |
115 | MessageBox.Show("The {0} value '{1}' is not in a recognizable format." + |
116 | test2.GetType().Name + test2); |
117 | } |
118 | } |
119 | } |
120 | |
121 | /******************************************** |
122 | * |
123 | * Stop des Empfangs |
124 | * |
125 | *******************************************/ |
126 | private void button2_Click(object sender, EventArgs e) |
127 | { |
128 | sp.Close(); |
129 | button1.Enabled = true; |
130 | button2.Enabled = false; |
131 | } |
132 | } |
133 | } |
BG Andreas
Andreas Riegebauer schrieb: > private void sp_datareceived(object sender, SerialDataReceivedEventArgs args) > > { > > test2 = sp.ReadLine(); > > sp.DiscardInBuffer(); > > this.Invoke(new EventHandler(DisplayText)); > > } Das Problem scheint mir folgendes zu sein: Wenn Daten vorhanden sind, sagen wir mal 2 Byte, feuert der sp den Event. Die Daten werden ausgelesen und angezeigt. Bevor du diese Daten überhaupt nur siehst, kommt aber schon der nächste Event, womit letztlich diese Daten überschrieben werden. Ändere mal folgende Zeile: textBoxCH1.Text = String.Format("{0,7:0.00}", c / 1000.0); in textBoxCH1.Text += String.Format("{0,7:0.00}", c / 1000.0); zieh' die Textbox etwas länger, damit alles reinpasst. Dann siehst ob deine Daten irgendwo sonsthin gehen oder ob ich mit meiner Vermutung richtig liege. mfg.
Hallo! Ich werde es zu hause versuchen nachdem ich meinen uC nicht bei der Hand habe. Funktioniert das mit Readline aber wie in meinem PDF skizziert? Wie wird das normalerweise gelöst? Das was ich habe wird ja nichts exotisches sein. Das wird es doch öfter geben das ein Datenstrom auf der Seriellen daher kommt der ausgewertet werden möchte. BG Andreas
Noch was zu dem Buffer: Warum löscht du den Buffer? Den würde ich gar nicht anrühren. Denn wenn du die Daten liest und dann den Puffer löscht, weisst du nicht, ob in der Zwischenzeit schon neue Daten angekommen sind. im Eventhandler: statt: test2 = sp.ReadLine(); sp.DiscardInBuffer(); unnötig. Würde ich höchstens nach dem Öffnen machen, um noch evtl vorhandenen Schrott rauszu- schmeissen. so: test2 = ""; byte[] nRB = new byte[sp.BytesToRead]; sp.Read(nRB, 0, sp.BytesToRead); for (int nInd = 0; nInd < nRB.Length; nInd++) { char chData = (char)nRB[nInd]; test2 += chData.ToString(); } Das ist dann völlig Datentransparent und erwartet auf der Schnittstelleseite keine Endebedingung. Die Daten solltest du dann auswerten, bevor du sie anzeigst. Und solange zwischenspeichern, bis alles da ist. mfg.
Wieso nimmst Du nicht die Komponente SerialPort aus der Toolbox ? Da musst Du Dich um keine Threads kümmern, das macht die Komponente selbst. Viele Grüße, Klaus
@K.S. Das mit den Threads ist ja nicht das Problem. Das funktioniert ja soweit. Nur das er mir hin und wieder was verschluckt. Ich würde halt gerne einen ganzen Datensatz lesen also bis zum NewLine um das auf einmal zu verarbeiten. Ich weiß aber eben nicht ob das so gelesen wird wie ich es skizziert habe. wenn es so ist dann sollte es doch funktionieren. Das mit dem Löschen des Buffers weiß ich auch nicht wieso ich das drinnen habe. Muss ein Überbleibsel sein aus dem Code von dem ich das entnommen habe. Wie kann ich das Abfeuern des DataReceived steuern? Also das er z.B. nur anspringt wenn NewLine gekommen ist? BG Andreas
K.S. schrieb: > Wieso nimmst Du nicht die Komponente SerialPort aus der Toolbox ? > Da musst Du Dich um keine Threads kümmern, das macht die Komponente > selbst. Das ist die gleiche Komponente bei der die gleiche Vorgehensweise beim Updaten von UI-Elementen nötig ist. > Viele Grüße, > Klaus
Thomas Eckmann schrieb: > Deine Applikation, das WindowsForms-Fenster, ist ein Thread. Und mit der > Instanziierung der Serialport-Klasse wird ein weiterer Thread angelegt. > Nun ist aber .Net threadsicher. D.h. man kann keine Daten direkt von > einem in einen anderen Thread schreiben. Das lässt der Compiler zwar > durchgehen, das Programm stürzt aber ab. Man kann die Threadüberorüfung abschalten und dann wedern keine Ausnahmen mehr ausgelöst. Ich habe fast noch nie so korrekt wie du es beschreibst programmiert, und trotzdem hatte ich nie Probleme. Und Daten von einen Thread in einen anderen gehen eben doch! Man setzt CheckForIllegalCrossThreadCalls auf false. Thomas Eckmann schrieb: > Ich weiss... > ...was ein delegate ist > ...wie man einen event anlegt und abfeuert > ...was invokerequired bedeutet > ...wie man ein callback anlegt und abfeuert Ja delegate musst ich schon benutzen Event auch Invoke habe ich glaube ich nur einmal gebraucht. Und Callback hab ich noch nie benutzt Und hab Treadübergreifende Sachen alle ohne Events gemacht. Das funktioniert wuderbar.
Andreas Riegebauer schrieb: > Wie kann ich das Abfeuern des DataReceived steuern? Also das er z.B. nur > > anspringt wenn NewLine gekommen ist? gar nicht. Der liest ja nicht mit, sondern schiebt nur durch. Die Auswertung muß nachher erfolgen. mfg.
Samuel K. schrieb: > Man kann die Threadüberorüfung abschalten und dann wedern keine > > Ausnahmen mehr ausgelöst. Ich habe fast noch nie so korrekt wie du es > > beschreibst programmiert, und trotzdem hatte ich nie Probleme. Und Daten > > von einen Thread in einen anderen gehen eben doch! Man setzt > > CheckForIllegalCrossThreadCalls auf false. Das kann man natürlich machen. Aber funktioniert das morgen auch noch? Also ich meine jetzt nicht Samstag, sondern z.B. mit Visual Studio 2012 mit Service Pack 2 von Windows 8. Dann konvertiert man das und guckt nur noch blöd. Damals mit Visual Studio 2003 und Framework 1 war das alles überhaupt kein Problem. Dann kam VS 2005 und Framework 2 und Schluss mit lustig. mfg.
Samuel K. schrieb: > Ja delegate musst ich schon benutzen > > Event auch > > Invoke habe ich glaube ich nur einmal gebraucht. > > Und Callback hab ich noch nie benutzt Bei der richtigen Implementierung sind wir noch gar nicht. Bislang ist das noch etwas halbgar. mfg.
Thomas Eckmann schrieb: > Damals mit Visual Studio 2003 und Framework 1 war das alles überhaupt > kein Problem. Dann kam VS 2005 und Framework 2 und Schluss mit lustig. > > mfg. ICh hab das immer mit NET2.0 gemacht. Aber heißt dass man braucht wenn man es richtig macht immer ein event?
Samuel K. schrieb: > ICh hab das immer mit NET2.0 gemacht. Aber heißt dass man braucht wenn > > man es richtig macht immer ein event? Nein braucht man nicht. Ich pack' das Ganze nur in ein Usercontrol und zieh das dann einfach in die Anwendung. Dann ist das mit drei Klicks fertig. Und dafür brauch ich den Event. In dem Usercontrol kann ich dann auf bestimmte Zeichen triggern und die Daten, erst wenn sie komplett da sind, weiterreichen. So wie Andreas das ja auch gerne haben möchte. mfg.
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.