Inizializzazione SD-card in corso d'opera :(

Ciao a tutti! Vi presento questo codice che sto completando per riuscire a controllare da web il mio clima. Tuttavia nel momento in cui entro nella condizione:

if( temp == 25 && page == 2)

dove dovrebbe verificare successivamente:

if(StrContains(HTTP_req, "GET /?vel1"))

questo non accade! entra nel primo if ma nel secondo esce e riparte da zero con l'inizializzazione della SD e di tutte le variabili che quindi tornano a zero e nel passaggio successivo ovviamente non entra neanche più nel primo if...
Non capisco dov'è l'errore anche perchè la sintassi mi sembra giusta...
Riuscite a darmi una mano? Se devo chiarire qualcosa non esitate a dirmelo!
Grazie

Ecco il codice:

#include <SPI.h>        //Si inizia con la dichiarazione delle librerie
#include <Ethernet.h>   //utili allo scopo
#include <SD.h>
#include <IRremote.h>
#include <avr/pgmspace.h>
#define REQ_BUF_SZ   20

byte MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  //Si dichiara il MAC address
byte IP[] = { 192, 168, 1, 20 };                       //unico per ogni utente e l'IP
                                                      //che gli diamo noi

PROGMEM prog_uint16_t on_1[] ={4400,4300,550,1600,500,1600,550,1600,550,1600,550,500,550,550,500,1600,550,550,500,550,550,500,550,550,550,500,550,1600,550,1600,500,550,550,1600,550,500,550,550,500,550,550,500,550,550,550,500,550,1600,550,1600,500,1600,550,1600,550,1600,550,1600,500,1600,550,1600,550,550,500,550,550,500,550,550,500,550,550,500,550,550,550,500,550,550,500,1600,550,1600,550,500,550,550,550,500,550,550,500,500,600,500,550,550,550,500,550,1600,550,500,550,550,500,550,550,500,550,550,550,1550,550,550,550,500,550,550,500,550,550,500,550,550,550,500,550,500,550,1600,550,1600,550,500,550,550,550,500,550,550,500,550,550,500,550};

EthernetClient client;   //Si definisce una variabile EthernetClient di nome client
EthernetServer server(80);    //Fa si che Arduino sia in ascolto sulla porta 80
File htmlFile;            //Si definisce una variabile "File" della libreria SD.h
char HTTP_req[REQ_BUF_SZ] = {0};
char req_index = 0;
boolean currentLineIsBlank;
unsigned int uSendBuff[RAWBUF];
IRsend irsend;
byte page = 0;
byte temp = 0;
int i = 0;
const int ledpin = 9;

void sendAcCommand(int index) {
  uint16_t rawlen;
  prog_uint16_t * pfSendBuff = getAcSendBuff(index);
  if (0 != pfSendBuff) {
    rawlen = pgm_read_word_near(pfSendBuff);
    memcpy_P(uSendBuff, pfSendBuff+1, rawlen * sizeof(uint16_t));
    for(i=0;i<3;i++){
    irsend.sendRaw(uSendBuff, sizeof(uSendBuff)/sizeof(int), 38);
    }
  }
}

prog_uint16_t * getAcSendBuff(int index) {
if ( index == 1 ) { return on_1; }
return 0;
}

void setup()
 {
   Serial.begin(9600);  //Scelgo di inizializzare la comunicazione seriale (facoltativo)
   Serial.println("Inizializzazione SD Card..."); //Scritta di "rito"
   if (!SD.begin(4))    //Inizializzo la SD card sul pin 4 (CS=Card Select)
    {                  //Se (SD.begin!=4) ovvero che non legge la SD sul pin 4 allora
                        // fallisce l'inizializzazione altrimenti riesce
      Serial.println("Inizializzazione SD fallita!");
      return;
    }
   else
    {
      Serial.println("Inizializzazione SD riuscita!");    
    }
   Ethernet.begin(MAC,IP);    //Inizializzo la comunicazione ethernet passando
   server.begin();            //MAC e IP e avvio il server
   pinMode(9,OUTPUT);
   digitalWrite(ledpin, LOW);
 }

void loop()
 {
   //Ascolto client in arrivo
  client = server.available(); // memorizzi la presenza di una richiesta da 
                               // parte di un Client Web in client, in pratica quando dal 
                               // tuo browser ti collegherai all’interfaccia web, 
                               // Arduino riceverà una richiesta di tipo Client che 
                               // puoi leggere con il metodo available() della 
                               // classe server
  if(client)  // leggi se la variabile client contiene una richiesta da parte di un browser 
              // allora esegue ciò che è indicato nelle linee successive;
    {
      Serial.println("Nuovo client"); //Dimmi che c'è il client
      currentLineIsBlank = true; //Utilizzata dopo
      while (client.connected()) // inizia un ciclo impostato sulla presenza di una connessione 
                                 // da parte di un browser web, tale verifica ti evita di far 
                                 // elaborazioni durante l’assenza di connessione;
        {
          if(client.available())  //verifica che la connessione oltre ad essere presente sia 
                                  // anche utilizzabile;
            {
              char c = client.read();  // leggi il valore inviato dal client con il metodo read() 
                                       // dell’oggetto client assegnalo ad una variabile di tipo char;
              if (req_index < (REQ_BUF_SZ - 1)) 
                {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
              Serial.println(c);    // print HTTP request character to serial monitor
              if(c=='\n' && currentLineIsBlank)  // verifica che il carattere c letto sia un “\n” (new line) 
                                                // e che contemporaneamente la variabile current_line_is_blank  
                                                // sia settata a true
                {
                  // Invio header standard di risposta
                  client.println("HTTP/1.1 200 OK");
                  client.println("Content-Type: text/html");
                  client.println("Connnessione: close");
                  client.println();
                  Serial.println("Caricamento pagina sul server...");
                  if (StrContains(HTTP_req, "GET / ") || StrContains(HTTP_req, "GET /index.htm")) 
                          {
                            htmlFile = SD.open("index.htm");        // open web page file
                            page = 1;
                            Serial.println(F("Pagina assegnata 1"));
                          }
                  if (StrContains(HTTP_req, "GET /index2.htm")) 
                          {
                            htmlFile = SD.open("index2.htm");        // open web page file
                            page = 2;
                            Serial.println(F("Pagina assegnata 2"));
                          }
                  if (StrContains(HTTP_req, "GET /index3.htm")) 
                          {
                            htmlFile = SD.open("index3.htm");        // open web page file
                            page = 3;
                            Serial.println(F("Pagina assegnata 3"));
                          }
                  if(StrContains(HTTP_req, "GET /?25"))
                          {
                            htmlFile = SD.open("index4.htm");
                            Serial.println(F("Temperatura assegnata 25"));
                            temp = 25;
                          }
                  Serial.print("Temperatura: ");
                  Serial.println(temp);
                  Serial.print("Pagina: ");
                  Serial.println(page);
                  if( temp == 25 && page == 2)
                          {
                           Serial.println(F("INGRESSO IN PRIMA PARTE CICLO"));
                            if(StrContains(HTTP_req, "GET /?vel1"))
                            {
                              sendAcCommand(1);
                              Serial.println(F("INVIO SEGNALE ACCENSIONE"));
                            }
                          }
                  if (htmlFile)                     // Se l'apertura è riuscita...
                    {
                      Serial.println("Caricamento riuscito");
                      while (htmlFile.available())  //Finchè il file è disponibile...
                        {  
                          client.write(htmlFile.read()); // Stampo sul server il file contenuto su SD
                                                         // tramite il metodo read (File.read())
                        }
                  htmlFile.close();  //chiudo il file su SD
                  Serial.println("File chiuso");
                    }
                  else
                      {
                        Serial.println("Apertura del file non riuscita");
                      }
                      
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
          if (c == '\n') 
          {
            currentLineIsBlank = true;
          }
          else if (c != '\r')   
          {
            currentLineIsBlank = false;
          }
       }
     }
     delay(100);
     client.stop();
     Serial.println("Client disconnesso");
    }
   }

Ecco l'ultima parte del codice

void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) 
    {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index_ = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index_ < len) {
        if (str[index_] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index_++;
    }

    return 0;
}

E' come se la scheda crashasse e ripartisse dal setup azzerandomi oltretutto le variabili che mi servono da controllo! :fearful: :fearful:
Non so più dove sbattere la testa... avreste da darmi qualche aiuto? Anche piccolo! Ogni cosa è gradita! =(

Purtroppo quello sketch che hai postato mi restituisce una montagna di errori.
Potresti indicare che arduino usi e con quale IDE compili?

Utilizzo l'IDE alla versione 1.0.5 r2 con Arduino Mega e Ethernet Shield.

Quando intendi pieno di errori cosa intendi? Nella comunicazione con il client, nel richiamo della stringa dalla flash del micro, utilizzo della SD.. o è tutto completamente alle ortiche?
E dire che l'ho costruito per parti... prima ho imparato a usare la IRRemote, poi la PROGMEM, poi la ethernet, poi la SD e poi ho messo insieme un po' per volta cercando di stare attento...
Grazie per l'aiuto :wink:

la IRremote e il progmem mi danno errori ... aspetta che scarico la 1.0.5 r2

Ok! a me lo sketch di per se non dà alcun errore... anzi! la pagina la carica correttamente fino a index4.htm (se ti servono le pagine html per provarle te le passo senza problemi) ma quando deve far ripartire il loop alla chiamata successiva allora si blocca e su seriale esce questo:

Nuovo client
GET /?vel1 HTTP/1.1
Host: 192.168.1.20
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Referer: http://192.168.1.20/?25
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en,it-IT;q=0.8,it;q=0.6

Caricamento pagina sul server.?à?³ÿInizializzazione SD Card...
Inizializzazione SD riuscita!

L'anomalia sta proprio in quel "Inizializzazione SD card"

No, non è un problema di inizializzazione della SD, in qualche modo stai saturando la ram e quindi si resetta il micro, poi ovviamente la prima riga che leggi sul serial è l'inizializzazione SD

ho dovuto togliere IRremote dallo sketch perchè non lo vuole proprio mi da molti errori, dove hai preso il tuo IRemote?

nel tuo setup manca questo

pinMode(10, OUTPUT);                       
  digitalWrite(10, 1);   
  pinMode(4, OUTPUT);                       
  digitalWrite(4, 1);

Questa versione l'ho presa modificata da non mi ricordo dove perchè mi serviva un buffer un po' più capiente per la stringa da inviare.. l'unica modifica era proprio al RAWBUF all'interno della libreria... Strano che non ti compili... a me non ha mai dato errori... Nè con la UNO nè con MEGA...

EDIT: Inserisco e vedo cosa succede

Quel metodo che usi per raccoglie i dati provenienti dal client mi lascia perplesso

if (req_index < (REQ_BUF_SZ - 1)) 
                {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }

può essere la causa della saturazione

poi scusa, ma come richiami le pagine index1.htm index2.htm index3.htm index4.htm le scrivi a mano sul browser?

se metti un href ti basta un click sul link

Quel metodo che usi per raccoglie i dati provenienti dal client mi lascia perplesso
Code:
if (req_index < (REQ_BUF_SZ - 1))
{
HTTP_req[req_index] = c; // save HTTP request character
req_index++;
}
può essere la causa della saturazione

Ho utilizzato una variabile char per non usare la String.h! Proprio per evitare di usare troppa memoria... Sicuramente l'ho utilizzata in modo errato..

poi scusa, ma come richiami le pagine index1.htm index2.htm index3.htm index4.htm le scrivi a mano sul browser?

se metti un href ti basta un click sul link

Ti linko le pagine html ( Dropbox - html_povera - Simplify your life )
Comunque utilizzo un href su bottone...
(Ti prego non guardare l'impaginazione HTML... è orribile! :roll_eyes: )

l'href lo usi così

void loop(){
String readString=""; 
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         if (readString.length() < 100) {
           readString += c; 
         } 
        
        if (c == '\n') {
     
          Serial.println(readString); 

          client.println(F("HTTP/1.1 200 OK")); //send new page
          client.println(F("Content-Type: text/html"));
          client.println();

          client.println(F("<HTML>"));
          client.println(F("<HEAD>"));
          client.println(F("<TITLE>Arduino GET test page</TITLE>"));
          client.println(F("</HEAD>"));
          client.println(F("<BODY>"));

          client.println(F("<H1>Arduino muenu pagine</H1>"));          
          
          client.print(F("<li><a href=\"INDEX1.HTM\">Pagina 1</a></li>"));
          client.print(F("<li><a href=\"INDEX2.HTM\">Pagina 2</a></li>"));
          client.print(F("<li><a href=\"INDEX3.HTM\">Pagina 3</a></li>"));
          client.print(F("<li><a href=\"INDEX4.HTM\">Pagina 4</a></li>"));
                                                
          client.println(F("</BODY>"));
          client.println(F("</HTML>"));
             
         delay(1);         
          client.stop(); 
                                                               
          readString="";

        }
      }
    }
  }
}

nel readstring leggi quello che c'è dopo il GET /

In realtà quella stringa è molto piccola poichè legge una riga alla volta e la svuota subito

Però se devi gestire diverse pagine html, molti file su SD saltando da una all'altra ti consiglio di usare una lib webserver che fa già tutto senza complicarti la vita a leggere le GET i POST negli header dell'http

pablos:
l'href lo usi così

void loop(){

String readString="";
 EthernetClient client = server.available();
 if (client) {
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();
        if (readString.length() < 100) {
          readString += c;
        }
       
       if (c == '\n') {
   
         Serial.println(readString);

client.println(F("HTTP/1.1 200 OK")); //send new page
         client.println(F("Content-Type: text/html"));
         client.println();

client.println(F(""));
         client.println(F(""));
         client.println(F("Arduino GET test page"));
         client.println(F(""));
         client.println(F(""));

client.println(F("

Arduino muenu pagine

"));          
         
         client.print(F("
  • <a href="INDEX1.HTM">Pagina 1
  • "));
             client.print(F("
  • <a href="INDEX2.HTM">Pagina 2
  • "));
             client.print(F("
  • <a href="INDEX3.HTM">Pagina 3
  • "));
             client.print(F("
  • <a href="INDEX4.HTM">Pagina 4
  • "));
                                                   
             client.println(F(""));
             client.println(F(""));
               
            delay(1);        
             client.stop();
                                                                 
             readString="";

    }
         }
       }
     }
    }

    
    
    
    nel readstring leggi quello che c'è dopo il GET /
    
    In realtà quella stringa è molto piccola poichè legge una riga alla volta e la svuota subito
    
    Però se devi gestire diverse pagine html, molti file su SD saltando da una all'altra ti consiglio di usare una lib webserver che fa già tutto senza complicarti la vita a leggere le GET i POST negli header dell'http
    

    Guarda... devo gestire 4 pagine HTML che viaggiano sostanzialmente in sequenza senza salti o interruzione di alcun genere...
    Avevo provato a utilizzare la webserver.h ma non mi gestiva l'integrazione con SD (fino a un paio di mesi fa eh! ora non ho più controllato)
    Provo a utilizzare questo metodo e ti faccio sapere :slight_smile:
    Intanto grazie davvero per l'aiuto!

    Ecco il link da dove ho preso lo sketch per la gestione di pagine HTML multiple:

    Dici che ci sono metodi più performanti? Vorrei in ogni caso lasciare le pagine su SD..