Nochmal LAN-Shield Basics

Hallo nochmal,

nachdem ich mein LAN-Shield mit dem Democode jetzt am Laufen habe möchte ich jumperabhängig die IP wählen können.

Problem: die Festlegung der IP erfolgt ja per IPAddress ip(192,168,xxx,yyy); noch vor dem Setup. Im Setup kann ich aber erst die Jumperabfrage machen.

Dort geht aber eine erneute Zuweisung wie IPAddress ip(192,168,aaa,bbb); nicht :confused:

Ich geb's zu, ich bastel mir hier ohne richtigen Plan was zusammen, aber das ist ja durchaus der arduino-Gedanke.

Wer hilft mir auf die Sprünge?

Die Adresse wird da nicht festgelegt. Du erstellst da lediglich ein Objekt das die Adresse enthält. Wenn du dann ein weiteres Objekt mit einer anderen Adresse erstellst wird auch nichts geändert.

Ähhh, ok - und wie mache ich dann die Änderung?

Klaus_ww: Problem: die Festlegung der IP erfolgt ja per IPAddress ip(192,168,xxx,yyy); noch vor dem Setup. Im Setup kann ich aber erst die Jumperabfrage machen.

Dort geht aber eine erneute Zuweisung wie IPAddress ip(192,168,aaa,bbb); nicht :confused:

Eine IP-Adresse ist meines Erachtens einfach ein Byte-Array mit 4 Bytes.

Also schreibst Du statt:

IPAddress ip(192, 168, 1, 177);

ein Byte-Array:

byte ip[4]={192, 168, 1, 177};

und kannst dann an die vier Bytes mit ip[0], ip[1], ip[2], ip[3] im setup() auch erstmal andere Werte zuweisen, bevor Du loslegst. Geht das nicht?

Nicht praktisch getestet, aber du kannst die 'IPAdress(..' und 'Ethernet.begin(..' Zeilen auch in der Hauptschleife (loop) ausführen. Verschiebe diese hierher und wenn du eine neue IP setzten willst führe hinterher wieder 'Ethernet.begin(mac, ip)' aus. Ach ja, denke daran eine Abfrage einzubauen die diese Schritte nur einmal bzw. erst wieder ausführt wenn du die Jumper geändert hast.

Eine IP-Adresse ist meines Erachtens einfach ein Byte-Array mit 4 Bytes.

Intern ja. IPAddress ist eine Klasse. Aber der Subkript-Operator [] und der Zuweisungs-Operator sind überladen. Daher kann man die Adresse direkt ändern. Man muss also nicht unbedingt gleich ein Byte Array nehmen, sondern sollte auch ip[0] = ... machen können

Klaus_ww: Problem: die Festlegung der IP erfolgt ja per IPAddress ip(192,168,xxx,yyy); noch vor dem Setup. Im Setup kann ich aber erst die Jumperabfrage machen.

Dort geht aber eine erneute Zuweisung wie IPAddress ip(192,168,aaa,bbb); nicht :confused:

"Jumperstellung" hört sich für mich nicht nach "Änderung in loop" an. Kann man das Objekt nicht einfach im setup erstellen, also in setuo

Wenn Schalter in Stellung A, dann IPAddress ip(192,168,xxx,yyy); Wenn Schalter in Stellung B, dann IPAddress ip(192,168,aaa,bbb);

?

Ne, ich denke nicht in der loop. Das könnte auch Probleme bereiten. Er will sicher niccht während des Betriebs die IP Adresse ändern.

Hier ist die setup genau das richtige, denn die wird EINMAL nach dem Reset ausgeführt. Danach sollte die Jumperstellung niht mehr interessant sein.

So, hab eure Vorschläge mal ausprobiert - danke schonmal für das rege Feedback!

Meine Abfrage für die tatsächliche einmalige Festlegung der IP bei Start funktioniert. Serielles Debugging bestätigt das.

Ein ändern des Arrays geht aber in's Leere. Es wird immer die im Deklarationsbereich übergebene IP verwendet. Ansonsten MUSS dort per IPAddress ip(192,168,aaa,bbb); eine ebensolche festgelegt werden, sonst meckert der Compiler.

Bleibt also die Frage, wie ich das dann tatsächlich einmalig im Setup gebacken bekomme. Heute aber sicher nicht mehr ...

Für meinen Test morgen schreib ich's einfach erst mal hart in den Code. Und dann sehen wir mal weiter.

Du kannst doch erst mal global das Objekt erstellen und dann in setup() ändern. Erst wenn du Ethernet.begin() macht ist die Adresse fest.

Klaus_ww: Ein ändern des Arrays geht aber in's Leere.

Verstehe ich nicht.

Gerade mal das Webserver-Beispiel leicht modifiziert und auf einen MEGA mit dieser Initialisierungssequenz draufgeladen:

byte ip[4]={192, 168, 2, 180};
EthernetServer server(80);

void setup() {
  Serial.begin(9600);
  ip[3]=185; // hier wird die Adresse geändert
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

Und das Programm meldet im Seriellen Monitor einwandfrei:

server is at 192.168.2.185

Serenifly:
Du kannst doch erst mal global das Objekt erstellen und dann in setup() ändern. Erst wenn du Ethernet.begin() macht ist die Adresse fest.

Und wie mach ich das konkret? Sorry, dass ich so auf dem Schlauch stehe.

Hmm, ich hatte im Test das gesamte Array neu beschrieben. Sollte ja keinen Unterschied machen - dachte ich.

Also nochmal probieren :)

Jurs, das gibt wieder einen Punkt für Dich - so klappt das tatsächlich. Hatte natürlich nen Fehler in der Syntax :angry: der irgendwas gemacht hat aber nicht den Inhalt des Arrays ändern.

Jetzt fluppt das :grinning:

Großes Danke!!!

Und wie das jurs gemacht, sollte das auch mit einem IPAddress Objekt statt einem Array gehen. Die IPAddress Klasse verwaltet das Array intern, aber man kann sie durch den überladenen Subkript Operator wie ein Array ansprechen

Hey, das bringt mich vielleicht auf eine Idee, eine Lösung für folgendes Problem zu finden: Die IP soll später frei konfigurierbar sein, ohne jedesmal die Programmierung ändern zu müssen. Jetzt hätte ich da so spontan eine Idee: Eine Datei auf der SD-Karte ablegen und in dieser Datei die IP speichern. Beim Start des Systems dann erst die Datei einlesen, die IP übernehmen und entspr. der o.g. Vorschläge weitermachen. Ob das gehen würden ? Grübel ...

Greece2001

Serenifly: Die IPAddress Klasse verwaltet das Array intern, aber man kann sie durch den überladenen Subkript Operator wie ein Array ansprechen

Uff, wenn ich das irgendwann mal verstehe geb' ich einen aus!

Greece2001: Eine Datei auf der SD-Karte ablegen und in dieser Datei die IP speichern. Beim Start des Systems dann erst die Datei einlesen, die IP übernehmen und entspr. der o.g. Vorschläge weitermachen. Ob das gehen würden ?

Karte lesen geht problemlos, und nach meinen jüngsten Lernerfolgen mit dem dynamischen Ändern von IP-Adressen sollte das auch gehen. Aber sicher steckt irgendwo noch ein Pferdefuss, könnte ich drauf wetten!

Klaus_ww: Uff, wenn ich das irgendwann mal verstehe geb' ich einen aus!

Der Subskript Operator ist der Array Operator []. Eine Klasse kann den überladen, damit man damit auch eine Klasse wie ein Array ansprechen kann.

Die IpAddress Klasse macht das:

// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address.bytes[index]; };
uint8_t& operator[](int index) { return _address.bytes[index]; };

Die erste Zeile ist für ein const Objekt. Entsprechend wird ein Wert statt eine Referenz zurückgegeben und man kann den Wert nicht ändern. Der Compiler bringt dann einen Fehler. Die zweite Zeile ist die normale Variante. Dabei wird eine Referenz zurückgegeben und man kann den Wert ändern

Dann kann man das machen

IPAddress ip(192,168, 0, 0);
ip[3] = 100;

Ah jetzt ja - wenn ich's so erklärt bekomme leuchtet es mir ein. Aber ich bin weit davon entfernt, da selbst drauf zu kommen.

Aber ich arbeite dran!

Danke Dir