Wie kann ich meinen Code vereinfachen?

Ne nicht direkt.

Aber mein Problem ist das ich wenn ich meinen Dateinamen gegen eine Varible (sting) autauschen möchte die Anzeige bekomme das nur eine Char-Array passt. Die bekomme ich aber noch nicht mit passendem Inhalt befüllt auf aufgerufen.

Sven

SvenM:
Aber mein Problem ist das ich wenn ich meinen Dateinamen gegen eine Varible (sting) autauschen möchte die Anzeige bekomme das nur eine Char-Array passt.

Den Datentyp "String" als Objekt vergisst Du am besten ganz schnell. Für die Programmierung von Mikrocontrolllern völlig ungeeignet. Am besten nur char-Arrrays verwenden.

SvenM:
Die bekomme ich aber noch nicht mit passendem Inhalt befüllt auf aufgerufen.

???

An ein char-Array kannst Du mit der Funktion strcpy einen anderen String zuweisen. Und wenn Du einen char-Pointer als Variable einer Funktion deklarierst, kannst Du auch Konstanten als Parameter übergeben, und Funktionen aufrufen mit:
printMyFile("Datei.txt");

Wobei die Deklaration des Funktionsrumpfes dann lauten würde:

void printMyFile(char* fn)
{
// hier der auszuführende Code der Funktion
}

Ich probiere es grade.

Wie kann ich denn auf diese Client aufrufe aus dem Ethentaufruf im loop zurückgreifen?

EthernetClient client = server.available();
if (client) {.....

Die hat er ja in der neuen Funktion nicht mehr.

Hmmm.

Jetzt bekomme ich nur noch Müll in meinem seriellen Monitor.

Starting SD..Starting SD..

Kann es daher kommen das ich den Ethernetserver 2 mal starte?
Irgendwie habe ich mit dem zusammenspiel von Ethernet und SD-Karte
klärungsbedarf.

Der aktuelle Code:

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x65, 0x3A };
byte ip[] = { 192, 168, 1, 2 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

EthernetServer server(80); //server port

String readString;

long Sperrzeit = 1200000; // 20min = 1 200 000
long Abschaltzeit = 1500000; // 25min = 1 500 000
long LetzteZeitSperr; // Sperrzeit bei Falscher Antwort
long LetzteZeitAus; // Zeit um Aus Automatisch

int Fragencounter = 0; // Zähler aktuelle Frage
int AusPin = 5; // Pin mit Relais Aus
int StatusAusPin = LOW; // Statusspeicher des Relais für AUS
int Filenummer = 0; // Auswahlnummer zur Dateiöffnung
int StatusFalscheFrage = LOW; // Frage Falsch = Sperrzeit abwarten

//////////////////////

void setup(){

Serial.begin(9600);

pinMode(10,OUTPUT); // disable w5100 while setting up SD
digitalWrite(10,HIGH);
Serial.print("Starting SD..");
if(!SD.begin(4)) Serial.println("failed");
else Serial.println("ok");

Ethernet.begin(mac, ip, gateway, subnet);
digitalWrite(10,HIGH);

server.begin();
Serial.println("Ready");
}

void loop(){
// ------------------------------------------------------------------------- Abschaltzeit
if (millis() - LetzteZeitAus > LetzteZeitAus) {
StatusAusPin = false; }
else {
StatusAusPin = true;
digitalWrite(AusPin, StatusAusPin);
}

// ------------------------------------------------------------------------- Sperrzeit falsche Frage
if (StatusFalscheFrage = HIGH) {
if (millis() - LetzteZeitSperr > Sperrzeit) {
StatusFalscheFrage = HIGH; }
else {
StatusFalscheFrage = LOW;
}
}

// ------------------------------------------------------------------------- Create a client connection
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();

if (readString.length() < 100) { //read char by char HTTP request
readString += c; //store characters to string
}
if (c == '\n') { //if HTTP request has ended
LetzteZeitAus = millis();
Serial.println(readString); //print to serial monitor for debuging
client.stop();

// ------------------------------------------------------------------------- Programmstand erkennen
Filenummer = 0;
if(readString.indexOf("Joker=Joker+einl") > -1) { // ----- Joker einlösen
if(readString.indexOf("Code=36811") > -1) { //// --- Code Frage 2
Serial.println("Code Frage 2 erkannt");
Fragencounter = 2;
printMyFile("0102fr.txt");..........................................................

.......................................... }
else if(Fragencounter >> 1 && readString.indexOf("Antw=") > -1) { // ----- Frage 1
Serial.println("Antwort Frage erkannt");
if (readString.indexOf("Antw=B") > -1) { //// --- Richtig
Serial.println("Richtig"); }
else {
Serial.println("Falsch");
}
}
else { // ----- Nichts erkannt - neuladen
Serial.println("Keine Anfrage erkannt - neuladen");
}
}
}
}
}
}

// ------------------------------------------------------------------------- Client ausgeben

void printMyFile(char* filename) {
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
client.println("HTTP/1.1 200 OK"); //send new page
client.println("Content-Type: text/html");
client.println();
File myFile = SD.open(filename);
if (myFile) {
while (myFile.available()) {
client.write(myFile.read());
}
myFile.close();
}
delay(1);
//stopping client
client.stop();

}
}
}
}

Wer kann und will mir helfen?

:wink:

Edit:
Wäre es vielleicht eine Lösung "Client" an die neue Funktion zu übergeben?
Damit könnte ich den 2. EthernetClient aufruf sparen.
Wie kann das bewerkstelligt werden?

Sven

SvenM:
Kann es daher kommen das ich den Ethernetserver 2 mal starte?

Ja, Du deklarierst zweimal die Variable mit dem Namen client, und zwar mit unterschiedlichem Gültigkeitsbereich: Einmal in der Funktion "loop" und einmal in der Funktion "printMyFile".

Mache Dir klar, was das bedeutet:

EthernetClient client = server.available();

Das sind eigentlich zwei Programmzeilen zusammengefasst, und zwar eine Variablendeklaration:
EthernetClient client; // Deklarieren den Namen "client" vom Typ "EthernetClient" (was ein Objekttyp aus einer Library ist).
und einer Zuweisung:
client = server.available();
wobei "server" ebenfalls ein Objekt aus einer Library ist (Typ EthernetServer), das ganz oben in Deinem Programmcode deklariert ist.

Am besten machst Du Dir mal Gedanken über den GÜLTIGKEITSBEREICH von deklarierten Namen:

  • Deklaration innerhalb einer Funktion ==> Gültig nur innerhalb der Funktion ("lokale Variable")
  • Deklaration außerhalb einer Funktion ==> Gültig im ganzen Programm ("globale Variable")

Du hast nun zwei Möglichkeiten, den Client in der Funktion verfügbar zu machen: Entweder erweiterst Du die Parameterliste der selbstgeschriebenen Funktion (in der bisher nur der String als Dateiname übergeben wird) um einen weiteren Paramter passenden Typs, um den "client" ebenfalls als Parameter zu übergeben.

Oder Du machst mit "client" das, was auch mit "server" der Fall ist: Eine "globale Variable" deklarieren statt einer lokalen Variablen, die nur in "loop" gültig ist.

Also deklarierst Du oben im Code (außerhalb von Funktionen!) sowohl "server" als auch "client" als globale Variablen:
(Oberhalb/außerhalb der loop und anderen Funktionen, globale Variablen):
EthernetServer server(80); //server port
EthernetClient client;

Und dann stehen sowohl die Variablen "client" als auch "server" im ganzen Programm zur Verfügung, einschließlich Deinen selbstgeschriebenen Funktionen, ohne dass eine Übergabe als Parameter notwendig ist.

Die bisherige Deklaration an der Stelle in der loop muss dann dort natürlich verschwinden (sonst hättest Du wieder eine doppelte Deklaration), aus der bisherigen "Deklaration mit Zuweisung" in der Loop wird einfach nur eine Zuweisung:
(In der loop) aus:
EthernetClient client = server.available(); // Deklaration und Zuweisung
wird:
client = server.available(); // Zuweisung

Und in Deiner selbstgeschriebenen Funktionen natürlich genau dasselbe.
So ungefähr. Dann hast Du am jeweils eine "globale" Deklaration für "server" und für "client" (Deklaration "oben" im Programm und außerhalb von allen Funktionen) und kannst diese in jeder Funktion Deines Programms verwenden, ohne sie per Funktionsparameter übergeben zu müssen.

Einen Schritt weiter, aaber....

Jetzt kommt das Problem mit der SD-Karte zum tragen.

Leider initialisiert sich der SD-Kartenleser nicht mehr korrekt.

Im seriellen Monitor erscheint nur noch:

Starting SD..

Die Funktion habe ich nun so programiert und es erscheint auch keine Fehlermeldung.

Ein Auszug:

void setup(){

Serial.begin(9600);

pinMode(10,OUTPUT); // disable w5100 while setting up SD
digitalWrite(10,HIGH);
Serial.print("Starting SD..");
if(!SD.begin(4)) Serial.println("failed");
else Serial.println("ok");

Ethernet.begin(mac, ip, gateway, subnet);
digitalWrite(10,HIGH);
delay(2);
server.begin();
Serial.println("Ready");

}

EthernetClient client;

void loop(){

// ------------------------------------------------------------------------- Create a client connection
client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();

if (readString.length() < 100) { //read char by char HTTP request
readString += c; //store characters to string
}
if (c == '\n') { //if HTTP request has ended
LetzteZeitAus = millis();
Serial.println(readString); //print to serial monitor for debuging

if(readString.indexOf("Joker=Joker+einl") > -1) { // ----- Joker einlösen
if(readString.indexOf("Code=36811") > -1) { //// --- Code Frage 2
Serial.println("Code Frage 2 erkannt");
Fragencounter = 2;
printMyFile("0102fr.txt");
}....................

.............client.stop();
}
}
}
}
}

// ------------------------------------------------------------------------- Client ausgeben

void printMyFile(char* filename) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
File myFile = SD.open(filename);
if (myFile) {
while (myFile.available()) {
client.write(myFile.read());
}
myFile.close();
}
delay(1);
}

So sieht es jetzt aus. Wo könnte noch ein Fehler liegen?

Grüße
Sven

 Serial.print("Starting SD..");
  if(!SD.begin(4)) Serial.println("failed");
  else Serial.println("ok");

Wenn nach "Starting SD.." deine Ausgabe weder "failed" noch "ok" ist,
...hast du eventuell nicht genug RAM frei und SD.begin() zerschiesst die eigene Rücksprungadresse auf dem Stack.

Kommt denn wenigstens "..failed", wenn gar keine Karte steckt ?

Aktuell ist es so das sich bei gesteckter Karte das "Starting SD" komplett verhackt im Monitor todläuft.

Bei nicht gesteckter Karte Erscheint im 1 Sekunden rythmus "Starting SD..Starting SD..Starting SD...usw...."

Keine Ahnung ob es zur sache beiträgt, aber die Sketchgröße beträgt aktuell ca. 25.000 Bytes.

Grüße
Sven

SvenM:
Wo könnte noch ein Fehler liegen?

Hast Du jetzt noch andere Erweiterungen in den Sketch eingebaut?

Wenn nicht, sollte das Programm einerseits durch die Verwendung von Funktionen kleiner werden, andererseits steigt der Speicherbedarf im RAM auf dem Stack an, weil da Rücksprungadresse und Parameter im RAM abgelegt werden beim Funktionsaufruf. Wenn der Speicher schon vorher bis zum Anschlag ausgereizt war, können die vier Bytes für den Stack natürlich der Tropfen sein, der das Fass zum Überlaufen bringt.

Andererseits könnte es sein, dass die Initialisierung nur scheinbar nicht läuft, weil das Programm nach dem Serial.println weiterläuft und es auch dann abstürzen kann, bevor die Zeichen über die serielle Schnittstelle eintrudeln. Die serielle Schnittstelle ist nämlich lahm. Probiere mal ein delay hinter der Karteninitialisierung:

Serial.print("Starting SD..");
if(!SD.begin(4)) Serial.println("failed");
else Serial.println("ok");
delay(3000);

Macht das einen Unterschied und Du siehst entweder "failed" oder "ok"?

So ich bastele munter weiter...

Aber irgendwie reicht es noch nicht zum Durchbruch.

Das zeigt mein Monitor mit delay auf 3000 nach einem Reset:

StartinktktaStartikt´WÉÑ¥­ÑÑStarti11StStartinkSk2ºWÉÑ¥­M2tStartik1tk2StartinStktWÉÑ¥¹­Ñ­ÑMÑ?ÉÑ¥¹­Ñ­ÉºWÉÑ¥ÅSa2tStartikStktStartinSt11StartinkS

Aktueller Programmstand komplett:

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x65, 0x3A };
byte ip[] = { 192, 168, 1, 2 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

EthernetServer server(80); //server port

String readString;

long Sperrzeit = 1200000; // 20min = 1 200 000
long Abschaltzeit = 1500000; // 25min = 1 500 000
long LetzteZeitSperr; // Sperrzeit bei Falscher Antwort
long LetzteZeitAus; // Zeit um Aus Automatisch

int Fragencounter = 0; // Zähler aktuelle Frage
int AusPin = 5; // Pin mit Relais Aus
int StatusAusPin = LOW; // Statusspeicher des Relais für AUS
int StatusFalscheFrage = LOW; // Frage Falsch = Sperrzeit abwarten

void setup(){

Serial.begin(9600);

pinMode(10,OUTPUT);
digitalWrite(10,HIGH);
Serial.print("Starting SD..");
if(!SD.begin(4)) Serial.println("Fehler");
else Serial.println("Ok");
delay(2000);

Ethernet.begin(mac, ip, gateway, subnet);
digitalWrite(10,HIGH);

server.begin();
Serial.println("Server Ready");
delay(2000);
}

EthernetClient client;

void loop(){
// ------------------------------------------------------------------------- Abschaltzeit
if (millis() - LetzteZeitAus > LetzteZeitAus) {
StatusAusPin = false; }
else {
StatusAusPin = true;
digitalWrite(AusPin, StatusAusPin);
}

// ------------------------------------------------------------------------- Sperrzeit falsche Frage
if (StatusFalscheFrage = HIGH) {
if (millis() - LetzteZeitSperr > Sperrzeit) {
StatusFalscheFrage = HIGH; }
else {
StatusFalscheFrage = LOW;
}
}

// ------------------------------------------------------------------------- Create a client connection
client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();

if (readString.length() < 100) { //read char by char HTTP request
readString += c; //store characters to string
}
if (c == '\n') { //if HTTP request has ended
LetzteZeitAus = millis();
Serial.println(readString); //print to serial monitor for debuging
client.stop();

// ------------------------------------------------------------------------- Programmstand erkennen
if(readString.indexOf("Joker=Joker+einl") > -1) { // ----- Joker einlösen
if(readString.indexOf("Code=36811") > -1) { //// --- Code Frage 2
Serial.println("Code Frage 2 erkannt");
Fragencounter = 2;
printMyFile("0102fr.txt");
}
else if (readString.indexOf("Code=63026") > -1) { //// --- Code Frage 3
Serial.println("Code Frage 3 erkannt");
Fragencounter = 3;
printMyFile("0103fr.txt");
}
else if (readString.indexOf("Code=98222") > -1) { //// --- Code Frage 4
Serial.println("Code Frage 4 erkannt");
Fragencounter = 4;
printMyFile("0104fr.txt");
}
else if (readString.indexOf("Code=23284") > -1) { //// --- Code Frage 5
Serial.println("Code Frage 5 erkannt");
Fragencounter = 5;
printMyFile("0105fr.txt");
}
else if (readString.indexOf("Code=88168") > -1) { //// --- Code Frage 6
Serial.println("Code Frage 6 erkannt");
Fragencounter = 6;
printMyFile("0106fr.txt");
}
else if (readString.indexOf("Code=47022") > -1) { //// --- Code Frage 7
Serial.println("Code Frage 7 erkannt");
Fragencounter = 7;
printMyFile("0107fr.txt");
}
else if (readString.indexOf("Code=20692") > -1) { //// --- Code Frage 8
Serial.println("Code Frage 8 erkannt");
Fragencounter = 8;
printMyFile("0108fr.txt");
}
else if (readString.indexOf("Code=80692") > -1) { //// --- Code Frage 9
Serial.println("Code Frage 9 erkannt");
Fragencounter = 9;
printMyFile("0109fr.txt");
}
else if (readString.indexOf("Code=39762") > -1) { //// --- Code Frage 10
Serial.println("Code Frage 10 erkannt");
Fragencounter = 10;
printMyFile("0110fr.txt");
}
else if (readString.indexOf("Code=46047") > -1) { //// --- Code Frage 11
Serial.println("Code Frage 11 erkannt");
Fragencounter = 11;
printMyFile("0111fr.txt");
}
else if (readString.indexOf("Code=97346") > -1) { //// --- Code Frage 12
Serial.println("Code Frage 12 erkannt");
Fragencounter = 12;
printMyFile("0112fr.txt");
}
else if (readString.indexOf("Code=68095") > -1) { //// --- Code Frage 13
Serial.println("Code Frage 13 erkannt");
Fragencounter = 13;
printMyFile("0113fr.txt");
}
else if (readString.indexOf("Code=92060") > -1) { //// --- Code Frage 14
Serial.println("Code Frage 14 erkannt");
Fragencounter = 14;
printMyFile("0114fr.txt");
}
else if (readString.indexOf("Code=05860") > -1) { //// --- Code Frage 15
Serial.println("Code Frage 15 erkannt");
Fragencounter = 15;
printMyFile("0115fr.txt");
}
else if (readString.indexOf("Code=") > -1) { //// --- Kein Code eingegeben
Serial.println("Kein Code eingegeben");
Fragencounter = 0;
printMyFile("startp.txt");
}
}
else if(readString.indexOf("Neu=Neues+Spiel") > -1) { // ----- Neues Spiel
Serial.println("Neues Spiel starten erkannt und Zeit abfragen");
if (StatusFalscheFrage == HIGH) {
Serial.println("Neustart gesperrt");
printMyFile("zsperr.txt");
}
else if (StatusFalscheFrage == LOW) {
Serial.println("Neustart frei");
Fragencounter = 1;
printMyFile("0101fr.txt");
}
}
else if(Fragencounter >> 1 && readString.indexOf("Antw=") > -1) { // ----- Frage 1
Serial.println("Antwort Frage erkannt");
if (readString.indexOf("Antw=B") > -1) { //// --- Richtig
Serial.println("Richtig"); }
else {
Serial.println("Falsch");
}
}
else { // ----- Nichts erkannt - neuladen
Serial.println("Keine Anfrage erkannt - neuladen");
}
}
client.stop();
readString="";
}
}
}
}

// ------------------------------------------------------------------------- Client ausgeben

void printMyFile(char* filename) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
File myFile = SD.open(filename);
if (myFile) {
while (myFile.available()) {
client.write(myFile.read());
}
myFile.close();
}
delay(1000);
}

Jooo.....

G
Sven

Wenn ich so drüber nachdenke beduetet das doch das der Pin 4 HIGH wird und wieder abfällt. Aus keinem anderen Grund würde sonst die Initialisierung neu starten. Oder?

SvenM:
Das zeigt mein Monitor mit delay:

Startinktkta

Das sieht für mich verdächtig danach aus, als wenn der RAM-Speicher Deines Controllers zu klein ist, bzw. Du mit Deinem Sketch zu viel RAM-Speicher verwendest, so dass da schon beim Programmstart Variablenbereiche überschrieben werden. Denn sonst sollten wenigstens mit dem eingebrachten delay die Initialisierungstexte der setup-Funktion soweit einwandfrei im Serial Monitor rüberkommen.

Ja das scheint es zu sein.... :frowning:

Ich habe soeben einige Serial-Ausgaben gestrichen und dann kommt die Meldung der SD Karte wie gewohnt....

Aber der Server-Ready kommt nicht. Kann das auch am Speicher hängen?
Oh, jetzt kommt es. Mit etwas zeitlicher Verzögerung. Aber das Board reagiert nicht auf meine Anfragen...

Was würde Arbeitsspeicher sparen?

Grüße
Sven

SvenM:
Was würde Arbeitsspeicher sparen?

Es würde z.B. Arbeitsspeicher sparen, wenn Du
a) Texte einsparst
b) Texte in den PROGMEM Speicher verschiebst

Einsparen kannst Du z.B. bei immer wieder in leicher Variation auftretenden Texten wie z.B.
"Code Frage 15 erkannt"
indem Du eine Funktion schreibst, die den Text und die jeweils andere Zahl ausgibt. Dann müssen nicht jedesmal eine leicht unterschiedliche Variante des Textes gespeichert werden.

Verstehe.

Die seriellen Ausgaben werden am Ende überhaupt nicht mehr gebraucht. Also können diese relativ schnell entfallen.

Würde es etwas bringen wenn in die Dateinamen in der funktionsübergabe in den Progmem Speicher verlege?
Und falls ja, wir rufe ich die dann ab und übergebe sie an meine Funktion. Das Abspeichern dort sollte ich noch hinbekommen.

Da war doch etwas mit pointer.

Das Speichern sollte auf diesem Wag klappen? oder?

prog_uchar F1[] PROGMEM = {"startp.txt"};

Der Funktionsaufruf dann so?

printMyFile(F1);

Könnte ich es auch in ein mehrdimensionales array packen?

Grüße
Sven

Mal wieder einen kleinen zwischenstand.

Also der Server läuft wieder. Schon mal toll. Die Anfragen kommen rein.
Werden aber noch nicht abgearbeitet bzw. zugeordnet.

Ich habe versucht die eben angesprochene verlagerung in Flash umzusetzen. Aber ich habe keine wirkliche
Einsparung hinbekommen (50Bytes).

Welche Art des Aufrufs ist die richtig für mich? Siehe anhang.
Ich meine im besonderen die übergabe des Dateinamens an meine funktion und den auszuwertenden "Code"
an meine IF abfrage.

Grüße
Sven

#include <SPI.h>
#include <SD.h>
#include <Ethernet.h>
#include <avr/pgmspace.h>

prog_char F1[] PROGMEM = {"startp.txt"};
prog_char F2[] PROGMEM = {"zsperr.txt"};
prog_char F3[] PROGMEM = {"0101fr.txt"};
prog_char F4[] PROGMEM = {""};
prog_char F5[] PROGMEM = {""};
prog_char F6[] PROGMEM = {"0102fr.txt"};
prog_char F7[] PROGMEM = {""};
prog_char F8[] PROGMEM = {""};
prog_char F9[] PROGMEM = {"0103fr.txt"};
prog_char F10[] PROGMEM = {""};
prog_char F11[] PROGMEM = {""};
prog_char F12[] PROGMEM = {"0104fr.txt"};
prog_char F13[] PROGMEM = {""};
prog_char F14[] PROGMEM = {""};
prog_char F15[] PROGMEM = {"0105fr.txt"};
prog_char F16[] PROGMEM = {""};
prog_char F17[] PROGMEM = {""};
prog_char F18[] PROGMEM = {"0106fr.txt"};
prog_char F19[] PROGMEM = {""};
prog_char F20[] PROGMEM = {""};
prog_char F21[] PROGMEM = {"0107fr.txt"};
prog_char F22[] PROGMEM = {""};
prog_char F23[] PROGMEM = {""};
prog_char F24[] PROGMEM = {"0108fr.txt"};
prog_char F25[] PROGMEM = {""};
prog_char F26[] PROGMEM = {""};
prog_char F27[] PROGMEM = {"0109fr.txt"};
prog_char F28[] PROGMEM = {""};
prog_char F29[] PROGMEM = {""};
prog_char F30[] PROGMEM = {"0110fr.txt"};
prog_char F31[] PROGMEM = {""};
prog_char F32[] PROGMEM = {""};
prog_char F33[] PROGMEM = {"0111fr.txt"};
prog_char F34[] PROGMEM = {""};
prog_char F35[] PROGMEM = {""};
prog_char F36[] PROGMEM = {"0112fr.txt"};
prog_char F37[] PROGMEM = {""};
prog_char F38[] PROGMEM = {""};
prog_char F39[] PROGMEM = {"0113fr.txt"};
prog_char F40[] PROGMEM = {""};
prog_char F41[] PROGMEM = {""};
prog_char F42[] PROGMEM = {"0114fr.txt"};
prog_char F43[] PROGMEM = {""};
prog_char F44[] PROGMEM = {""};
prog_char F45[] PROGMEM = {"0115fr.txt"};
prog_char F46[] PROGMEM = {""};
prog_char F47[] PROGMEM = {""};
prog_char F48[] PROGMEM = {"spende.txt"};

PROGMEM const char *Quest_table[] =
{
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,
F11, F12, F13, F14, F15, F16, F17, F18, F19, F20,
F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
F31, F32, F33, F34, F35, F36, F37, F38, F39, F40,
F41, F42, F43, F44, F45, F46, F47, F48
};

prog_char J2[] PROGMEM = {"Code=36811"};
prog_char J3[] PROGMEM = {"Code=63026"};
prog_char J4[] PROGMEM = {"Code=98222"};
prog_char J5[] PROGMEM = {"Code=23284"};
prog_char J6[] PROGMEM = {"Code=88168"};
prog_char J7[] PROGMEM = {"Code=47022"};
prog_char J8[] PROGMEM = {"Code=20692"};
prog_char J9[] PROGMEM = {"Code=80692"};
prog_char J10[] PROGMEM = {"Code=39762"};
prog_char J11[] PROGMEM = {"Code=46047"};
prog_char J12[] PROGMEM = {"Code=97346"};
prog_char J13[] PROGMEM = {"Code=68095"};
prog_char J14[] PROGMEM = {"Code=92060"};
prog_char J15[] PROGMEM = {"Code=05860"};

PROGMEM const char *Joker_table[] =
{
J2, J3, J4, J5,
J6, J7, J8, J9, J10,
J11, J12, J13, J14, J15,
};

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x65, 0x3A };
byte ip[] = { 192, 168, 1, 2 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

char JokerBuffer[11];
char FileBuffer [11];

EthernetServer server(80); //server port

String readString;

long Sperrzeit = 1200000; // 20min = 1 200 000
long Abschaltzeit = 1500000; // 25min = 1 500 000
long LetzteZeitSperr; // Sperrzeit bei Falscher Antwort
long LetzteZeitAus; // Zeit um Aus Automatisch

int Fragencounter = 0; // Zähler aktuelle Frage
int AusPin = 5; // Pin mit Relais Aus
int StatusAusPin = LOW; // Statusspeicher des Relais für AUS
int StatusFalscheFrage = LOW; // Frage Falsch = Sperrzeit abwarten

void setup(){

Serial.begin(9600);

pinMode(10,OUTPUT);

digitalWrite(10,HIGH);
Serial.print("SD..");
if(!SD.begin(4)) Serial.println("Err");
else Serial.println("Ok");
delay(3000);

Ethernet.begin(mac, ip, gateway, subnet);
digitalWrite(10,HIGH);

server.begin();
Serial.println("Rdy");
}

EthernetClient client;

void loop(){
/* // ------------------------------------------------------------------------- Abschaltzeit
if (millis() - LetzteZeitAus > LetzteZeitAus) {
StatusAusPin = false; }
else {
StatusAusPin = true;
digitalWrite(AusPin, StatusAusPin);
}

// ------------------------------------------------------------------------- Sperrzeit falsche Frage
if (StatusFalscheFrage = HIGH) {
if (millis() - LetzteZeitSperr > Sperrzeit) {
StatusFalscheFrage = HIGH; }
else {
StatusFalscheFrage = LOW;
}
} */

// ------------------------------------------------------------------------- Create a client connection
client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (readString.length() < 100) { //read char by char HTTP request
readString += c; //store characters to string
}
if (c == '\n') { //if HTTP request has ended

Serial.println(readString); //print to serial monitor for debuging
Serial.println(J2);
//LetzteZeitAus = millis();
// ------------------------------------------------------------------------- Programmstand erkennen
if(readString.indexOf(J2) > -1) { //// --- Code Frage 2
// Serial.println("Code Frage 2 erkannt");
Fragencounter = 2;
strcpy_P(FileBuffer, (char*)pgm_read_word(&(Quest_table[6])));
printMyFile(FileBuffer);.......................................................................................

.........................................Fragencounter = 15;
printMyFile(F45);
}
else if (readString.indexOf("Joker+einl") > -1) { //// --- Kein Code eingegeben
// Serial.println("Kein Code eingegeben");
Fragencounter = 0;
printMyFile(F1);
}
else if(readString.indexOf("Neu=Neues+Spiel") > -1) { // ----- Neues Spiel
Serial.println("Neu Zeit");
if (StatusFalscheFrage == HIGH) {
// Serial.println("Neustart gesperrt");
printMyFile(F2);
}
else if (StatusFalscheFrage == LOW) {
Serial.println("Neu frei");
Fragencounter = 1;
printMyFile(F3);
}
}
else if(Fragencounter >> 1 && readString.indexOf("Antw=") > -1) { // ----- Frage 1
Serial.println("Antw");
if (readString.indexOf("Antw=B") > -1) { //// --- Richtig
Serial.println("Ok"); }
else {
Serial.println("Err");
}
}
else { // ----- Nichts erkannt - neuladen
Serial.println("neuladen");
printMyFile(F1);
}
}
// client.stop();
// readString="";
}
}
}
}

// ------------------------------------------------------------------------- Client ausgeben

void printMyFile(char* filename) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
File myFile = SD.open(filename);
if (myFile) {
while (myFile.available()) {
client.write(myFile.read());
}
myFile.close();
}
delay(1000);
}

Was würde Arbeitsspeicher sparen?

Nachdem du schon viele feste Texte ins PROGMEM gepackt hast,
kommt als nächstes, den String readString; rauszuschmeissen.

        readString += c;                          //store characters to string
Ist eine der aufwendigsten Operationen, die du dir (nicht) vorstellen kannst.

        else if(readString.indexOf("Neu=Neues+Spiel") > -1) {    // ----- Neues Spiel

für solche Sachen ist ein Arduino als Web-Server auch nicht optimal ...

Hallo,

so mein Programm hat sich wieder weiterentwickelt. Die einzelnen IF-Abfrage wurden nun durch Schleifen ersetzt usw...
Trotzdem knapse ich an der Grenze meines Arbeitsspeichers herum.

@Michael_x und alle anderen:

Gibts eine Möglichekit diesen vorher angesprochenen

readString += c;

so zu verändern das mein Webserver immer noch unverändert läuft, ich aber weniger Speicher verbrauche?

Grüße
Sven

Gibts eine Möglichekit diesen vorher angesprochenen
readString += c;
so zu verändern das mein Webserver immer noch unverändert läuft, ich aber weniger Speicher verbrauche?

z.B. wie hier
statt readString wird hier ein statisches char array clientline verwendet.

#define BUFSIZ 80  //defines the buffer size.  reduce size if less ram is available.
char clientline[BUFSIZ];

void loop() {
  EthernetClient client = server.available();
  if (client) {
    boolean current_line_is_blank = true;
    index = 0;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          if (index < BUFSIZ-1)
            index++;
          continue;
        }
        clientline[index] = 0;
        Serial.println(clientline);
        // ... clientline auswerten
      }
    }
  }
}

Mit einfach auszuwertenden Paramtern in der URL machst du dir das Leben leichter ( Es gibt sinnvolleres als deinen knappen RAM bzw die clientline auf das Vorkommen von "Neu=Neues+Spiel" -- was auch im RAM liegt -- zu durchsuchen ... )
Die clientline schon auszuwerten während sie gelesen wird, und allen unnötigen Schnickschnack erst gar nicht zu speichern, ist noch ausgefuchster.