C# Programm zum Steuern eines Sensornetzwerks

Gast #2048277
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
Angehängte Dateien:
(Firma: UAS Merseburg) #2048842
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 ;-)
#2048889
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
#2050534
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
#2050697
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.
#2050970
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
#2051305
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
#2051382
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren