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
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?
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 ;-)
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?
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
classProgram
2
{
3
staticvoidMain(string[]args)
4
{
5
Aa1=newA(13);
6
Aa2=a1;
7
a1.I=7;
8
System.Console.WriteLine(a1.I+","+a2.I);
9
a2=newA(a1.I);
10
System.Console.WriteLine(a1.I+","+a2.I);
11
a1=newA(4);
12
System.Console.WriteLine(a1.I+","+a2.I);
13
}
14
}
15
classA
16
{
17
inti;
18
publicA(inti)
19
{
20
this.i=i;
21
}
22
publicintI
23
{
24
get{returni;}
25
set{i=value;}
26
}
27
}
Ein paar Begriffe: Event, Delegate, je nach Anwendung Indexer und
Vererbung
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
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
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.
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
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
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(...kvpindict){
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)