Warum flasht du nicht einfach , sobald einer defekt ist? Es gibt auch die Möglichkeit, die IP Adresse von der SD Karte zu lesen. Gibt eine Beispiele mit Hilfe von Google dazu.
Dann stell 192.168.178. fest, und stelle die letzten 3 stellen mit einem 8Bit-Schalter ein. Gehen dir aber 8Ports für flöten. Diesen fragst du dann im setup ab.
Alternativ musste mit USB dran und über Seriellen Monitor Parameter schicken, die der Arduino dann im EEPROM schieben soll. Dann holt er sich bei jedem Restart die Einstellungswerte aus dem Eeprom.
Fest wird immer ins EEPROM geschrieben. Beispiele habe ich keine. Gibt aber genügend Sketche in der Arduino IDE und im Playground. Ansonsten behandelt fast jedes Arduino Buch dieses Thema.
Sketch nicht vollständig. Habe den Ethernet Teil rausgehalten. Das System sollte nun klar sein mit dem Eeprom.
Du fragst am besten dann in der setup() ab, ob IP geändert werden soll. Sprich mit PC dran und Serial Monitor.
Werte werden ins Eeprom an die Stellen geschriebne. Nun fehlt dir dann noch das auslesen in der setup vor der setIP Abfrage. Wenn du setIP ausführst., würdest du die alten Werte überschreiben.
Alle nötigen Infos sind bereits in der IDE hinterlegt unter Beispiele EEPROM
#include <EEPROM.h>
const int NUMBER_OF_FIELDS = 4; // Wie viele kommaseparierte Felder erwarten wir?
int fieldIndex = 0; // Das aktuell empfangene Feld
int values[NUMBER_OF_FIELDS]; // Array mit den Werte aller Felder
void setup()
{
Serial.begin(9600); // Serieller Port sendet und empfaengt mit 9600 Baud
}
void setIP() {
Serial.println("IP Einstellung, neue IP bitte wie folgt eingeben und mit Enter bestaetigen");
Serial.println("192.168.178.100");
if( Serial.available()) {
for(fieldIndex = 0; fieldIndex < NUMBER_OF_FIELDS; fieldIndex ++)
{
values[fieldIndex] = Serial.parseInt(); // Numerischen Wert einlesen
}
Serial.print( fieldIndex);
Serial.println(" Felder empfangen:");
for(int i=0; i < fieldIndex; i++)
{
EEPROM.write(values[i],i);
}
fieldIndex = 0; // und von vorn anfangen
Serial.println("Neue IP Adresse :");
Serial.print(values[0]);Serial.print("."); Serial.print(values[1]);Serial.print("."); Serial.print(values[2]);Serial.print("."); Serial.println(values[3]);
}
}
void loop()
{
}
Garnicht! Ich hab nur die Funktion erstellt. Würde es splitten! die ersten Textausgaben in setup. Im loop immer wieder nach
if(Serial.available() > 0 && newVar == false) { ...] abfragen.
Die newVar sollte eine statische/globale Variable sein, die gesetzt wird, sobald die Daten geändert wurden, damit der aufruf nicht erneut kommt.
Problem:
gebe ist als erstes Getip 192.168.178.123
ein. Sagt er mit Ihre ip ist 0.0.0.0
das ist ja soweit richtig.
Nun gebe ich Setip 192.168.178.123 ein
Ihre neue ip ist 192.168.178.123
auch richtig.
ABER gebe ich nun wieder Getip 192.168.178.123 ein
kommt als Antwort: Ihre ip ist 0.168.178.123
wieso wird ip1 eine 0 ?
und kann ich nach Getip abbrechen? muss nun immer alle 22 stellen ausfüllen. würde es gerne so haben das er nur Getip einlesen braucht und gleich reinspringt
Du hast einen Puffer-Überlauf programmiert:
MPresponse[22] = '\0';
Ein Array der Größe 22 geht von 0 bis 21. Wenn du auf auf den Index 22 zugreifst, überschreibst du dir ip1, da der Speicher direkt hintereinander belegt wird.
Das ist kürzer, übersichtlicher und weniger fehleranfälllig. Den Offset gibt du als Addition zu MPresponse an. z.B. atoi(MPresponse + 4) für das 2. Oktett. MPresponse selbst entspricht dabei +0. Aber du kannst nicht die eckigen Klammern verwenden da die Funktion einen Zeiger als Parameter will. Man kann jedoch einfach einen festen Wert auf den Variablen-Namen addieren, da Arrays Zeiger auf das erste Element sind.
2.)
Für das Vergleichen von Teil-Strings gibt es strncmp(): http://www.cplusplus.com/reference/cstring/strncmp/
Da gibst du nur einen Vergleichs-Strings an und die Anzahl der Zeichen die verglichen werden sollen. Die Funktion liefert bei Gleichheit 0 zurück.
Wichtig ist hier die "n" Version zu verwenden, da das normale strcmp() den kompletten String vergleicht.
Baue deine Einlese-Routine um. Statt auf die Anzahl der Zeichen abzufragen, stellst du den Serial-Monitor so ein, dass er am Ende ein Linefeed/Newline sendet (links von der Baudrate). Auf das fragst du dann ab:
Du hast bisher deine Auslese-Sachen in loop(). Das ist jetzt alles in der Funktion checkSerial(). Die Funktion wird immer wieder aufgerufen und gibt solange false zurück bis das Linefeed kommt. Der Teil, den du machst wenn die Eingabe fertig eingelesen ist kommt dann innerhalb der geschweiften Klammern.
Falls, das klarer ist. Das ist die Kurzversion von dem hier:
Das kompiliert nicht, weil öffnende Klammern fehlen. und der Funktionsanfang.
macht also gar nichts.
Eine Funktion, die als
bool func()
deklariert ist, muss vereinbarungsgemäss einen bool (oder boolean) Wert zurückliefern.
Das kann auch vor dem Ende der Funktion passieren. Spart also evtl. if - else Ebenen.
/// bool checkSerial ()
// liest Serial und liefert true zurück, wenn eine Eingabe,
// die im globalen char SerialBuffer[] gesammelt wurde,
// vollständig ist
bool checkSerial()
{
if (Serial.available() )
{
zeichenLesen();
if (allesAngekommen()) return true;
}
return false;
}