Le wifi shield

Accueil/Le wifi shield
Le wifi shield 2016-12-20T11:38:33+00:00

Project Description

Le Wifi est très courant de notre vie de tous les jours, en effet rare sont les habitations qui n’ont pas de réseau Wifi. Ce moyen de communication présente plusieurs avantages, il est tout d’abord très rapide, mais aussi profite d’une portée conséquente, d’environ 20m. Alors pourquoi ne pas en faire profiter votre Arduino pour interagir avec le web? Heureusement pour nous, l’équipe officielle d’Arduino nous a designé un shield bien pratique! Nous allons voir comment l’utiliser.

Matériel

Pour réaliser ce tutoriel il faudra vous munir de :

Si votre Arduino n’est pas une R3 ou supérieur (si vous avez 8 pins au bloc d’alimentation , vous avez un modèle R3 ou plus), il vous faudra relier le pin IOREF (celui au dessus du reset) du shield Arduino au pin +3.3V du shield, soit avec un câble soit avec une soudure à exécuter en dessous du shield.Ensuite, branchez simplement votre shield sur la carte Arduino en alignant les pins du SPI, branchez votre Arduino à votre PC et vérifiez que votre réseau Wifi est bien allumé.

Les commandes de bases

Après avoir branché le shield sur la carte, il est tant de intéresser à la bibliothèque Wifi officielle. Celle-ci est relativement simple d’utilisation, si vous avez déjà utilisé le shield Ethernet, alors vous constaterez de grandes similitudes.

Dans un tout premier temps, il faut inclure deux librairies, la SPI, pour communiquer avec le shield et la wifi pour faciliter cette communication.

#include <SPI.h>
#include <WiFi.h>

Ensuite, pour démarrer la liaison wifi, il existe une fonction très simple : begin. En fonction du type de connexion (sans mot de passe, WPA, WEP), il vous faudra soit seulement le nom du réseau, soit son nom et le mot de passe, et dans le cas du WEP rajouter son KeyIndex. Cela nous donne les lignes suivantes :

char ssid[] = "monreseau";

char pass[] = "motdepasse";

int keyIndex = 0;

int status = WL_IDLE_STATUS;

void setup() {

status = WiFi.begin(ssid); // reseau sans mot de passe

status = WiFi.begin(ssid, pass); // connection WPA (le plus courant)

status = WiFi.begin(ssid, keyIndex, pass); //connection WEP

}

Vous remarquerez que j’ai récupérer le retour de la fonction begin dans la variable status, cela me permet de vérifier à le statut du shield (connecté, absent…), cela nous permet de rajouter quelques sécurités, comme celle-ci qui vérifie que le shield est bien présent (notez bien que dans ce cas ce n’est pas la variable status mais une fonction de la librairie, car on n’a pas encore appelé la fonction begin) et que l’on est bien connecté :

char ssid[] = "monreseau";

char pass[] = "motdepasse";

int keyIndex = 0;

int status = WL_IDLE_STATUS;

void setup() {

Serial.begin(9600);
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield non connecte"); 
    // don't continue:
    while(true);
  } 
status = WiFi.begin(ssid); // reseau sans mot de passe

status = WiFi.begin(ssid, pass); // connection WPA (le plus courant)

status = WiFi.begin(ssid, keyIndex, pass); //connection WEP
delay(10000);
 if ( status != WL_CONNECTED) { 
    Serial.println("Erreur de connexion");
    while(true);
  }
  else {
    Serial.println("Shield connecte au reseau!");
  }

}

Mais il existe une manière plus intelligente de tester si l’on est connecté, en effet, on peut faire une boucle que tourne en boucle tant que l’on est pas connecté, cela ressemble à ce bout de code :

while (status != WL_CONNECTED) { 
    Serial.print("Tentative de connexion au reseau: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, pass); 
    // wait 10 seconds for connection:
    delay(10000);
  } 
  Serial.println("Connecte au wifi");

Ensuite, il peut être utilise d’afficher les différents paramètre du shield une fois connecté, pour retrouver son IP local par exemple, pour cela, la documentation d’Arduino nous fournit une fonction toute faite :

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Voila, il me semble que vous êtes bon au niveau des réglages! Nous allons ensuite passer aux deux fonctions du shield : le serveur et le client.

Le mode serveur

Voila un exemple de la documentation officielle Arduino, qui affiche une page web contenant la valeur de 6 potentiomètres reliés à l’Arduino. Nous allons décortiquer le code ensemble :

/*
  WiFi Web Server
 
 A simple web server that shows the value of the analog input pins.
 using a WiFi shield.
 
 This example is written for a network using WPA encryption. For 
 WEP or WPA, change the Wifi.begin() call accordingly.
 
 Circuit:
 * WiFi shield attached
 * Analog inputs attached to pins A0 through A5 (optional)
 
 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe

 */

#include <SPI.h>
#include <WiFi.h>


char ssid[] = "yourNetwork";      // your network SSID (name) 
char pass[] = "secretPassword";   // your network password
int keyIndex = 0;                 // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

WiFiServer server(80);

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  } 
  server.begin();
  // you're connected now, so print out the status:
  printWifiStatus();
}


void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    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
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          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
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            int sensorReading = analogRead(analogChannel);
            client.print("analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(sensorReading);
            client.println("<br />");       
          }
          client.println("</html>");
           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
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

En tête de ce programme, on retrouve une nouvelle variable : WiFiServer server(80); La variable server est en fait la variable dont on va se servir pour utiliser notre serveur, que ce soit pour récupérer les clients, leur envoyer des donnés ou en recevoir. Quand au nombre 80, il indique le port sur lequel le serveur va « écouter », il faut savoir que l’on peut se connecter à un serveur sur différents ports, en fonction de l’organisation de celui-ci, par exemple le port 22 est en général pour le FTP. Le port par defaut des requetes HTTP, c’est à dirre le port par defaut de votre navigateur web est le port 80, c’est pourquoi on met ici 80 comme port. Si vous changez ce nombre, il faut dans votre navigateur rajouter le port de connexion de cette facon : VOTREIP:PORT (ex -> 192.168.0.21:8080).

Ensuite vient tout la partie d’initialisation que l’on a déjà vu ensemble. Mais on remarque aussi le server.begin () qui comme son nom l’indique démarre le serveur.

Puis vient la partie intéressante. Dans la fonction loop() de notre programme on regarde si un client essaye de se connecter à notre serveur de cette façon :

WiFiClient client = server.available();
if (client) {
Serial.println(« nouveau client »);

}

Le server.available renvoie une variable de type client si un client essaye de se connecter, on récupère cette variable et on regarde si elle vaut quelque chose grâce au if. Si elle vaut quelque chose alors on va pouvoir faire des manipulations avec.

Ces manipulations sont un peu plus complexes à comprendre mais rien de bien inquiétant. Tout d’abord, on peut récupérer les caractère que nous envoie le client à l’aide de client.read(); qui marche comme pour la liaison série en quelque sorte. On sait aussi qu’une requête HTTP finie par une ligne blanche, autrement dit, lorsque l’on trouvera deux /n la requête sera terminée et on pourra écrire notre réponse. On peut donc maintenant comprendre le code suivant :

if (client) {
Serial.println("new client");
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);

if (c == '\n' && currentLineIsBlank) {
// le requete est finie, on peut donner notre reponse.

// pour ecrire vos propres reponses, renseignez vous sur le protocol HTTP, voila une reponse classique
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println("Refresh: 5");
client.println();

// maintenant place au code HTML
client.println("<!DOCTYPE HTML>");
client.println("<html>");
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
break;
}
if (c == '\n') {
// On commence une nouvelle ligne
currentLineIsBlank = true;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
Serial.println("client deconnecte");
}

Comme vous l’aurez vu, dès que le client se déconnecte, on appelle la fonction client.stop() pour stopper la connexion de notre coté aussi.

Voila, vous savez maintenant programmer un serveur web avec votre Arduino, notez bien que vous n’êtes pas obligés de suivre le protocole HTTP mais que vous pouvez aussi inventer les vôtres si vous avez des besoins spécifiques.

Le mode client

Voila maintenant un code, pris de la documentation officielle encore une fois, qui envoie par liaison série la réponse HTML de google sur la recherche de « tutoarduino », nous allons de la même façon décortiquer ce code :

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using a WiFi shield.
 
 This example is written for a network using WPA encryption. For 
 WEP or WPA, change the Wifi.begin() call accordingly.
 
 This example is written for a network using WPA encryption. For 
 WEP or WPA, change the Wifi.begin() call accordingly.
 
 Circuit:
 * WiFi shield attached
 
 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe
 */


#include <SPI.h>
#include <WiFi.h>

char ssid[] = "yourNetwork"; //  your network SSID (name) 
char pass[] = "secretPassword";    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.google.com";    // name address for Google (using DNS)

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid, pass);
  
    // wait 10 seconds for connection:
    delay(10000);
  } 
  Serial.println("Connected to wifi");
  printWifiStatus();
  
  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /search?q=arduino HTTP/1.1");
    client.println("Host: www.google.com");
    client.println("Connection: close");
    client.println();
  }
}

void loop() {
  // if there are incoming bytes available 
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Dans ce code, on retrouve deux nouvelles variables, une chaîne de caractère server qui contient l’URL du serveur auquel on veut se connecter, cela peut aussi être une IP. Et une variable de type WifiClient que l’on a déjà rencontré auparavant, qui va nous servir à interagir avec le serveur de google.

Ensuite on retrouve le bout de code concernant la connexion. On utilise la fonction connect(URL, PORT) pour ce connecter au serveur en question, cette fonction renvoie true ou false, ce qui nous permet de tester son succès. Ensuite, on trouve dans cette même partie l’envoi de la requete HTTP, pour plus de renseignement sur ce protocole, je vous conseille cette page qui est une bonne introduction. Vous pouvez maintenant comprendre le code suivant :

if (client.connect(server, 80)) {
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /search?q=arduino HTTP/1.1");
client.println("Host: www.google.com");
client.println("Connection: close");
client.println();
}

Ensuite, on peut agir dans la fonction loop() comme en quelque sorte avec une liaison série, on utilise la fonction read() pour lire les caractères envoyés, et on peut dans cet exemple les envoyer par liaison série, ce qui nous donne ce code :

while (client.available()) {
char c = client.read();
Serial.write(c);
}

Enfin, il faut penser à vérifier que l’on est toujours connecté au serveur, pour pouvoir fermer la connexion au besoin , pour cela, il existe la fonction connected() qui renvoie true ou false, on arrive donc à ce bout de code :

if (!client.connected()) {
Serial.println();
Serial.println("deconnecte du server");
client.stop();

// on arrete le programme
while(true);
}

Et voila, ce tutoriel touche à sa fin ,normalement vous êtes capables de manipuler votre shield comme vous le souhaitez. Pour plus de détails sur des fonctions plus techniques, pensez à vous rendre sur la documentation officielle ou à poser une question en commentaire ou sur notre forum, réponse rapide assurée!!

8 Commentaires

  1. Nikki 20 février 2015 à 3 h 31 min␣- Répondre

    thanks you so much, i love french website like this one <3

  2. fabrice54 22 août 2015 à 2 h 44 min␣- Répondre

    Bonjour.

    Je viens de voir votre tuto sur les shields Wifi qui est très intéressant.Mais il y a un point de détail qui n’est pas très clair pour moi. Ce que je ne comprend pas ,est la procédure pour entrer en communication avec mon arduino?.
    Explication,si je suis sur google je tape l’adresse ip de mon shield arduino avec un mot de passe + un caractère ,sur lequel j’ effectue un traitement ou est ce différent?.C’est pour une petite application domotique car j’habite la Réunion et ma mère habite en seine et marne et je voudrais pouvoir de chez moi commander différents éléments chez elle.
    Merci.

    • ! 20 novembre 2015 à 8 h 39 min␣- Répondre

      Je t’apperais ca dans l’URL nan ?

    • Albator_123 9 mai 2016 à 19 h 33 min␣- Répondre

      Tu ne peux pas accéder directement à ses équipements… car tu ne vois pas l’IP du shield depuis l’exterieur de la maison…
      Sinon il faut que tu fasses des routes IP sur le routeur de la maison… pour acceder au shield…

  3. ! 20 novembre 2015 à 8 h 36 min␣- Répondre

    nouveauuuuuuuuuuu.ino: In function ‘void setup()’:
    nouveauuuuuuuuuuu.ino:30:31: error: ‘pass’ was not declared in this scope
    Erreur lors de la compilation.

    Que faire ? merci !

    • Dayana 6 octobre 2016 à 10 h 58 min␣- Répondre

      That’s really thiinnkg of the highest order

    • Marie Madeleine shalom a vous,Je vous souhaite la bienvenue parmi nous. N’hesitez pas a intervenir. Je m’efforcerai de repondre aux questions qui seront les votres.C’est moi qui vous remercie,Cordial shalom,Haim O.

  4. madara 16 mai 2016 à 22 h 14 min␣- Répondre

    mon schild wifi n’est pas detecter comment faire ???

Laisser un commentaire