Arduino UNO + Ethernet server y SD

Buenas tardes, estoy teniendo un problema con la arduino ethernet (W5100) y el uso de la SD “a la vez”.

Estoy aprendiendo a programar el server, recibiendo una petición POST que trae un texto escrito, cosa que ha funcionado bien hasta ahora, ya que se muestra bien por puerto serial. Una imagen del servidor:

Y un ejemplo de funcionamiento, aísla perfectamente el texto, incluso deja de mostrarlo si no hay nada como es el caso en el que ocurre un GET:

Ahora quiero que éste texto que he recibido y aislado, se escriba en un archivo de texto en la SD. Para ello utilizo el siguiente código (Las partes correspondientes a la SD están comentadas porque no funciona)

/*
  Web Server modificado por jmth
 */
#include <SPI.h>
#include <Ethernet.h>
//#include <SD.h>
//File myFile;


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
static byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
static IPAddress ip(192,168,1,177);
String estado="OFF";
String men ="";


// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);
boolean SDfailed;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection and the server:
/*    pinMode(10,OUTPUT);
  if(!SD.begin(4)){
    Serial.println("SD initialization failed");
    SDfailed = 1;
  }
  else{
    Serial.println("SD initialization done");
  }*/
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("Server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    String cadena = String(25);
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        //AQUI SE COMPRUEBAN LAS COSAS
        cadena.concat(c);
        int posicion = cadena.indexOf("LED=");
        if(cadena.substring(posicion)=="LED=ON"){
          digitalWrite(8,HIGH);
        }
        if(cadena.substring(posicion)=="LED=OFF"){
          digitalWrite(8,LOW);        
        }
        
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          //Aquí se recibe el POST
          String rec;
          while(client.available()){
              rec += (char)client.read(); //Añade todo el mensaje
          }
          int txt = rec.indexOf("texto="); //busca esto
          men = rec.substring(txt+6); //aisla lo que hay despues
          if(men!=0){ //Si has aislado un caracter no nulo
          Serial.println("");
          Serial.println(men); //Lo muestras por serial
          Serial.println("");
          }
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          //AQUI SE ESCRIBE EL CODIGO HTML
          if(digitalRead(8)) client.print("LED is <font color='green'>ON</font>");
          else client.print("LED is <font color='red'>OFF</font>");
          client.println("
");
          client.println("<button onClick=location.href='./?LED=ON\'>ON</button>");
          client.println("<button onClick=location.href='./?LED=OFF\'>OFF</button>");
          client.println("
");
          client.println("Firma el logbook:");
          client.println("<form method='post' action='#'>Nombre:<input type=text size=25 name=texto value=""><input type=submit action=submit></form>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line

          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
   /* if(men!=0){ //Si se ha recibido caracter no nulo
      SD.begin(4); //Se inicia la SD
      myFile = SD.open("logbook.txt", FILE_WRITE); 
      if(myFile) myFile.println(men); //Si se ha abierto escribe el dato
      else Serial.println("No se ha podido escribir en la SD");
      myFile.close();
    }
    */
    Serial.println("client disconnected");
  }
}

Al programar ésto (quitando los comentarios de lo que corresponde a SD, lógicamente) la secuencia es la siguiente:

  • La SD se inicializa correctamente en setup
  • El server está en marcha y puedo conectarme
  • Envío el texto pero éste deja de aparecer por puerto serial y por lo tanto no se escribe en la SD, por lo que supongo que se ha dado un error al recibirlo, pero no se ha cambiado el código que se encarga de ello.

La SD está funcionando correctamente con el ejemplo de ReadWrite e incluso si escribo cualquier cosa después de la inicialización en setup, lo hace correctamente.

¿Cuál es el problema y alguna posible solución? Muchas gracias.

Yo lo que hice y te recomiendo es que no hagas un doble if(men!=… pues el que esta al final ya lo haces al terminar todo. mejor haz la evaluación para escribir en la SD al mismo tiempo que
Serial.println("");
Serial.println(men); //Lo muestras por serial
Serial.println("");

No estudie el funcionamiento de la shield ni de la sintaxism solo hice esa observación.

/*
 Web Server modificado por jmth
*/
#include <SPI.h>
#include <Ethernet.h>
//#include <SD.h>
//File myFile;


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
static byte mac[] = { 
 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
static IPAddress ip(192,168,1,177);
String estado="OFF";
String men ="";


// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);
boolean SDfailed;

void setup() {
// Open serial communications and wait for port to open:
 Serial.begin(9600);
  while (!Serial) {
   ; // wait for serial port to connect. Needed for Leonardo only
 }
 // start the Ethernet connection and the server:
/*    pinMode(10,OUTPUT);
 if(!SD.begin(4)){
   Serial.println("SD initialization failed");
   SDfailed = 1;
 }
 else{
   Serial.println("SD initialization done");
 }*/
 Ethernet.begin(mac, ip);
 server.begin();
 Serial.print("Server is at ");
 Serial.println(Ethernet.localIP());
}


void loop() {
 // listen for incoming clients
 EthernetClient client = server.available();
 if (client) {
   Serial.println("new client");
   // an http request ends with a blank line
   boolean currentLineIsBlank = true;
   String cadena = String(25);
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();
       Serial.write(c);
       // if you've gotten to the end of the line (received a newline
       // character) and the line is blank, the http request has ended,
       // so you can send a reply
       //AQUI SE COMPRUEBAN LAS COSAS
       cadena.concat(c);
       int posicion = cadena.indexOf("LED=");
       if(cadena.substring(posicion)=="LED=ON"){
         digitalWrite(8,HIGH);
       }
       if(cadena.substring(posicion)=="LED=OFF"){
         digitalWrite(8,LOW);        
       }
       
       if (c == '\n' && currentLineIsBlank) {
         // send a standard http response header
         //Aquí se recibe el POST
         String rec;
         while(client.available()){
             rec += (char)client.read(); //Añade todo el mensaje
         }
         int txt = rec.indexOf("texto="); //busca esto
         men = rec.substring(txt+6); //aisla lo que hay despues
         if(men!=0){ 
//Si has aislado un caracter no nulo
//ojo para que hacerlo despues si no vueles a cambiar el valor de "men"
//yo haria la evaluacion para la sd de una vez
//Si se ha recibido caracter no nulo
         SD.begin(4); //Se inicia la SD
         myFile = SD.open("logbook.txt", FILE_WRITE); 
         if(myFile) myFile.println(men); //Si se ha abierto escribe el dato
         myFile.close();
         Serial.println("");
         Serial.println(men); //Lo muestras por serial
         Serial.println("");
         }
     else{
Serial.println("No se ha podido escribir en la SD");
}
         client.println("HTTP/1.1 200 OK");
         client.println("Content-Type: text/html");
         client.println("Connection: close");  // the connection will be closed after completion of the response  // refresh the page automatically every 5 sec
         client.println();
         client.println("<!DOCTYPE HTML>");
         client.println("<html>");
         //AQUI SE ESCRIBE EL CODIGO HTML
         if(digitalRead(8)) client.print("LED is <font color='green'>ON</font>");
         else client.print("LED is <font color='red'>OFF</font>");
         client.println("
");
         client.println("<button onClick=location.href='./?LED=ON\'>ON</button>");
         client.println("<button onClick=location.href='./?LED=OFF\'>OFF</button>");
         client.println("
");
         client.println("Firma el logbook:");
         client.println("<form method='post' action='#'>Nombre:<input type=text size=25 name=texto value=""><input type=submit action=submit></form>");
         break;
       }
       if (c == '\n') {
         // you're starting a new line

         currentLineIsBlank = true;
       } 
       else if (c != '\r') {
         // you've gotten a character on the current line
       }
     }
   }
   // give the web browser time to receive the data
   delay(1);
   // close the connection:
   client.stop();
  /* if(men!=0){ //Si se ha recibido caracter no nulo
     SD.begin(4); //Se inicia la SD
     myFile = SD.open("logbook.txt", FILE_WRITE); 
     if(myFile) myFile.println(men); //Si se ha abierto escribe el dato
     else Serial.println("No se ha podido escribir en la SD");
     myFile.close();
   }
   */
   Serial.println("client disconnected");
 }
}