WiFi shield e riconnessione alla rete

Scusate il ritardo ma il lavoro di certo qui non manca ūüėČ
Prima di tutto mi presento. Mi chiamo Ruffo Daniele e vengo dall’ ISIS Facchinetti di Castellanza ( 4 anno ).

 

Preciso che sono gi√† stato stagista presso Futura Elettronica¬†assieme al mio compagno Speroni Manuel ed abbiamo realizzato un robot LineFollower per permettere all’istituto di partecipare alla robocup. Il robot √® attualmente a scuola ed utilizzato da dei ragazzi di 5 come progetto per la maturit√†. Spero di avere la possibilit√† di rendervi partecipi di quel progetto non appena mi ricapita sotto le mani. ( Se lo ritrovo, pubblico il video di prova effettuato durante uno dei vari test)

 

Quest’anno invece mi √® stato proposto un lavoro di diverso tipo:
Prima di tutto trovare una soluzione ad un problema riscontrato nella nuova WifiShield ( 8190-WIFI_SHIELD ), ovvero ritrovare e riccolegarsi alla rete in caso di perdita del segnale ( derivante da una caduta di rete, spegnimento del modem, perdita del segnale, caduta di corrente o qualsivoglia tipo di situazione).

Risolto questo problema sviluppare diverse applicazioni utilizzando questa shield.

 

Come primo passo aggiorniamo l’idee di Arduino alla versione 1.0.1 ¬†( qui il link per la pagina del download ) e riscontriamo il primo problema.
Alcune delle vecchie librerie sembrerebbero non funzionare su questa nuova versione per cui un consiglio che posso darvi per
N.B. Ci tengo a precisare che tale operazione non risolve il problema per tutte le librerie !!tentare di risolvere questo problema consiste nel aprire il .h che avete incluso e controllare che non ci siano istruzioni del tipo:
#include <wire.h>
In tal caso sostituendole con #include <Arduino.h> dovrebbe risolvere il problema.

Ora scarichiamo la libreria per il  WifiShield ed ecco che purtroppo sorgono ulteriori e gravosi problemi. Purtroppo questa libreria risente di diverse limitazioni, ecco il motivo per cui mi sono permesso di apportare delle modifiche ( Il perchè viene spiegato in seguito ).
Qui il link per il download della libreria aggiornata.

Per la ricerca del problema si è utilizzato uno sketch di esempio, atto a scaricare dei valori

da un sito francese(CO2 presente nell’aria) ed accendere delle lampade di un intensit√†

pari al valore letto.


Download
sketch di esempio

 

.
Da qui si inizia la ricerca del problema riconnesione wifi. Come prima soluzione si √® pensato di effettuare un reset di arduino via software utilizzando una funazione che punta all’indirizzo 0.

void(* Riavvia)(void) = 0;

Questo riavvia appunto arduino e quindi lo sketch ritenta la connessione attraverso l’istruzione nel setup “WiServer.init(NULL);” . I problemi per√≤ non sono del tutto risolti utilizzando questo metodo poich√® se la rete ritorna in tempi molto brevi la connessione risulta possibile, se per√≤ i tempi sono lunghi lo sketch si impalla sull’istruzione di inizializzazione¬†appena citata . Ecco che entra in gioco la modifica apportata alla libreria.
Ad essa, infatti, sono stati aggiunti dei metodi che permettano la connessione asincrona di arduino, permettendo così allo sketch di non bloccarsi durante il tentativo ( sia esito positivo o negativo che sia ) di connessione.

WiServer.async_init(sendMyPage, NULL);

Anche questo presenta degli svantaggi ma non del tutto impossibili da ovviare. Il difetto principale √® che anch’esso non riesce a collegarsi se la rete ritorna ad essere disponibile dopo tempi lunghi e a volte dopo una riconnessione parte dopo molto a scaricare gli eventuali dati dal sito richiesto. Di conseguenza si √® trovato una via di mezzo tra queste due soluzioni per ovviare qualsivoglia tipo di problema ( mostrer√≤ dopo il codice e la spiegazione di questa soluzione ). Come ultimo tentativo di soluzione si √® provato a collegare il pin di reset del modulo wifi ad un pin di arduino per mandarlo basso (lavora in logica negativa) e vedere se la riconnessione era possibile attraverso il suo riavvio.Si √® constatato che questo metodo porta gli stessi svantaggi dei metodi precedenti se non in aggiunta una modifica hardware allo shield.

Si è anche guardato un possibile utilizzo del watchdog ma essendo risultato inutile rimando la spiegazione a questo articolo di cosa consiste.

 

Ora la soluzione trovata è stata idealizzata pensando allo sviluppo di un datalogger ma può benissimo essere modificata per le proprie esigenze. Nella spegazione seguente non mi riferisco al datalogger ma semplicemente alla riconnessione dopo una perdita della rete.

Nel setup √® stata sostituita l’istruzione WiServer.init(NULL); con questo ciclo ( si suppone che nel monento in cui avvio lo sketch ¬†sono in presenza del wifi, altrimenti va modificata la partenza ) :

while(!WiServer.connection_up()){           
    WiServer.async_init(sendMyPage, NULL);     
if(WiServer.connection_up())
        WiServer.init(NULL);
    }

Finchè non mi collego veramente, tento la connessione attraverso il metodo asincrono async_init(sendaMyPage, NULL) così da evitare un eventuale blocco dello sketch derivante dalla init(NULL). Per ovviare la possibilità che avvenga la connessione attraverso tale metodo ma che non parti immediatamente il downliad effettuo una init(NULL) essendo sicuro che la connessione esiste davvero e che non si bloccherà lo sketch.

Nel loop(), nel momento in cui viene a mancare il segnale, si ha questo tipo di controllo:

if(!WiServer.connection_up()) {
    int i;
    for(i=0;i<300 && !WiServer.connection_up();i++){
¬† ¬† ¬† ¬† Serial.println(“Cerco di ricollegarmi”);
        server_up = WiServer.async_init(sendMyPage, NULL);
        delay(1000);
        Serial.println(i);
      }
   if(WiServer.connection_up() || i==300){
¬† ¬† ¬† ¬†Serial.println(“Riavvio i=” +i);
       delay(1000);
       Riavvia();}
}

Il ciclo for prosegue finchè o non trovo la connessione e quindi posso ricollegarmi ( viene effettuato un riavvio software precedentemente citato così da riportarsi nel setup ed escludere tutti i problemi ) oppure se sono passati 5 minuti.

Il riavvio effettuato dopo il passaggio dei 5 minuti ci solleva dal problema della connessione che ritorna dopo un tempo lungo ( o che non torna proprio). In sintesi se io provo a collegarmi ma la rete torna dopo molto che io proseguo con questi tentativi il modulo non riesce in ogni caso a collegarsi. Per effetto del riavvio, invece, il modulo torna ad essere in grado di effettuare un collegamento.

Qui il download dello sketch di esempio modificato in modo tale da presentare le diverse opzioni possibili per la connessione alla rete caduta. Spero sia abbastanza chiara.

Nel caso di un datalogger l’operazione di connessione e upload dei dati salvati su un sito viene effettuato solo nel momento in cui un eventuale sensore di movimento ci avvisa che siamo fermi. La ricerca della rete wifi continua finch√® il movimento non riparte oppure finch√® non mi collego veramente.

Ai prossimi articoli la spiegazione dei problemi e delle scelte effettuate per lo sviluppo di un datalogger.

 

 

Daniele Ruffo

5 pensieri su “WiFi shield e riconnessione alla rete

  1. Ciao,
    molto interessante il tuo articolo, complimenti.
    Ho realizzato questo progetto (termostato wifi):
    http://arduino.cc/forum/index.php/topic,99669.0.html
    Ho scaricato la tua libreria wifi e sono finalmente passato ad arduino 1.0.1 (prima usavo la versione 0023), ho dovuto solo eliminare dal mio codice la riga “#include ” e mettere al posto “#include “.
    Stasera provo a scaricare il codice nell’arduino e vedo se funziona tutto bene.
    Non ho problemi di disconnessione perch√© l’unico caso che pu√≤ capitare √® una mancanza di corrente e il router wifi √® pi√Ļ rapido a riavviarsi rispetto all’arduino.
    Il problema che ho √® la trasmissione della pagina web, mi spiego meglio: all’avvio e per qualche ora nessun problema, poi dopo un po’ di ore (o un po’ di giorni, dipende) l’arduino risulta connesso (risponde al ping) ma non trasmette pi√Ļ la pagina web, l’unico modo per risolvere √® riavviare.
    Questa cosa è molto fastidiosa perché ho realizzato il progetto apposta per accendere il riscaldamento da remoto in modo che quando arrivo trovo la casa calda. Hai qualche tipo di soluzione?

    Grazie

    • Ciao
      Prima di tutto grazie mille per esserti interessato
      Mi scuso per il ritardo ma vedo solo ora il commento avendo particolari problemi familiari che mi impediscono l uso di internet in modo frequente.
      Per quanto riguarda il tuo problema dovrei vedere pi√Ļ in dettaglio quel potrebbe essere il tuo problema, ma su due piedi opterei per una sorta di escamotage, almeno finche non si riesce a trovare la vera soluzione del problema (che potrebbe derivare anche da errori non tuoi, es librerie, o addirittura da limitazioni a livello hardware, ricordandoci che lavoriamo con micro controllori a 8bit !! ).
      Prova ad escogitare prendendo magari spunto dalla mia soluzione, un metodo che ti permetta di capire quando smette di inviare la pagina ed effettuare una riconnessione via software proprio come nel mio esempio.
      Questo ti permette di riavviare il Micro ogni qualvolta esso smetterà di inviare la pagina e non troverà problemi nella riconnessione in quanto, proprio come hai detto tu, non ci sono problemi di rete.
      Spero di essere stato esaustivo ( per quanto mi è possibile tramite un cellulare ) e spero che l esempio ti aiuti a capire cosa intendo.
      Buona fortuna e buon divertimento !!

      • Perdonami nella fretta e nella stanchezza della serata ho scritto una parola che magari potrebbe confonderti
        Il metodo che ti permette di capite quando smette di inviare la pagina ed effettua un riavvio tramite software del micro ūüėČ

        • Grazie, seguir√≤ il tuo consiglio appena avr√≤ un po’ di tempo per fare dei test.
          Per ora come “toppa” faccio riavviare l’arduino ogni 30 minuti con questa funzione:

          void softReset()
          {
          asm volatile (” jmp 0″);
          }

          Ho notato (ma forse √® solo un caso) che se mi collego con il browser da un normale PC windows l’arduino non va mai in quella situazione anomala.
          Se invece mi collego con il browser di un dispositivo android (telefono/tablet) dopo un po’ di collegamenti capita la situazione anomala (risponde al ping ma non trasmette la pagina web).
          Non so quindi se il problema √® il browser di android che invia troppe richieste e fa “impazzire” l’arduino.

          Grazie dei consigli ūüôā

          Giancarlo

          • Scusami ancora, ho solo paio di dubbi.
            Siccome nel mio codice nella funzione setup() a differenza del tuo esempio io passo la pagina web Thermostat:

            WiServer.init(Thermostat);

            Devo modificare così come segue?

            while(!WiServer.connection_up()){
            WiServer.async_init(Thermostat, NULL);
            if(WiServer.connection_up())
            WiServer.init(Thermostat);
            }

            Nella funzione loop quindi devo aggiungere quanto segue?

            if(!WiServer.connection_up()){
            int i;
            for(i=0;i<300 && !WiServer.connection_up();i++){
            Serial.println("Cerco di ricollegarmi");
            server_up = WiServer.async_init(Thermostat, NULL);
            Serial.println("L'ho superato");
            delay(1000);
            Serial.println(i);
            }
            if(WiServer.connection_up() || i==300){
            Serial.println("Riavvio i=" +i);
            delay(1000);
            Restart();
            }
            }

Lascia un commento