Arduino Ethernet + SD POST

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:

tumblr_ngmwyxhX2l1r7bo7xo2_400.jpg


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:

tumblr_ngmwyxhX2l1r7bo7xo1_250.jpg


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)

Código:
/*
  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("<br />");
          client.println("<button onClick=location.href='./?LED=ON\'>ON</button>");
          client.println("<button onClick=location.href='./?LED=OFF\'>OFF</button>");
          client.println("<br />");
          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.
 
El error está en esta sección:
Código:
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();     }
Toda vez que recibes un dato haces el SD.begin(4); esto está mal.
Comenta esa línea y haz la prueba.

Saludos.
 
Última edición por un moderador:
Como dijo Fernando123, estas inicializando la SD en cada momento y no estás permitiendo que los datos sean guardados en ésta. Haz la prueba como dijo Fernando.
 
No he conseguido solucionarlo haciendo lo que decís.

El problema es que en el momento que utilizo la SD dentro del loop, el código encargado de coger el POST y sacar el texto que se ha enviado deja de funcionar, a lo que no encuentro explicación.

Gracias.
 
Sin SD está funcionando, acabo de descubrir que con la SD la ethernet recibe datos extraños: lo que suelen ser frases con sentido ahora son símbolos y letras sueltas. Puede deberse a la falta de tiempo. Seguiré informando.

Edito: éste efecto puede haber estado producido por la lectura de la recepción en distintas líneas del código, así que al comentar una de ellas, el problema de los caracteres extraños ha desaparecido. El error de recepción ha desaparecido, pero quiero que desaparezca cuando comento la otra línea.

Edito 2: comento la otra línea y hago un pequeño código que me muestra la recepción en la variable (tipo string haciendo String += client.read(); ) que se almacena para después buscar el texto enviado, el resultado es el mismo: el mensaje desaparece. Ésto es lo que consigo recibir:

POST / HTTP/1.1
Host: 192.168.1.177
Connection: keep-alive
Content-Length: 14 -> Efectivamente, he enviado un texto de longitud 14
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin:
¿Por qué se ha cortado aquí?

La siguiente línea es un GET
 
Última edición:
Hola, vengo a actualizar el tema y subirlo. Creo que he encontrado otra solución algo más conveniente.

Dicha solución pasa por utilizar un script que lee el contenido del text input cuando pulsas el botón submit, os lo dejo a continuación:

Código:
<!DOCTYPE HTML>
<html>
<body>

<input type="text" name="txtJob" value="Write here"></input>
<button onclick="myFunction()">Submit</button>

<script>
function myFunction(){
	var texto = document.getElementsByName('txtJob')[0].value;
	alert(texto);
}
</script>
</body>
</html>

He comprobado que es capaz de mostrar en la alert el texto que escribo, el problema es que ahora quiero pasar esa var "texto" al puerto serial o la SD, y no se me ocurre cómo, así que necesito una ayudita. Muchas gracias.
 
Atrás
Arriba