Ethernet-Code funktioniert nur mit Mega, nicht mit Duemilanove

Hallo,

ich habe einige Zeit lang an einem Server rumgebastelt und nach einiger Zeit funktionierte er so wie ich es wollte...auf dem Arduino Mega.

Als ich dann den Code auf mein Arduino Duemilanove geladen habe, habe ich festgestellt, dass es nicht so funktioniert wie auf dem Mega.
Es fängt schon damit an, dass ich den Server nicht einmal erreiche!

Nun hoffe ich dass mir jemand von euch helfen kann, der Code ist im Anhang.

Danke schon mal im Vorraus

Server.ino (10.1 KB)

Ach ja, so sieht der Serial-Monitor beim Starten des Servers aus:

Initializing Ethernet-Server...
ERROR! - Failed to obtain IP-Address from DHCP-Server.
Initializing Ethernet-Server manually...
SUCCESS! - Ethernet-Server online at
m
Initializing SD-Card...
SUCCESS! - SD-Card initialized.
Searching
¢¨ÊÐ Ç?

Spuckt Dein Debug-Code über Serial Meldungen aus?

Nutzt du denn die gleiche Ethernet-Hardware? Wenn nicht, mußt du doch die MAC-Adresse anpassen, oder?
Immerhin ist das ja der Punkt wo er aussteigt.

ArduPros:
ich habe einige Zeit lang an einem Server rumgebastelt und nach einiger Zeit funktionierte er so wie ich es wollte...auf dem Arduino Mega.

Als ich dann den Code auf mein Arduino Duemilanove geladen habe, habe ich festgestellt, dass es nicht so funktioniert wie auf dem Mega.
Es fängt schon damit an, dass ich den Server nicht einmal erreiche!

Ein Duemilanove hat nur einen Bruchteil des RAM-Speichers eines MEGA.

Und wenn ich sowas sehe:

      Serial.println("ERROR! - Failed to obtain IP-Address from DHCP-Server.");
      Serial.println("Initializing Ethernet-Server manually...");  
        Ethernet.begin(mac, ip);
        Serial.println("SUCCESS! - Ethernet-Server online at 192.168.2.133" );

dann brauche ich gar nicht weitersuchen. Zu 99,99% geht dem speicherschwachen Board der RAM-Speicher aus, wenn Du so schweinemäßig RAM verbrauchst!

Spare wenigstens mal den RAM-Speicher ein, den die konstanten Strings verbrauchen, indem Du die Serial-Ausgaben ALLER Textkonstanten auf das F-Makro umschreibst!

Also statt (braucht haufenweise RAM):

      Serial.println("ERROR! - Failed to obtain IP-Address from DHCP-Server.");

Setze (spart ne Menge RAM):

      Serial.println(F("ERROR! - Failed to obtain IP-Address from DHCP-Server."));

P.S.: Dass zwei verschiedene Geräte in einem Netzwerk nie (NIE!) gleichzeitig dieselbe MAC-Adresse erhalten dürfen, ist hoffentlich klar und von Dir berücksichtigt worden?!

Ich glaube langsam auch, dass es am Speicherunterschied liegt. Wie kann ich denn noch RAM einsparen, außer die Serial-Ausgaben umzuschreiben bzw. wegzulassen?

Und außerdem benutze ich das gleiche Ethernet-Shield und wechsle das nur zwischen den Boards, dann muss ich die MAC-Addresse doch nicht ändern.

ArduPros:
Ich glaube langsam auch, dass es am Speicherunterschied liegt. Wie kann ich denn noch RAM einsparen, außer die Serial-Ausgaben umzuschreiben bzw. wegzulassen?

Die kannst nirgends so viel und so einfach RAM auf einen Schlag einsparen wie mit dem Umschreiben aller print und println Anweisungen für die Ausgabe von reinen Textkonstanten auf die Verwendung des F-Makros.

Die nächste Massnahme wäre dann, alle "String" Objekte aus dem Programm rauszuschmeißen und in geeigneter Weise durch C-Strings/Char-Arrays zu ersetzen. Dazu muss einiges an Programmlogik umgeschrieben werden, da Du mehrfach String-Objekte verwendest:

String msg
String erg;
String data;
String pw
String par

Letzteres String Objekt ("par") wird offenbar innerhalb derselben Funktion mehrfach re-deklariert.
Keine Ahnung, was das für Auswirkungen auf den Speicherverbrauch hat.

BTW: String-Objekte sind in allen Arduino Versionen vor v1.0.5 fehlerhaft implementiert. Also String-Objekte nicht mit den Versionen 1.0.1, 1.0.2, 1.0.3 oder 1.0.4 verwenden, sondern wenn überhaupt notfalls erforderlich dann nur mit Version 1.0.5 (oder vielleicht zukünftigen Versionen), sonst drohen selbst bei fehlerfreien Programmen extreme Programm-Fehlfunktionen!

Der Gebrauch von String-Objekten ist das zweite große Ding an RAM-Speicherverschwendung, das Du bei Dir in den Sketch eingebaut hast. Aber im Gegensatz zu den F-Makros, die man bei print() und println() leicht nachträglich reinschieben kann, ist das Umschreiben auf char-Arrays mit mehr Aufwand verbunden, um RAM-Speicher zu sparen.

Wieviel RAM-Speicher jeweils noch frei ist, kannst Du Dir mit der Funktion freeRam anzeigen lassen, wenn Du die mal gelegentlich irgendwo in Deinem Sketch aufrufst und Dir das Ergebnis über Serial ausgeben läßt.

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Okay, danke für die schnelle Hilfe, dann werde ich da wohl ein bisschen rumbasteln müssen :wink:

ArduPros:
Okay, danke für die schnelle Hilfe, dann werde ich da wohl ein bisschen rumbasteln müssen :wink:

Ich glaube, Du bleibst mal lieber beim MEGA-Board.

Der von Dir gepostete Sketch kompiliert mit Arduino 1.0.5 ja bereits zu einer grenzwertigen Größe für ein UNO-Board, so dass er mit einem Bootloader gar nicht mehr auf einen Atmega328 draufpasst, sondern nur wenn man den Bootloader wegläßt und den Sketch mit einem Programmer hochlädt.

Durch den RAM-speichersparenden Gebrauch von F-Makros wird dann allerdings der Sketch so groß, dass er dann gar nicht mehr draufpasst. Die F-Makros sparen zwar eine Menge RAM-Speicher, aber sie erzeugen auch etwas zusätzlichen Code, so dass im Gegenzug mehr Flash-Programmspeicher benötigt wird als ohne die F-Makros.

Bei umfangreichen Sketchen die SD und Ethernet gleichzeitig verwenden und dann nur auf einem Atmega328 laufen sollen, wäre es eigentlich besser gewesen, von Anfang an ein speichersparendes Konzept zu entwickeln und speichersparend zu programmieren, als erst das Kind in den Brunnen fallen zu lassen und es dann mit irgendwelchen fliegenden Konstruktionen nachträglich noch auffangen zu wollen.