Pages: [1] 2   Go Down
Author Topic: explication de code  (Read 1353 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai une requete assez chiante, donc si ça ne se bouscule pas pour me répondre je comprendrais  smiley-mr-green

Alors voila un code ( qui soit dit en passant fonctionne très bien) dont pas mal de subtilités m'échappent :
Code:
#include <SPI.h>
#include <Ethernet.h>
#define LED 7

byte mac[] = {  0x92, 0xA2, 0xDA, 0x0D, 0x20, 0x63 };
byte ip[] = { 192, 168, 1, 177 };
char link[30], LEDStatus[4];

Server server(80);

void setup() {
  pinMode(7, OUTPUT);
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop() {
  Client client = server.available();
  if (client) {
    char request[10];
    int i = 0;
    boolean current_line_is_blank = true;
    request[9] = '\0';
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (i < 9) {
          request[i] = c;
          i++;
        }
        if (c == '\n' && current_line_is_blank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          client.println("<html><head><title>LampeChambre</title></head><body>");
          client.println("<h1>LampeIphoneChambre</h1>");
          client.println("<table>");
          client.print("<tr><td>Analog inputs:</td><td><b>");
          for (int x = 0; x < 6; x++) {
            client.print(x);
            client.print(" = ");
            client.print(5000 * (analogRead(x) / 1024.0));
            client.print(" mV<br>");
          }
          client.println("</b></td></tr><tr><td>uptime:</td> <td><b>");
          client.print(millis() / 1000.0);
          client.println(" seconds</b></td></tr>");
          if (strncmp("GET /off", request, 8) == 0) {
            digitalWrite(7, LOW);
            sprintf(LEDStatus, "OFF");
            sprintf(link, "<a href=\"/on\">Allumer</a>");
          }
          else {
            sprintf(LEDStatus, "ON");
            digitalWrite(7, HIGH);
            sprintf(link, "<a href=\"/off\">Eteindre</a>");
          }
          client.print("<tr><td>Lampe:</td> <td><b>");
          client.print(LEDStatus);
          client.println("</b></td></tr><tr><td colspan=\"2\" align=\"center\">");
          client.println(link);
          client.println("</td></tr></table></body></html>");
          break;
        }
        if (c == '\n') {
          current_line_is_blank = true;
        } else if (c != '\r') {
          current_line_is_blank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

j'aimerais qu'on m'explique ce que veulent dire les lignes suivantes en fait :
-
Code:
   char request[10];
    int i = 0;
    boolean current_line_is_blank = true;
    request[9] = '\0';
-
Code:
char c = client.read();
        if (i < 9) {
          request[i] = c;
          i++;
-
Code:
if (c == '\n' && current_line_is_blank)
-
Code:
for (int x = 0; x < 6; x++) {
            client.print(x);
            client.print(" = ");
            client.print(5000 * (analogRead(x) / 1024.0));
            client.print(" mV<br>");
-
Code:
if (strncmp("GET /off", request, 8) == 0)
-
Code:
if (c == '\n') {
          current_line_is_blank = true;
        } else if (c != '\r') {
          current_line_is_blank = false;

ca fait de gros bouts de code que je ne connais pas tout de meme ! smiley-sweat smiley-sweat
« Last Edit: August 13, 2012, 12:36:59 pm by kira » Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

Il y a pas mal de choses qui servent à générer une page HTML compréhensible par un navigateur.

Ce morceau là lit les 6 entrées analogiques de l'Arduino, fait un petit calcul et affiche les valeurs sur la page web :
Code:
for (int x = 0; x < 6; x++) {
    client.print(x);
    client.print(" = ");
    client.print(5000 * (analogRead(x) / 1024.0));
    client.print(" mV<br>");
Logged


Forum Moderator
Geneva
Offline Offline
Faraday Member
*****
Karma: 30
Posts: 3231
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Est ce que tu peux éditer ton message et mettre le code entre les balises "code" et pas "quote"  smiley-lol

Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci SesechXP, pour m'avoir éclairé sur le premier bout de code et désolé Jean-François, c'est réparé !  smiley
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

J'ai une requete assez chiante, donc si ça ne se bouscule pas pour me répondre je comprendrais  smiley-mr-green
Bon et bien c'est parti smiley-mr-green

-
Code:
    char request[10];
    int i = 0;
    boolean current_line_is_blank = true;
    request[9] = '\0';
1) Déclare un tableau de 10 char
2) Déclare une variable i de type int, initialisé à la valeur 0
3) Déclare une variable current_line_is_blank de type boolean, initialisé à la valeur true (vrai)
4) Clôture la chaine de caractéres ASCIIZ que représente le tableau "request"
(En C un chaine de caractéres est un tableau de char se terminant par '\0' = valeur 0)

-
Code:
char c = client.read();
        if (i < 9) {
          request[i] = c;
          i++;
1) Lit un octet depuis l'ethernet et le stock dans la variable "c" de type char
2) Si i est strictement inférieur à 9 alors :
3) l'octet en question est stocké dans la chaine de caractéres que représente le tableau "request" à l'index i
4) Incrémentation de i (i = i + 1)
--> Cette portion de code a pour but de stocker 9 octets lu depuis l'ethernet dans la chaine de caractére.

-
Code:
if (c == '\n' && current_line_is_blank)
-
Code:
if (c == '\n') {
          current_line_is_blank = true;
        } else if (c != '\r') {
          current_line_is_blank = false;
En protocole HTTP un entête de requête se termine par \n\r, ces deux morceaux de code ont pour but de détecter la fin d'entête.

-
Code:
for (int x = 0; x < 6; x++) {
            client.print(x);
            client.print(" = ");
            client.print(5000 * (analogRead(x) / 1024.0));
            client.print(" mV<br>");
Affiche 6 lignes (en html) correspondant au 6 entrées analogiques (valeur calculé en millivolts).

-
Code:
if (strncmp("GET /off", request, 8) == 0)
strcmp = "string compare" -> comparaison de deux chaines de caractéres.
Si la requête recu dans la variable "request" est égale à "GET /off" le code exécute le contenu du if.
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

super simpa la réponse aussi détaillée ! smiley
J'ai pas encore compris tout le code mais au moins j'ai les mots clefs pour chercher !

Et skywodd, je pense que tu devrais faire un tuto sur ton blog (si tu es bien le même skywodd que le skywood qui fait des tuto video :p ), qui expliquerait comment se servir de feuilles de styles qu'on aurait stocké dans une microSD insérée dans l'eternet shield !
C'est pas que j'en ai besoin hein, mais ça manque au blog  smiley-mr-green smiley-mr-green smiley-mr-green
Juste une idée hein !
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

En lisant attentivement toutes ces explications, je ne comprend pas une chose, où la variable request prend la valeur "GET /off" :/
Quote
Si la requête recu dans la variable "request" est égale à "GET /off" le code exécute le contenu du if.
C'est pas ultra simple tout ca :p
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ou sinon, n'y aurait il pas un moyen plus simple de controler l'etat de mes pin avec du code html, avec une case à coché dans, qui quand elle est cochée renvoi une valeur à l'arduino..
Je ne comprend pas bien ce code en fait, il me parait alambiqué ( j'ai surement tord hein, mais c'est l'effet que ça me donne)
Logged

Pays de la betise
Offline Offline
Sr. Member
****
Karma: 4
Posts: 419
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

Quote
En lisant attentivement toutes ces explications, je ne comprend pas une chose, où la variable request prend la valeur "GET /off" :

ici:

Code:
        if (i < 9) {
          request[i] = c;
          i++;
        }

c'est à dire lorsque tu décharges le buffer de l'ENC28J60 octet par octet.

Gromain
Logged

"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui ça j'avais à peu près compris, mais les octets, ou prennent ils leurs valeurs ?
Et au fait simpa ton site Gromain smiley
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 224
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A cette ligne :
Code:
char c = client.read();
On vient lire ce qui arrive sur la liaison Ethernet.
Logged


Pays de la betise
Offline Offline
Sr. Member
****
Karma: 4
Posts: 419
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Oui ça j'avais à peu près compris, mais les octets, ou prennent ils leurs valeurs ?
Le contrôleur Ethernet ENC28J60 ou Wiznet (selon le shield) reçoit des paquets TCP/UDP en provenance du réseau.
Il fait un premier tri pour n'accepter dans son buffer Rx que les paquets qui t'intéresse.
Ton code interroge le contrôleur via le bus SPI pour savoir s'il a reçu des données. Si c'est le cas, il récupère octet par octet le paquet, toujours via le bus.
Dans le cas d'un Wiznet, l'arduino ne reçoit que la partie data du paquet. Pour l'ENC28J60, c'est le paquet complet qui est récupéré (en-tête+data). A ton code (ou la lib) d'extraire les datas.

Avec un logiciel comme Wireshark tu peux écouter le réseau local et voir passer toutes les données. Chaque paquet aura une en-tête qui précise les ports et adresses mac et IP de la source et de la destination.

Gromain
Logged

"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hum d'accord mais qu'es-ce qui fait qu'on retrouve "GET / OFF" dans les data ? :/
je comprend vite mais il faut m'expliquer longtemps.. désolé  smiley-mr-green
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 86
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

enfait, je voudrais arriver à gérer une autre entrée avec un autre lien par exemple..
L'idéal serait mêmede pouvoir entrer une valeur dans la page généré, valeur qui déterminerais l'Etat d'un pin PWM.. pour par exemple diriger ma lampe avec un servo.. :p
Logged

Pays de la betise
Offline Offline
Sr. Member
****
Karma: 4
Posts: 419
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
qu'est-ce qui fait qu'on retrouve "GET / OFF" dans les data ?

En simplifiant:
"GET / OFF" fait partie d'une requête HTTP, envoyée par le client au serveur (ici l'arduino). Cette requête HTTP (couche applicative) est encapsulée dans un paquet TCP/IP (couche transport, géré par le wiznet), contenant une en-tête (IP, mac, port...).
Donc du point de vue réseau, "GET /OFF" fait partie des datas.

Pour arriver à tes fins, je te conseille de t'intéresser aux grandes lignes de la pile TCP/IP et au protocole HTTP (cf wikipedia par ex). En supposant que le HTML ne te pose pas de problème smiley-wink

Gromain
« Last Edit: August 14, 2012, 02:08:58 pm by Gromain59 » Logged

"pour résoudre un gros problème, il est souvent plus facile de le diviser en petits problèmes élémentaires..."

projet domotique xPLDuino
IRC: freenode #xplduino

Pages: [1] 2   Go Up
Jump to: