Problema stabilità Arduino UNO R3 con W5100

Buongiorno a tutti.
Ho un problema con una applicazione che ho sviluppato.

Scopo dello Sketch: Controllare 2 uscite manualmente tramite pagina WEB e automaticamente.

Uscita 1 (VENTO): l’uscita può essere abilitata manualmente tramite bottone su pagina HTML. Si abilita automaticamente quando il vento (rilevato da un anemometro a palette) rileva una velocità superiore ad una certa soglia impostata. L’uscita va ad OFF solo quando il comando manuale è a OFF e la velocità del vento è sotto la soglia impostata.

Uscita 2 (GRANDINE): Si abilita e disabilita solamente tramite comando manuale su pagina WEB.

PROBLEMA: Funziona tutto per 1/2 giorni dal momento in cui il sistema viene alimentato, ad un certo punto la pagina web non risulta più raggiungibile (dal browser ricevo “pagina non trovata”) ma se faccio il ping sull’indirizzo IP assegnato ottengo una risposta in pochi millisecondi. Il sistema riprende a funzionare solo dopo aver scollegato e poi ricollegato l’alimentazione.

Non riesco a capire quale possa essere il problema. Non sono un esperto e il codice l’ho scritto scopiazzando sul WEB…
Allego lo sketch in quanto troppo lungo per essere caricato sul testo del post.

Grazie a chiunque abbia voglia di darmi una mano!

versione_finale.ino (9.05 KB)

Allora, intanto cambia il nome del programma da "versione_finale" a "versione_test" :wink:

Poi il tuo codice è complicatissimo da leggere, io ho un poco di pratica ma mi chiedo come tu possa capirci qualcosa lì dentro, e rendi ancora più difficile il compito a noi che cerchiamo di aiutarti.
Inizia ad indentare decentemente tutto, ti basta premere Ctrl-T e te lo sistema l'IDE in automatico, poi continua a mantenere la formattazione mi raccomando! E comunque essendo frutto di vari "copia/incolla/adatta" di roba trovata in rete, il pericolo inquesti casi è quello di fare un "minestrone" ingestibile (indigeribile?:D) quantomeno se fatto da qualcuno ancora abbastanza alle prime armi.

Detto questo, temo che il tuo grosso problema sia causato dall'uso di variabili di tipo "String" (con la "S" maiuscola) che vedo in quel listato. E' stato detto centinaia di volte anche in questo stesso forum, ma provo a spiegarlo in poche parole: dato che su piccole MCU come questa non esiste un sistema operativo sottostante ma soprattutto non esiste un "garbage collector" quindi non si può sempre riutilizzare la memoria rilasciata quando una variabile String non serve più, il che dopo un certo tempo (che dipende da quante String ci sono e come vengono usate) la memoria disponibile finisce ed Arduino si comporta in modo anomalo o si blocca del tutto.
Se vuoi approfondire meglio perché siano da evitare puoi cercare in rete per trovare ad esempio QUESTO (è in inglese, se hai problemi fattelo tradurre con Google).

Quindi devi eliminare ogni variabile "String" e sostituirla con equivalenti "stringhe C" ossia array di caratteri (o "char array") con il byte '\0' come terminatore di stringa. Se non conosci le stringhe C ti consiglio di studiare un poco questo aspetto prima di rimettere mano a quel "minestrone" :wink: tanto dato che le stringhe in Arduino sono identiche a quelle del linguaggio C, ti basta trovare un qualsiasi tutorial o reference che spieghi queste stringhe o char array, ad esmepio QUI o QUI tanto per darti un paio dei primi link che trovi cercando con Google.

Grazie mille dell'aiuto!
Faccio quello che hai detto e se funziona ti ringrazierò di nuovo :smiley:

Ho cercato di fare le modifiche suggerite.
Ho tolto diverse String ma non riesco a trovare un modo per togliere la String header.

Posto il codice in allegato, funziona, ma sembra bloccarsi ancora dopo qualche giorno dalla connessione all’alimentazione. Non ho fatto caso a se il tempo che il sistema funziona sia legato o meno al numero delle richieste fatte nella pagina http.

Continuo a pensare ad una soluzione per non usare la String sopra citata, se avete degli spunti vi sono grato visto che ci sto’ perdendo un sacco di tempo senza ottenere nulla.

grazie ancora!

versione_test.ino (9.2 KB)

La “header” vedo che accumula tutte le righe della request, essendo una stringa composta da varie righe ovviamente è difficile prevederne la dimensione massima, cosa che invece si deve fare per allocare una variabile char per fare la stessa cosa.
A te però quello che interessa è la riga con la sola GET, ossia la prima della request, per cui puoi allocare un buffer diciamo di 30 caratteri per stare abbondanti (visto che la GET più lunga è attualmente “GET /soglia3”).

Quindi le modifiche sono più o meno una cosa del genere:

...
//String header;
char header[30];
// Puntatore/contatore caratteri nel buffer
byte hLen = 0;
...
  EthernetClient client = server.available();
  if (client) {                             // If a new client connects,

    // Azzeramento del buffer
    hLen = 0;
    header[0] = 0;

    boolean currentLineIsBlank = true;
    currentTime = millis();
...
            // turns the IOs on and off
            //if (header.indexOf("GET /7/on") >= 0) {
            // Il confronto si fa ora con strstr()
            if (strstr(header,"GET /7/on") ) {
              ModVentoMan = HIGH;
              EEPROM.write(2, 255);
            } else if (strstr(header,"GET /7/off")) {
              ModVentoMan = LOW;
              EEPROM.write(2, 0);
... eccetera ...

Chiaramente se il problema fosse quella String, si, dipenderebbe dal numero di chiamate GET ricevute, per cui potresti risolvere eliminando pure quella.

In allegato è il codice modificato in questo senso, provalo (l’ho modificato al volo ed ovviamente non l’ho provato…) e fammi sapere.

versione_test2.ino (9.13 KB)