Forum: PC-Programmierung C# Programm zum Steuern eines Sensornetzwerks


von Soma-web (Gast)


Angehängte Dateien:

Lesenswert?

Hi MC Community,
ich muss in C# ein Programm entwerfen welches ein Sensornetz verwaltet.

Hardware: Cypress First Touch Starter Kit bestehend aus
- Cypress PC Bridge
- Cypress RF Expansion Card (Identifizierbar über eine MID)

Für die Kommunikation zwischen dem USB Dongle und dem RF Sensorboard 
wird das CyFi_portokoll verwendet.

Es gibt noch eine Besonderheit: Die normale Anmeldung eines RF Sensors 
geschieht normalerweise über einen auf beiden Seiten ausgeführten Bind 
Befehl (hierzu muss auf dem USB Dongle ein Button geklickt werden (oder 
per SW der Befehl gestartet werden) und auf der Sensorplatine auch ein 
Button gedrückt werden. Nun weißt der USB Dongle dem RF-Board eine DevID 
zu und spricht ab diesem zeitpunkt immer über die DevId mit dem 
jeweiligen Sensor (so ist er also identifizierbar) bei mir geschieht das 
aber über eine eigen gebaute Induktive Datenübertragung. Sprich sobald 
der Sensor an die Induktive Kopplung angehängt wird weißt der USB Dongle 
dem Board eine Dev Id zu. So sparrt man sich lässtiges Buttongedrücke.

Die Aufgabe des Programms besteht nun darin dem Sensor eine spezielle 
Position zuzuordnen (es werden bis zu 255 Sensoren verwendet). Um im 
Ausfall sofort zu wissen an welcher Position der Sensor spinnt.

Über USB kann ich die DevID und MID des gerade induktiv gekoppelten 
Sensors auslesen.

Ich habe mir gedacht dazu ein Struct Array zu erstellen:

Struct Sensor
{
int pos;
int DevId;
int MID;
}

Struct[] Sesnor = new Sensor[255];

for(int i = 0; i < 255; ++i)
{
Sensor[i].pos = i+1;
}

und ab da an mit dem Sensor über das Struct Array zu kommunizieren.

D.H. Wenn der gerade eben ind. gekoplte Sensor auf pos 12 installiert 
wird sagt man im Programm:

Sensor[12].DevID = getcurrentDevID();

Das Problem sehe ich jetzt nur, wenn man z.b. den Sensor erst auf Pos11 
angibt
Sensor[11].DevID = getcurrentDevID();
sich es aber dann anders überlegt und doch Pos31 machen will.
Sensor[31].DevID = getcurrentDevID();
Dann ist der Sensor ja doppelt gelistet!

Habt ihr irgendwelche Verbesserungsvorschläge oder ein anderen Geadnken 
mit dem es sich besser realisieren lässt.

Danke und Grüße
Soma

von Soma W. (soma)


Lesenswert?

Oder sollte ich einfach mit einem Zeiger auf eine Stelle in einem DevID 
Array arbeiten?

von Peter (Gast)


Lesenswert?

Soma Web schrieb:
> Oder sollte ich einfach mit einem Zeiger auf eine Stelle in einem DevID
> Array arbeiten?

zeiger gibt es in c# nicht mehr, es sind alles nur referenzen.

Warum nicht ein Dictionary verwenden, mit den Index auf die ID?

von Soma W. (soma)


Lesenswert?

Dictonray werd ich mir mal anschaun danke erstmal

von Oliver P. (Firma: UAS Merseburg) (olipunk)


Lesenswert?

Warum nicht gleich eine Klasse "Sensor" entwerfen, die sich dann über 
Methoden selbst verwalten kann? Und dann in eine generische Liste 
schreiben? Oder eben (besser => Peter) in einem Dict verwalten? Warum 
ein struct? Oder gleich einen SensorManager als Klasse implementieren, 
der die Ausfallsicherheit managed?
C# (ich vermute mal .NET) ist mächtig ;-)

von Soma W. (soma)


Lesenswert?

Hi ganz ehrlich ich bin noch nicht soooo firm in C# bitte füttert mich 
mal mit googlebaren begriffen. Klasse die sich selbst verwaltet? Versteh 
ich gerade nich (ok es sind auch schon eineige Biere ;) Dict ist doch in 
der art eine ArrayList oder?

von Sam .. (sam1994)


Lesenswert?

Soma Web schrieb:
> Dict ist doch in
> der art eine ArrayList oder?

Nein! Eine Dict ist KEY -> Value
Eine ArrayList ist  Object

Für was speichert du überhaupt pos? Das ist doch schon der Index des 
Elements?

Mit Referenzen kann man auch viel machen. Sie entsprechen Zeigern. Wenn 
man sich damit aber nicht auskennt können komische Fehler entstehen.
Ein Beispiel für die tückischen Referenzen:
1
class Program
2
{
3
    static void Main(string[] args)
4
    {
5
        A a1 = new A(13);
6
        A a2 = a1;
7
        a1.I = 7;
8
        System.Console.WriteLine(a1.I + "," + a2.I);
9
        a2 = new A(a1.I);
10
        System.Console.WriteLine(a1.I + "," + a2.I);
11
        a1 = new A(4);
12
        System.Console.WriteLine(a1.I + "," + a2.I);
13
    }
14
}
15
class A
16
{
17
    int i;
18
    public A(int i)
19
    {
20
        this.i = i;
21
    }
22
    public int I
23
    {
24
        get { return i; }
25
        set { i = value; }
26
    }
27
}


Ein paar Begriffe: Event, Delegate, je nach Anwendung Indexer und 
Vererbung

von Sam .. (sam1994)


Lesenswert?

Noch was zu deinem Problem:

Bessere Idee

Nimm eine List<T>
Bei einem neuen Sensor trägst du ihn ein. Sollte er seine pos verändern, 
änderst du nur die pos in der Struct.

Noch ein Begriff um Klassen zu sortieren (z.b. nach pos): IComparable

von Soma W. (soma)


Lesenswert?

Samuel K. schrieb:
> Noch was zu deinem Problem:
>
> Bessere Idee
>
> Nimm eine List<T>
> Bei einem neuen Sensor trägst du ihn ein. Sollte er seine pos verändern,
> änderst du nur die pos in der Struct.
>
> Noch ein Begriff um Klassen zu sortieren (z.b. nach pos): IComparable

Verstehe ich das richtig eine List<int pos, int DevID, string MID> und 
wenn er nun die Position ändert einfach die pos übeschreiben?
Wie spreche ich denn dann eine bestimmte position an? Ich muss ja dann 
in meinem Programm auch sagen können GetTemp_posX?

Danke für alles ich werde es jetzt mal mit einer Klasse versuchen. Für 
Vorschläge in ich immer dankbar.

grüße Soma

von Sam .. (sam1994)


Lesenswert?

Soma Web schrieb:
> List<int pos, int DevID, string MID>

Das gibt es nicht.

Am besten wäre Dictionary<int DevID, *deiner struct*>

Wenn ein Gerät es sich anders überlegt, suchst du es über den Key (ID) 
und setzt die Position in deiner struct.

Mit einer List kannst du es auch machen, allerdings müsstest du sie nach 
dem richtigen Eintrag durchsuchen.


Wenn du nur 256 Sensoren hast macht es nichts, mal alle Einträge 
durchzugehen und die Position abzufragen. Bei Dictonary macht man das 
mit foreach.

von Soma W. (soma)


Lesenswert?

Samuel K. schrieb:
> Soma Web schrieb:
>> List<int pos, int DevID, string MID>
>
> Das gibt es nicht.
>
> Am besten wäre Dictionary<int DevID, *deiner struct*>
>
> Wenn ein Gerät es sich anders überlegt, suchst du es über den Key (ID)
> und setzt die Position in deiner struct.
>
> Mit einer List kannst du es auch machen, allerdings müsstest du sie nach
> dem richtigen Eintrag durchsuchen.
>
>
> Wenn du nur 256 Sensoren hast macht es nichts, mal alle Einträge
> durchzugehen und die Position abzufragen. Bei Dictonary macht man das
> mit foreach.

Hi Samuel, danke für die Hilfe!
Das klingts ehr gut, was du da schreibst. Ich würde es dann 
folgendermaßen umsetzen. Bitte sag bescheid, wenn es besser, schöner 
etc. pp geht.
Ist jetzt nurmal ne Überlegung also kein funktionierender Code.
1
struct sensor
2
{
3
int pos;
4
int DevID;
5
int MID;
6
}
7
8
Dictionary Nodes <int DevID, struct sensor>
9
10
public void new_sensor()
11
{
12
if(get_DevID =! Eintrag in Liste) //muss ich iwie durchchecken krieg ich 
13
                                  //aber hin denk ich
14
{
15
struct newsensor = new sensor;
16
newsensor.pos = get_pos();
17
newsensor.DevID = get_DevID();
18
newsoensor.MID = get_MID();
19
20
Add.Nodes(get_DevID(), newsensor)
21
}
22
else
23
{
24
WrietOutput("DevId schon vorhanden, trotzdem einfügen? Ja/Nein")
25
... //in Liste einfügen wie oben nur davor den alten Sensor mit selber
26
    //DevID entfernen
27
if(get_DevID() == Eintrag in Liste)
28
{Remove.Nodes(DevID);}
29
}
30
}
So in etwa hab ich mir das dann vorgestellt? Richtig?

P.S. wie füge ich hier denn code ein?
danke und Grüße Soma

von Soma W. (soma)


Lesenswert?

Wie komm ich denn dann bitte auf einen Struct Wert in meinem Value der 
Dictionary?

von Sam .. (sam1994)


Lesenswert?

Dein Ansatz stimmt.

Es müsste korrekt so aussehen:
1
struct sensor
2
{
3
int pos;
4
int DevID;
5
int MID;
6
}
7
8
Dictionary<int, sensor> Nodes;
Man schreibt nur den Typ in die <> Klammern
1
nimm [c]...[/c] für code

von Soma W. (soma)


Lesenswert?

1
namespace WindowsFormsApplication1
2
{
3
    public partial class Form1 : Form
4
    {
5
        public struct Sensor
6
        {
7
            public int pos;
8
            public int DevID;
9
            public string MID;
10
        }
11
12
       // Sensor newsensor = new Sensor();
13
14
        Dictionary<int, Sensor> network = new Dictionary<int, Sensor>();
15
        
16
        public Form1()
17
        {
18
            InitializeComponent();
19
        }
20
21
        private void Form1_Load(object sender, EventArgs e)
22
        {
23
            
24
        }
25
26
        private void newsensor()
27
        {
28
            Sensor newsensor = new Sensor();
29
            newsensor.pos = Convert.ToInt32(textpos.Text);
30
            newsensor.DevID = Convert.ToInt32(textdev.Text);
31
            newsensor.MID = textmid.Text;
32
33
            network.Add(Convert.ToInt32(textdev.Text), newsensor);
34
35
        }
36
37
        private void add_Click(object sender, EventArgs e)
38
        {
39
            newsensor();
40
        }
41
42
        private void list_Click(object sender, EventArgs e)
43
        {
44
            foreach(KeyValuePair<int, Sensor> kvp in network)
45
            {
46
                textBox1.Text = "" + Convert.ToString(kvp.Key) + " " + Convert.ToString(kvp.Value.DevID) + " " + Convert.ToString(kvp.Value.MID) + "\n\r";
47
            }
48
49
                       
50
        }
51
52
        private void remove_Click(object sender, EventArgs e)
53
        {
54
            Sensor newsensor = new Sensor();
55
            newsensor.pos = Convert.ToInt32(textpos.Text);
56
            newsensor.DevID = Convert.ToInt32(textdev.Text);
57
            newsensor.MID = textmid.Text;
58
59
            network.Remove(Convert.ToInt32(textdev.Text));
60
        }
61
62
63
    }
64
}

So hab ich das jetzt mal testhalber gemacht.

ERSTMAL 1000 DANK!

Grüße Soma

von Soma W. (soma)


Lesenswert?

Eine letzte Frage hätte ich noch.
Und zwar hab ich jetzt mehrmals gelesen, dass man in einem Dict die 
Values nicht verändern darf. Heißt das, dass ich die zu bearbeitende 
Position entfernen muss und dann neu einpflege in dem Dict?

Danke

von Arc N. (arc)


Lesenswert?

Soma Web schrieb:
> Eine letzte Frage hätte ich noch.
> Und zwar hab ich jetzt mehrmals gelesen, dass man in einem Dict die
> Values nicht verändern darf. Heißt das, dass ich die zu bearbeitende
> Position entfernen muss und dann neu einpflege in dem Dict?
>
> Danke

Das geht (abhängig vom Kontext)...
1
dict[...] = newValue;
was nicht geht ist beim Iterieren den Wert direkt zu verändern
1
foreach (... kvp in dict) {
2
    kvp.Value = newValue;
3
}
da kvp.Value readonly ist. Ist Value aber eine Referenz und kein 
Wert(etyp) wie in deinem Fall, kann man deren Inhalte durchaus verändern 
(also statt struct class verwenden)
1
    kvp.Value.irgendwas = newValue;

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.