Autor Beitrag
Lord-Maricek
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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:
ausblenden volle Höhe C#-Quelltext
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)
            {
                /* 
                 * wenn trackbar z.b. 14
                 * send[0] = 1;
                 * send[1] = 4;
                 * 
                 * wenn trackbar z.b. 10
                 * send[0] = 1;
                 * send[1] = 0;
                */

            }
        }

    }
}


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:
ausblenden 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:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
else if (_trackbar >= 10)
            {
                /* 
                 * wenn trackbar z.b. 14
                 * send[0] = 1;
                 * send[1] = 4;
                 * 
                 * wenn trackbar z.b. 10
                 * send[0] = 1;
                 * send[1] = 0;
                */

            }



Ich hoffe ihr könnt mir helfen.

philipp
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 15.03.10 00:28 
user profile iconLord-Maricek hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: Mo 15.03.10 00:30 
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
6. Ein String besteht sowieso aus char; jedes Zeichen kann einzeln per Index angesprochen werden.

Das geht doch ganz einfach:
ausblenden 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:
ausblenden C#-Quelltext
1:
byte send = (byte)_trackbar;					
Lord-Maricek Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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:
ausblenden 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); // Wert_anzeige
            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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: Mo 15.03.10 16:47 
user profile iconLord-Maricek hat folgendes geschrieben Zum zitierten Posting springen:
Wie kann ich das mbesten machen?

Wie schon gesagt:
ausblenden C#-Quelltext
1:
(byte)_trackbar					

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: Mo 15.03.10 17:00 
wenn ich das ganze jetzt so mache:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
private void trackBar1_Scroll(object sender, EventArgs e)
        {
            _trackbar = trackBar1.Value;
            label8.Text = Convert.ToString(_trackbar); // Wert_anzeige
            send = (byte)_trackbar;

            sp.Write(send);

            
        }

bekomme ich immer eine Fehlermeldung:
ausblenden Quelltext
1:
2:
3:
Fehler  1  Die beste Übereinstimmung für die überladene System.IO.Ports.SerialPort.Write(string)-Methode hat einige ungültige Argumente.
und
Fehler  2  1-Argument: kann nicht von "byte" in "string" konvertiert werden.  C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\Visual Studio 2008\Projects\Servo_GUI\Servo_GUI\Form1.cs  53  22  Servo_GUI
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: 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:
ausblenden 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).
ausblenden C#-Quelltext
1:
sp.write(_bytes, 0, _bytes.Count);					
Lord-Maricek Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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
ausblenden 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); // Wert_anzeige
            

            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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 15.03.10 22:58 
So macht das wenig Sinn - wenn du wirklich Strings verschicken willst, dann mach das auch ;) .
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
if (trackbar <= 9)
  sp.Write("0" + trackbar.ToString());
else
  sp.Write(trackbar.ToString());
// oder auch sp.Write(trackbar.ToString("g2"));

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
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
BeitragVerfasst: 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
ausblenden C#-Quelltext
1:
2:
3:
4:
// nicht:
label8.Text = Convert.ToString(_trackbar);
// sondern:
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:
ausblenden C#-Quelltext
1:
2:
3:
4:
// nicht:
send = new char[2] { Convert.ToChar("0"), (char)_trackbar };
// sondern:
send = new char[2] { '0', (char)_trackbar };


3. char direkt benutzen, überflüssiges Convert weglassen
ausblenden C#-Quelltext
1:
2:
3:
4:
// nicht:
send = new char[2]{Convert.ToChar(_trackbar.ToString()[0]), Convert.ToChar(_trackbar.ToString()[1])};
// sondern:
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? :roll:

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 17



BeitragVerfasst: 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:
ausblenden C#-Quelltext
1:
2:
incoming[0] = Serial.read(); // ersts Zeichen
incoming[1] = Serial.read(); // zweites Zeichen.

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:
ausblenden C#-Quelltext
1:
2:
incoming[0] = Serial.read(); // das ist 0
incoming[1] = Serial.read(); // und dass die Zahl (1-9)

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 user profile iconChristian S.: C#-Tags hinzugefügt