Autor |
Beitrag |
Lord-Maricek
Beiträge: 17
|
Verfasst: So 14.03.10 20:57
Moin,
ich bin dabei ein Programm zuschreiben, bei dem eine Trackbar den Wert 0 bis 18 hat.
Nachdem die Trackbar verstellt wurde, soll die Position in einem String Array gespeichert werden.
Sehe hier:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| namespace Servo_GUI { public partial class Form1 : Form { SerialPort sp; int modus = 0; string[] send; int _trackbar;
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { if (modus == 0) { sp = new SerialPort(comboBox1.SelectedItem.ToString(), Convert.ToInt32(comboBox2.SelectedItem.ToString()), Parity.None, 8, StopBits.One); sp.Open(); modus = 1; button1.Text = "Trennen"; label4.Text = "Verbunden"; panel1.Enabled = true; } else if (modus == 1) { sp.Close(); modus = 0; button1.Text = "Verbinden"; label4.Text = "Getrennt"; panel1.Enabled = false; } }
private void trackBar1_Scroll(object sender, EventArgs e) { _trackbar = trackBar1.Value; if (_trackbar <= 9) { send[0] = "0"; send[1] = Convert.ToString(_trackbar); } else if (_trackbar >= 10) { } }
} } |
Mein erstes Problem ist, die Trackbar ist am anfang immer in Mittelstellung auf 9.
Wenn ich jetzt den Slider nach links bewege, also 0-8, bekomm ich immer ne Fehlermeldung:
Quelltext 1: 2:
| NullReferenceException wurde nicht bedandelt. Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt. |
Und mein 2. ist, wie ich dass in dem 2. Teil der if schleife mache:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| else if (_trackbar >= 10) { } |
Ich hoffe ihr könnt mir helfen.
philipp
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: So 14.03.10 21:17
1. Das String-Array wird nur deklariert, aber nicht erzeugt. Das ist die Erklärung für die NullReferenceException.
2. Ein String-Array ist falsch gewählt: Du weißt ja nicht, wie viele Einträge es geben wird. Benutze lieber eine List<T>.
3. Du willst Zahlen speichern, warum machst du daraus Strings? Nimm doch lieber List<int>. Oder wenn du die Ziffern speichern willst, dann kannst du ein char-Array bzw. List<char> verwenden.
4. Was ist eigentlich eine if-Schleife?
5. Zum Startwert der TrackBar kann ich nichts sagen. Laut SDK-Doku sollte der Standardwert 0 sein. Vielleicht wird das im Designer versehentlich falsch gesetzt.
6. Zu dem, was du unter 2. nennst: Wenn du Zahlen benutzen würdest, könntest du mit modulo (% 10) arbeiten. Ein String besteht sowieso aus char; jedes Zeichen kann einzeln per Index angesprochen werden. Wo ist dann das Problem?
Gruß Jürgen
PS. Der Code zum Button1-Click hat doch nichts mit diesem Problem zu tun, oder? Dann hättest du ihn weglassen sollen/können, weil er nur ablenkt.
PS 2. Namen wie Button1 oder Label23 gehören verboten, siehe .NET Richtlinien für Namen
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: So 14.03.10 22:40
ok danke.
Ich will die daten dann per SerialPort senden, dswegen wollte ich es in einem Array speichern.
Die Namen änder ich noch. Ich möchte die Zahlen in der 2. If-"ABFRAGE" gerne in einem Array speichern.
Habt ihr vielleicht ein beispiel,(mit code wens geht) wie ich das ambesten machen könnte?
Philipp
|
|
Kha
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 15.03.10 00:28
Lord-Maricek hat folgendes geschrieben : | Ich will die daten dann per SerialPort senden, dswegen wollte ich es in einem Array speichern. |
Und warum nicht in einem einzelnen Byte? Als ich das letzte Mal nachgeschaut habe, hat 0-99 noch in ein solches gepasst .
_________________ >λ=
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 00:30
JüTho hat folgendes geschrieben : | 6. Ein String besteht sowieso aus char; jedes Zeichen kann einzeln per Index angesprochen werden. |
Das geht doch ganz einfach:
C#-Quelltext 1:
| send[0] = _trackbar.ToString()[0]; |
Wenn du mit Strings arbeiten willst, dann sollten solche Grundlagen zur String-Verarbeitung bekannt sein.
Gruß Jürgen
PS. Sebastian hat natürlich recht:
C#-Quelltext 1:
| byte send = (byte)_trackbar; |
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Mo 15.03.10 15:17
moin,
ok danke für die Antworten. Mit bytes habe ich mich noch nicht so richtig beschäftigt.
Wenn ich das jetzt richtig verstanden habe passen in ein Byte 2 Zahlen oder Buchstaben rein?
Philipp
Ich habe das grade nochmal versucht, aber wenn ich sp.Write(tmp) eigebe kommt immer nur dass byte nicht zu string convertirt werden kann.
Nochmal mit strings, funtt aber noch nicht:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| private void trackBar1_Scroll(object sender, EventArgs e) { _trackbar = trackBar1.Value; label8.Text = Convert.ToString(_trackbar); if (_trackbar <= 9) { string _send = Convert.ToString(_trackbar); send = new string[2]{Convert.ToString("0"), Convert.ToString(_trackbar)}; sp.Write(_send); } else if (_trackbar >= 10) { char[] tmp; string _send; tmp = new char[2] {Convert.ToString(_trackbar)[0], Convert.ToString(_trackbar)[1] }; _send = Convert.ToString(tmp); } } |
Zuletzt bearbeitet von Lord-Maricek am Mo 15.03.10 15:55, insgesamt 1-mal bearbeitet
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 15:45
Falsch. Ein Byte kann Werte von 0 bis 255 enthalten, nämlich 8 Bit. Ein Buchstabe (char) benötigt unter .NET i.d.R. zwei Byte.
Einzelheiten siehe z.B. [Wikibooks] Datentypen und die dort folgenden Kapitel.
Jürgen
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Mo 15.03.10 16:27
Jo danke für die Antwort.
Also ich steige da immer noch nicht so richtig durch.
Ich bin zurzeit noch mit den Grundlagen beschäftigt, aber ich brauche dieses Programm für die Schule.
Könnt ihr mir da vielleicht nochmal helfen? Das Problem ist, dass die Zahlen an einen Mikrocontroller gesendet werden, und der Controller muss wissen, wie viele Bytes reichkommen. Da ich nur die Zahlen von 0 bis 18 übermitteln will, habe ich mir überlegt, dass ich dem Controller sage, dass 2 Bytes reinkommen werden, aber wenn die trackbar nur auf 0-9 steht, dass dann einfach eine Null vor die Zahl gesetzt wird, dass ich statt 1, 01 übersende. Wie kann ich das mbesten machen?
philipp
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 16:47
Lord-Maricek hat folgendes geschrieben : | Wie kann ich das mbesten machen? |
Wie schon gesagt:
C#-Quelltext
Das liefert ein Byte (diesen Typ brauchst du sowieso), und der Inhalt liefert einen der Werte 0 bis 18. Punkt.
Alles andere macht es komplizierter (und der Umweg über String ist eher abwegig).
Jürgen
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Mo 15.03.10 17:00
|
|
danielf
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mo 15.03.10 17:09
Hallo,
sagen dir Methoden etwas? Sagen dir Parameter etwas?
Diese Begriffe und das Verständnis dafür brauchst du um Programmieren zu können und gehören zu den absoluten Grundlagen. Am Besten du stöberst mal in dem Openbook C#. Ansonsten werden dir keine Hilfestellungen etwas helfen.
VS zeigt dir die Methoden-Deklarationen oder auch MSDN. Aus dieser geht hervor, dass du einen String benötigst. Das ist genau das was die Fehlermeldung auch sagt.
Gruß Daniel
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 17:47
@Daniel
Es ist nicht gesagt, dass du recht hast. Nach dem o.g. Hinweis von Kha könnte das Senden von Bytes sinnvoll(er) sein. Dazu gibt es eine eigene Version, nämlich SerialPort.Write-Methode (Byte[], Int32, Int32).
Aber du hast in einer Hinsicht völlig recht: Wenn und solange er nicht versteht, worin sich char, byte, integer unterscheiden und was ein Methodenaufruf macht, können wir stundenlang erklären, ohne dass er weiterkommt.
Gruß Jürgen
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Mo 15.03.10 17:47
moin,
ich brache den Code dringent, könntet ihr mir vielleicht mal ein beispiel nennen.
An Beispielen versteh ich das meistens.
C#-Quelltext 1: 2: 3: 4: 5:
| public void Write( byte[] buffer, int offset, int count ) |
das hatte ich mir noch angeschaut, aber weiß noch nicht so wirklich wie man es verwendet.
Philipp
Achja, ich muss den Wert in einem Byte übertragen, da ich sonst auf dem Mikrocontroller großen aufwand mit dem speichern der bytes betreiben muss.
|
|
danielf
Beiträge: 1012
Erhaltene Danke: 24
Windows XP
C#, Visual Studio
|
Verfasst: Mo 15.03.10 18:05
D.h. die Methode erwartet einen Byte-Array (byte[], einen Offset (in int) und einen Count (auch in int).
Da du ein byte hast, musst du dieses eben in einen Byte-Array bringen. Das kannst du zum Beispiel so:
C#-Quelltext 1:
| byte[] _bytes = new byte[] { (byte) _trackbar }; |
Einen Offset hast du in diesem Fall nicht. Count entspricht der Länge der zu übertragenden bytes (du willst 1 übertragen, bzw. alle die im Array sind).
C#-Quelltext 1:
| sp.write(_bytes, 0, _bytes.Count); |
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Mo 15.03.10 21:27
ok danke.
nach noch ein bisschemn rumprobieren habe ichs endlich geschafft
es heißt übrigens _bytes.lenght und nicht _bytes.count
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| private void trackBar1_Scroll(object sender, EventArgs e) { _trackbar = trackBar1.Value; label8.Text = Convert.ToString(_trackbar);
if (_trackbar <= 9) { send = new char[2] { Convert.ToChar("0"), (char)_trackbar }; sp.Write(send, 0, send.Length); } else if (_trackbar >= 10) { send = new char[2]{Convert.ToChar(_trackbar.ToString()[0]), Convert.ToChar(_trackbar.ToString()[1])}; sp.Write(send, 0, send.Length); } } |
|
|
Kha
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Mo 15.03.10 22:58
So macht das wenig Sinn - wenn du wirklich Strings verschicken willst, dann mach das auch .
C#-Quelltext 1: 2: 3: 4: 5:
| if (trackbar <= 9) sp.Write("0" + trackbar.ToString()); else sp.Write(trackbar.ToString()); |
Unsere Frage, warum du zwei Zeichen verschicken willst, wenn es doch ein Byte täte, hast du aber immer noch nicht beantwortet. Wenn das Ding am anderen Ende der Leitung bereits fertig ist und seine Daten so will, sag das doch so .
_________________ >λ=
|
|
JüTho
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Mo 15.03.10 23:11
Geschafft? Naja. Wo ist jetzt noch Byte-Array? Du sprichst wieder nur von Char-Array.
Einige überflüssige/sinnlose Codes können noch weg bzw. verkürzt werden:
1. ToString benutzen
C#-Quelltext 1: 2: 3: 4:
| label8.Text = Convert.ToString(_trackbar); label8.Text = _trackbar.ToString(); |
Das ist zwar inhaltlich das Gleiche; aber ToString ist das Standardverfahren, zumal jede Klasse diese Methode hat.
2. Es gibt char-Konstante:
C#-Quelltext 1: 2: 3: 4:
| send = new char[2] { Convert.ToChar("0"), (char)_trackbar }; send = new char[2] { '0', (char)_trackbar }; |
3. char direkt benutzen, überflüssiges Convert weglassen
C#-Quelltext 1: 2: 3: 4:
| send = new char[2]{Convert.ToChar(_trackbar.ToString()[0]), Convert.ToChar(_trackbar.ToString()[1])}; send = new char[2] { _trackbar.ToString()[0], _trackbar.ToString()[1] }; |
Ich hatte doch schon längst darauf hingewiesen, dass ein String aus Chars besteht und per Index ein einzelnes Zeichen geholt wird. Ein Zeichen ist ein char, wozu also noch Convert.ToChar?
Ich wiederhole meinen dringenden Rat: Lerne die verschiedenen Datentypen kennen und unterscheiden, und lerne, wie konvertiert werden kann! Auch Sebastians Nachfrage und Unverständnis bestätigt dies: Warum willst du es kompliziert mit sieben Umwegen machen, wenn es in einem Schritt ginge?
Jürgen
|
|
Lord-Maricek
Beiträge: 17
|
Verfasst: Di 16.03.10 18:53
ok dabke ich änder das nochmal. Da ich dann doch ein paar Probleme mit dem empfänger bekommen habe, sende ich doch in Chars[]. Jetzt zur Frage warum ich 2 Zeichen versenden will:
Das Problem ist, dass ich auf dem Mikroprozessor (Arduino Nano) immer angeben muss, wieviel reinkommt, wenn ich jetzt 2 Chars sende aber nur eine Serielle abfrage mache speichert er erst das erste übermittelte Zeichen und überschreibt, dann mit dem 2. Zeichen die Variable. Deswegen wollte ich es so machen, dass ich 2 Zeichen sende und 2 Serielle Abfragen mache:
C#-Quelltext 1: 2:
| incoming[0] = Serial.read(); incoming[1] = Serial.read(); |
Aber da ich für den Servo nicht nur 2 stellige Zahleb übertragen muss sonder auch mal einstellige (1-9) wollte ich, dass dann einfach erst ne 0 übermittelt wird und dann die einstellige Zahl:
C#-Quelltext 1: 2:
| incoming[0] = Serial.read(); incoming[1] = Serial.read(); |
Und wenn ich das dann in ein Integer wandeln will, frage ich einfach ab, ob in income[0] eine null ist oder nicht.
Das mit dem senden habe ich jetzt soweit verstanden, ich möchte jetzt auch noch Daten empfangen, und auch wider in einem Char speichern. Ichhabe schon ein bisschen im I-Net geschaut, aber noch nicht ein guten Tuto gefunden. Könnt ihr mir helfen? Ist es möglich, dass wenn eine Datei vom Mikroprocessor gesendet, der PC automatisch empfängt ohne aufruf einer Funktion bzw. ohne dass ich jetzt andauernd eine Funktion aufrufen muss.
Philipp
Moderiert von Christian S.: C#-Tags hinzugefügt
|
|