Web server sdcard URL

ciao a tutti,
ho sviluppato un software che carica una pagina web salvata su SD la quale comanda in GET delle uscite.
ma succede qualcosa di strano, se apro la pagina e poi magari faccio un refresh dal browser si blocca tutto, quindi devo spegnere tutto e al riavvio riesco ad aprire la pagina.
in più spesso capita che i comandi passati tramite URL, arduino non riesca a leggerli. e da quel momento non funzia più niente.

uso un arduino uno con ethernet shield w5500.
questo è il codice :

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

unsigned long previousMillis = 0; 

int out1 = 6;          
int out2 = 7;
int out3 = 8;          
int out4 = 9;          
int mode=0;
int time = 0;
int cicli;
int ledStateOut1 = LOW;
int ledStateOut2 = LOW;
int ledStateOut3 = LOW;
int ledStateOut4 = LOW;
int state;



#define maxLength 25
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

byte ip[] = { 192, 168, 0, 130 };
byte gateway[] = { 192, 168, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };

File htmlFile;
EthernetServer server(80);
 
void (*resetBoard)() = 0;

void setup() {
  Serial.println("SETUP");
Ethernet.begin(mac, ip);
server.begin();
  if (!SD.begin(4)) { return; }
Serial.begin(9600);
  pinMode(out1, OUTPUT);
  pinMode(out2, OUTPUT);
  pinMode(out3, OUTPUT);
  pinMode(out4, OUTPUT);
  
}

void loop() {
//Serial.println("LOOP");
//PAGINA WEB

  char* file_to_load = "home.htm";
  String inString = String(maxLength);
 
  EthernetClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    String line = String();
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        line.concat(c);
        if (inString.length() < maxLength) {
          inString += c;
        }
        if (c == '\n' && currentLineIsBlank) {
          //Serial.print("sono qui");
        /*  if (inString.indexOf(".htm") > -1) {
            String new_file_load;
            int rootIndex = inString.indexOf("/");
            new_file_load = inString.substring((rootIndex+1), (rootIndex+13));
 
            int endIndex = new_file_load.indexOf(" ");
            if (endIndex > -1) {
              new_file_load = new_file_load.substring(0, endIndex);
            }
            if (new_file_load != "")  {
              new_file_load.toCharArray(file_to_load,12);
            }
          }*/
          
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); 
          //read_file( "header.htm",client );
          //read_file( file_to_load,client );
          //read_file( "footer.htm",client );
          htmlFile = SD.open( "home.htm" );
            if (htmlFile) {
              while (htmlFile.available()) {
                  client.write(htmlFile.read());
              }
              // close the file:
              htmlFile.close();
            }
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
                   Serial.print(line);


          if (line.indexOf("hz_2")>0) {              
              state = 1;
   
              //cicli=0;
          }
          if (line.indexOf("hz_3")>0) {              
              state = 2;
              //cicli=0;
          } 
          if (line.indexOf("hz_4") >0 ) {              
              state = 3;
              //cicli=0;
          }  
          if (line.indexOf("modo_1") >0 ) {              
              mode = 1;
              //cicli=0;
          }
          if (line.indexOf("modo_2")>0  ) {              
              mode = 2;
              //cicli=0;
          } 

          if (line.indexOf("hz_0")>0 ) {
              state = 0; 
              mode = 0; 
                    
          }
          if (line.indexOf("modo_0")>0  ) {              
              mode = 0;
              state = 0;
              
          }  
          if (line.indexOf("finish")>0 ) {
              state = 0; 
              mode = 0; 
                     
          }       
          
          line = String();
          
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        
        }
      }
    }
    delay(1);

    client.stop();
  }

//char state = Serial.read();

unsigned long currentMillis = millis();

//SETTAGGIO FREQUENZA
  //if (Serial.available() > 0) {
    if (state==1){
        cicli=0;
        time=250;
        //mode=1;
    }else{
      if (state==2){
        cicli=0;
        time=187;
        //mode=2;
      }else{
        if (state==3){
          cicli=0;
          time=125;
        //mode=1;
        }else{
          if (state==0){
            cicli=0;
            time=0;
            
            //mode=0;   
          }
        }
      }
    }
  //}

const long interval=time;

//TEMPORIZZATORE
      if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
  if(mode==1){

      if (((ledStateOut1 == LOW)&&(ledStateOut3 == LOW))&&((ledStateOut2 == HIGH)&&(ledStateOut4 == HIGH))) {
        ledStateOut1 = HIGH;
        ledStateOut2 = LOW;
        ledStateOut3 = HIGH;
        ledStateOut4 = LOW;
        }else{
        ledStateOut1 = LOW;
        ledStateOut2 = HIGH;
        ledStateOut3 = LOW;
        ledStateOut4 = HIGH;
      }
      cicli++;
    
  }
    if(mode==2){

        if (((ledStateOut1 == LOW)&&(ledStateOut3 == HIGH))&&((ledStateOut2 == HIGH)&&(ledStateOut4 == LOW))) {
          ledStateOut1 = HIGH;
          ledStateOut2 = LOW;
          ledStateOut3 = LOW;
          ledStateOut4 = HIGH;
        }else{
          ledStateOut1 = LOW;
          ledStateOut2 = HIGH;
          ledStateOut3 = HIGH;
          ledStateOut4 = LOW;
        }
        cicli++;
      }    
    
      if(mode==0){
        ledStateOut1 = LOW;
        ledStateOut2 = LOW;
        ledStateOut3 = LOW;
        ledStateOut4 = LOW;

        }
      }
    


  digitalWrite(out1, ledStateOut1);
  digitalWrite(out2, ledStateOut2);
  digitalWrite(out3, ledStateOut3);
  digitalWrite(out4, ledStateOut4);
 // Serial.print(ledStateOut1);
 // Serial.print(ledStateOut2);
  //Serial.println(cicli);
//Serial.println(state);
//Serial.println(mode);


}

//CARICA FILE DA SD CARD
// void read_file( char* page_html, EthernetClient client ){

//}

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

urca scusate non me ne sono accorto.

1 Like

Innanzitutto devi assolutamente sistemare l'indentazione del programma che cosi è poco leggibile e si crea una gran confusione!

Dal punto di vista del software mi sono saltate all'occhio queste due cose (ma non escludo che ci sia altro)..

Questo break mi sembra fuori luogo. Se non ho letto male, va a interrompere il
while (client.connected()) {....},
ma in quel caso non esegue più il resto del codice dove vai a controllare le stringhe caratteri ricevute. Secondo me lo puoi tranquillamente eliminare tanto nel momento in cui chiami il metodo client.stop() la condizione del while diventa false.

Il metodo indexOf() restituisce -1 quando non trova la chiave di ricerca, quindi questa condizione (cosi come tutte le altre dove fai lo stesso errore) è vera solo quando la stringa ricevuta contiene altri caratteri prima di quella ricercata.

Ok... cercherò di fare pulizia si il brake; lo posso togliere.
IndexOf() viene valorizzato solo alla pressione di un button dalla pagina HTML.

Pardon, avevo scritto un'inesattezza, ho corretto.
Ad ogni modo, string.indexOf("substr) restituisce la posizione di "substr" all'interno di string, se "substr" non viene trovata il risultato è -1

string = "Ciao Erik22";
string.indexOf("Ciao") === 0

Se tu scrivi in questo modo, affinché le condizioni siano vere, devi inviare qualche carattere prima di quello che poi vai a confrontare come ad esempio "#hz_2" oppure " hz_2" etc etc.


if (line.indexOf("hz_2")>0) {              
  state = 1;
  //cicli=0;
}
if (line.indexOf("hz_3")>0) {              
  state = 2;
  //cicli=0;
} 
if (line.indexOf("hz_4") >0 ) {              
  state = 3;
  //cicli=0;
}  
if (line.indexOf("modo_1") >0 ) {              
  mode = 1;
  //cicli=0;
}
if (line.indexOf("modo_2")>0  ) {              
  mode = 2;
  //cicli=0;
} 
if (line.indexOf("hz_0")>0 ) {
  state = 0; 
  mode = 0; 
}
if (line.indexOf("modo_0")>0  ) {              
  mode = 0;
  state = 0;  
}  
if (line.indexOf("finish")>0 ) {
  state = 0; 
  mode = 0; 		 
}

Si io dalla pagina invio ed es. ?hz_2

La cosa strana è che il software sembra essere eseguito solo una volta.
Magari riesco ad inviare ad Arduino due comandi e poi si inchioda.

ho fatto le prove ma niente.
qualcuno ha qualche idea?
potrebbe essere la pagina web?
è composta da HTML (dove ho creato parecchie classi dentro ) e da JS con qualche funzione.

Su un Arduino UNO mi meraviglia che già giri ... con 2 KB di SRAM cosa pretendi?

Puoi fare ancora una prova, prova a pre-allocare TUTTE le variabili di tipo String nel setup(), in modo che la frammentazione sia minima, altrimenti ... passa ad una scheda "decente" per fare queste cose (una bella schedina con ESP32 e passa la paura).

Guglielmo

in effetti quando non si inchioda funziona bene l'applicativo. potrebbe davvero essere un problema di modello hardware? Guglielmo ti è già capitato di veder risolvere situazioni analoghe per questo motivo?
fosse così sarei fortunato. :v:

Si, come detto, ormai, se ho WiFi o BT, uso solo ESP32 ... costano una miseria, hanno quanta memoria vuoi e funzionano benissimo.

Non si può usare una UNO per fare certe cose ... è proprio un problema di mancanza di risorse!

Guglielmo

Però io non uso ne WIFI ne BT. la scheda è collegata direttamente al pc con cavo ETH in locale sono anche scollegato dalla rete di casa.

Cambia poco, stessa occupazione di un sacco di risorse ... fattene una ragione, la UNO NON è fatta per certe cose, è un piccolo microcontrollore e come tale va usato, NON per applicazioni WEB !

Guglielmo

ottimo proverò e vi aggiornerò..

Cercandole con Google trovi tranquillamente schede ESP32 con la Ethernet a bordo, anche se ... se hai a disposizione una rete WiFi, tanto vale che sfrutti il WiFi integrato :wink:

Guglielmo

Ho iniziato la ricerca della scheda più consona alle mie esigenze.
Nel frattempo ho provato a snellire il codice della pagina web e l'applicativo ha ricominciato a funzionare come dovrebbe.
Guglielmo credo proprio che prendere una scheda più performante risolva la problematica.
Appena l'ho individuata vi aggiorno.

1 Like

ho bisogno di un consiglio,
essendo la mia un'applicazione con fini industriali, arduino opta potrebbe andare bene?

Salvo che per il costo ... :money_mouth_face: :money_mouth_face: :money_mouth_face:

Guglielmo

Piuttosto, magari ti semplifica la vita, hai provato a guardare la libreria Webbino che è in Megatopic?

E' regolarmente manutenuta dall'autore ed è disponibile nel "Library manager" dell'IDE di Arduino. Ci sono vari esempi di utilizzo incluso il comandare LED on/off :wink:

Guglielmo

1 Like