Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino PhP

Web serveur arduino avec PhP

    31 mars 2015 à 9:56:22

    Bonjour, je suis en Terminale STI2D Sin. Je dois, pour mon projet de bac, créer un serveur web avec Arduino, sur lequel des variables doivent être affichées, et un message programmé affiché en fonction de ces variables. J'arrive parfaitement a afficher les variables d'arduino sur le site (je précise que j'utilise une carte SD sur mon shield ethernet, laquelle contient les pages web), mais mon souci réside dans le fait d'écrire avec un formulaire, (mon prof m'a dit d'utiliser PhP) le message prédéfini directement sur le site. Mais PhP n'a pas l'air de fonctionner sur Arduino, et je ne sais pas trop comment m'y prendre. Je vous met ici les différents codes que j'ai déjà produit :

    Code Arduino :

    /*--------------------------------------------------------------
     Program:      eth_websrv_SD_Ajax_XML
     
     Description:  Arduino web server that serves up a web page
     that displays the status of two switches and
     one analog input.
     The web page is stored on the SD card.
     The web page contains JavaScript code that uses
     Ajax and XML to get the states of the switches
     and value of the analog input.
     
     Hardware:     Arduino Uno and official Arduino Ethernet
     shield. Should work with other Arduinos and
     compatible Ethernet shields.
     2Gb micro SD card formatted FAT16.
     Push button switches interfaced to pin 7 and 8
     of the Arduino. Potentiometer interfaced to A2
     analog input.
     
     Software:     Developed using Arduino 1.0.5 software
     Should be compatible with Arduino 1.0 +
     SD card contains web page called index.php
     
     References:   - WebServer example by David A. Mellis and 
     modified by Tom Igoe
     - SD card examples by David A. Mellis and
     Tom Igoe
     - Ethernet library documentation:
     http://arduino.cc/en/Reference/Ethernet
     - SD Card library documentation:
     http://arduino.cc/en/Reference/SD
     
     Date:         27 March 2013
     Modified:     17 June 2013
     - removed the use of the String class
     
     Author:       W.A. Smith, http://startingelectronics.com
     --------------------------------------------------------------*/
    
    #include <SPI.h>
    #include <Ethernet.h>
    #include <SD.h>
    
    // size of buffer used to capture HTTP requests
    #define REQ_BUF_SZ   50
    
    File myFile;
    // MAC address from Ethernet shield sticker under board
    byte mac[] = { 
      0x90, 0xA2, 0xDA, 0x00, 0x7D, 0x15 };
    IPAddress ip(192, 168, 231, 56); // IP address, may need to change depending on network
    EthernetServer server(80);  // create a server at port 80
    File webFile;               // the web page file on the SD card
    char HTTP_req[REQ_BUF_SZ] = {
      0}; // buffered HTTP request stored as null terminated string
    char req_index = 0;              // index into HTTP_req buffer
    
    void setup()
    {
      // disable Ethernet chip
      pinMode(10, OUTPUT);
      digitalWrite(10, HIGH);
    
      Serial.begin(9600);       // for debugging
    
      // initialize SD card
      Serial.println("Initializing SD card...");
      if (!SD.begin(4)) {
        Serial.println("ERROR - SD card initialization failed!");
        return;    // init failed
      }
      Serial.println("SUCCESS - SD card initialized.");
      // check for index.php file
      if (!SD.exists("index.php")) {
        Serial.println("ERROR - Can't find index.php file!");
        return;  // can't find index file
      }
      Serial.println("SUCCESS - Found index.php file.");
      pinMode(7, INPUT);        // switch is attached to Arduino pin 7
      pinMode(8, INPUT);        // switch is attached to Arduino pin 8
    
      Ethernet.begin(mac, ip);  // initialize Ethernet device
      server.begin();           // start to listen for clients
      myFile = SD.open("test.txt", FILE_WRITE);
      // if the file opened okay, write to it:
      if (myFile) {
        Serial.print("Writing to test.txt...");
        myFile.println("testing 1, 2, 3.");
    	// close the file:
        myFile.close();
        Serial.println("done.");
      } else {
        // if the file didn't open, print an error:
        Serial.println("error opening test.txt");
      }
      
      // re-open the file for reading:
      myFile = SD.open("test.txt");
      if (myFile) {
        Serial.println("test.txt:");
        
        // read from the file until there's nothing else in it:
        while (myFile.available()) {
        	Serial.write(myFile.read());
        }
        // close the file:
        myFile.close();
      } else {
      	// if the file didn't open, print an error:
        Serial.println("error opening test.txt");
      }
    }
    
    void loop()
    {
      EthernetClient client = server.available();  // try to get client
    
      if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
          if (client.available()) {   // client data available to read
            char c = client.read(); // read 1 byte (character) from client
            // buffer first part of HTTP request in HTTP_req array (string)
            // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
            if (req_index < (REQ_BUF_SZ - 1)) {
              HTTP_req[req_index] = c;          // save HTTP request character
              req_index++;
            }
            // last line of client request is blank and ends with \n
            // respond to client only after last line received
            if (c == '\n' && currentLineIsBlank) {
              // send a standard http response header
              client.println("HTTP/1.1 200 OK");
              // remainder of header follows below, depending on if
              // web page or XML page is requested
              // Ajax request - send XML file
              if (StrContains(HTTP_req, "ajax_inputs")) {
                // send rest of HTTP header
                client.println("Content-Type: text/xml");
                client.println("Connection: keep-alive");
                client.println();
                // send XML file containing input states
                XML_response(client);
              }
              else {  // web page request
                // send rest of HTTP header
                client.println("Content-Type: text/html");
                client.println("Connection: keep-alive");
                client.println();
                // send web page
                webFile = SD.open("index.php");        // open web page file
                if (webFile) {
                  while(webFile.available()) {
                    client.write(webFile.read()); // send web page to client
                  }
                  webFile.close();
                }
              }
              // display received HTTP request on serial port
              Serial.print(HTTP_req);
              // reset buffer index and all buffer elements to 0
              req_index = 0;
              StrClear(HTTP_req, REQ_BUF_SZ);
              break;
            }
            // every line of text received from the client ends with \r\n
            if (c == '\n') {
              // last character on line of received text
              // starting new line with next character read
              currentLineIsBlank = true;
            } 
            else if (c != '\r') {
              // a text character was received from client
              currentLineIsBlank = false;
            }
          } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
      } // end if (client)
    }
    
    // send the XML file with switch statuses and analog value
    void XML_response(EthernetClient cl)
    {
      int analog_val;
    
      cl.print("<?xml version = \"1.0\" ?>");
      cl.print("<inputs>");
      cl.print("<button1>");
      if (digitalRead(7)) {
        cl.print("ON");
      }
      else {
        cl.print("OFF");
      }
      cl.print("</button1>");
      
      cl.print("<button2>");
      analog_val = 58;
      cl.print(analog_val);
    
      cl.print("</button2>");
      // read analog pin A2
      analog_val = analogRead(2);
      analog_val = 750;
      cl.print("<analog1>");
      cl.print(analog_val);
      cl.print("</analog1>");
      cl.print("</inputs>");
    
      
    }
    
    // sets every element of str to 0 (clears array)
    void StrClear(char *str, char length)
    {
      for (int i = 0; i < length; i++) {
        str[i] = 0;
      }
    }
    
    // searches for the string sfind in the string str
    // returns 1 if string found
    // returns 0 if string not found
    char StrContains(char *str, char *sfind)
    {
      char found = 0;
      char index = 0;
      char len;
    
      len = strlen(str);
    
      if (strlen(sfind) > len) {
        return 0;
      }
      while (index < len) {
        if (str[index] == sfind[found]) {
          found++;
          if (strlen(sfind) == found) {
            return 1;
          }
        }
        else {
          found = 0;
        }
        index++;
      }
    
      return 0;
    }
    
    

    Merci d'avance et bonne journée !

    • Partager sur Facebook
    • Partager sur Twitter
    Je ferai en sorte que ce soit lui qui me trouve
      31 mars 2015 à 20:09:32

      Il est marrant ton prof... (typiquement, il te dit PHP parce qu'il connait ça de nom mais il ne sait pas à quoi ça correspond).

      Serte, PHP est un langage extrêmement puissant pour gérer des pages WEB très facilement.

      Sauf que PHP est un langage haut niveau interprété par un système d'exploitation (Linux, Windows, Mac) et n'est donc clairement pas compatible avec arduino.

      L'arduino, ça ne se programme qu'en C ou C++ et rien d'autre (ou éventuellement en ASM pour les courageux).

      Pour que l'arduino récupère les données du formulaire, il fait donc analyser correctement le header HTTP envoyé par le navigateur.

      Concrètement, lorsque l'utilisateur va envoyer le formulaire, le navigateur internet va se connecter à ton arduino et envoyer un truc de ce genre :

      POST /url/tapage.html HTTP/1.1
      Host: online.roboform.com
      User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
      [...]
      Connection: keep-alive
      
      value1=data1&value2=data2&value3=data3
      

      La première ligne que le navigateur envoie correspond à la page qu'il demande (en claire, l'adresse pointée par le formulaire).

      Dans mon exemple, le navigateur demande donc à charger la page /url/tapage.html

      Ensuite, il y a pleins de lignes plus ou moins utile pour toi.

      Puis une ligne vide.

      Et après cette ligne vide se trouve le contenu que l'utilisateur a rempli dans le formulaire.

      Ce contenu est de la forme : NomDuChamp=Valeur&NomDuChampSuivant=Valeur&...

      Dans mon exemple, l'utilisateur donc envoyé en formulaire de 3 champs :

      - "data1" dans le <input name="value1" />

      - "data2" dans le <input name="value2" />

      - "data3" dans le <input name="value3" />

      Maintenant que tu connais la théorie, c'est à toi de jouer ;)

      -
      Edité par lorrio 31 mars 2015 à 20:13:24

      • Partager sur Facebook
      • Partager sur Twitter
        31 mars 2015 à 20:16:30

        Sur ta ligne 122, tu as : char c = client.read(); // read 1 byte (character) from client

        Je te conseille vivement d'ajouter ceci juste après : Serial.print(c); // debug the received byte

        Ainsi, ton arduino devrait t'afficher tout ce que le client/navigateur envoie sur la console Serial.

        Cela te permettra de bien voir à quoi ressemble le header HTTP dont je te parle et de voir ou se trouve tes données qui t’intéresses.

        Je te conseille aussi de supprimer temporairement la ligne 160 : Serial.print(HTTP_req); de façon à ce que ce print n'interfère pas avec le print de debug.

        -
        Edité par lorrio 31 mars 2015 à 20:19:02

        • Partager sur Facebook
        • Partager sur Twitter
          2 avril 2015 à 8:39:06

          Bonjour lorrio et merci a toi de m'avoir répondu.

          J'ai pas bien saisi comment créer un formulaire du coup o_O C'est sur la page Web qui est stockée sur ma carte SD qu'il faut que je le mette ! Mais sans PhP, comment faire ? De plus, quand tu dit qu'il faut un système d'exploitation pour interpréter le PhP, tu veux dire que la carte SD n'est pas en mesure de le faire ? 

          Je viens de me rendre compte que je ne t'ai pas indiqué mon code HTML, peut être que ce sera plus clair pour toi ? :)

          En tout cas merci pour ton aide

          <!DOCTYPE html>
          <html>
              <head>
                  <title>Programme exemple NON MODIFIE ! Fonctionne avec le programme d'exemple d'arduino</title>
                  <script>
                  function GetArduinoInputs()
                  {
                      nocache = "&nocache=" + Math.random() * 1000000;
                      var request = new XMLHttpRequest();
                      request.onreadystatechange = function()
                      {
                          if (this.readyState == 4) {
                              if (this.status == 200) {
                                  if (this.responseXML != null) {
                                      // extract XML data from XML file (containing switch states and analog value)
                                      document.getElementById("input1").innerHTML =
                                          this.responseXML.getElementsByTagName('button1')[0].childNodes[0].nodeValue;
                                      document.getElementById("input2").innerHTML =
                                          this.responseXML.getElementsByTagName('button2')[0].childNodes[0].nodeValue;
                                      document.getElementById("input3").innerHTML =
                                          this.responseXML.getElementsByTagName('analog1')[0].childNodes[0].nodeValue;
                                  }
                              }
                          }
                      }
                      request.open("GET", "ajax_inputs" + nocache, true);
                      request.send(null);
                      setTimeout('GetArduinoInputs()', 1000);
                  }
              </script>
              </head>
              <body onload="GetArduinoInputs()">
                  <h1>Arduino Inputs from SD Card Web Page using Ajax with XML</h1>
                  <p>Button 1 (pin 7): <span id="input1">...</span></p>
                  <p>Button 2 (pin 8): <span id="input2">...</span></p>
                  <p>Analog (A2): <span id="input3">...</span></p>
          		
          		<?php
          $monfichier = fopen('TEST.txt', 'r+');
           
          $pages_vues = fgets($monfichier); // On lit la première ligne (nombre de pages vues)
          $pages_vues++; // On augmente de 1 ce nombre de pages vues
          fseek($monfichier, 0); // On remet le curseur au début du fichier
          fputs($monfichier, $pages_vues); // On écrit le nouveau nombre de pages vues
           
          fclose($monfichier);
           
          echo '<p>Cette page a été vue'. $pages_vues .'fois !</p>';
          ?> 
              </body>
          </html>                                                                                                              

          Ici, il y a aussi un compteur de vue sur le site, pour voir si un fichier .txt peut faire la jonction :)

          EDIT : J'ai trouver cette petite réponse, je vais tenter de l'exploiter :')

          http://stackoverflow.com/questions/22643244/ethernet-shield-sending-data-from-web-to-arduino-using-html-form



          -
          Edité par LeMajorXepso 2 avril 2015 à 9:09:46

          • Partager sur Facebook
          • Partager sur Twitter
          Je ferai en sorte que ce soit lui qui me trouve
            2 avril 2015 à 10:24:55

            Une carte SD, c'est juste un support de stockage qui retient ton fichier, rien de plus.

            Voici ce qu'il se passe sur un vrai serveur WEB (genre le serveur d'OpenClassRoom par exemple) en HTML :

            Le serveur lit le header HTTP envoyé par le client, en déduit l'URL que le client demande et va chercher le fichier sur le disque dure (carte SD dans ton cas).

            Vu que c'est un fichier HTML, il n'y a pas grand chose à faire : le serveur se contente de lire le fichier et l'envoyer tel que.

            Voici ce qu'il se passe sur un vrai serveur WEB (genre le serveur d'OpenClassRoom par exemple) en PHP :

            Là encore, le serveur lit le header HTTP envoyé par le client, en déduit l'URL que le client demande et va chercher le fichier sur le disque dure.

            Mais cette fois ci, il ne se contente pas de lire et envoyer en brut.

            Dans un premier temps, il lit le fichier et envoie son contenu tout en cherchant une balise <?php

            Dès qu'il en trouve une, il arrête d'envoyer le contenu au client et continue de lire jusqu'à trouver la balise ?>

            Une fois qu'il a trouvé ces 2 balises, le serveur balance ce qu'il a lu sur un interpréteur de code PHP de façon à ce que celui-ci soit exécuté.

            Ainsi, si ton fichier contient <?php echo (2 + 2); ?> alors le serveur va exécuter echo (2 + 2); et donc envoyer 4 au client.

            Voici ce qu'il se passe sur ton petit arduino :

            Ton code est vraiment basique puisque tu fais ceci :

            if (webFile) {
                while(webFile.available()) {
                    client.write(webFile.read()); // send web page to client
                }
                webFile.close();
            }

            En clair, que ton fichier soit un fichier HTML ou un fichier PHP, ton arduino se contente de lire ce fichier et l'envoyer au client.

            Du coup, si c'est un fichier PHP qui contient <?php echo (2 + 2); ?>, ton arduino ne va rien exécuter du tout en envoyer <?php echo (2 + 2); ?> au client.

            Idem si ton fichier PHP contient du code servant à traiter un formulaire : ce code ne sera pas exécuté mais envoyé au client.

            Bref, ça ne sert à rien de faire du PHP sur un arduino.

            -
            Edité par lorrio 2 avril 2015 à 10:25:43

            • Partager sur Facebook
            • Partager sur Twitter
              2 avril 2015 à 10:47:33

              D'accord, merci !:)  Mais du coup, je dois passer par quel moyen pour éditer mes seuils et mon messages ?
              • Partager sur Facebook
              • Partager sur Twitter
              Je ferai en sorte que ce soit lui qui me trouve
                2 avril 2015 à 17:25:20

                Rien ne t’empêche d'utiliser un formulaire et des pour poster des données à ton arduino.

                Il faut juste que tu prennes en compte que c'est à toi de gérer la réception de ces données pour les traiter.

                pour le moment, aucun des codes que tu as posté ne contient un formulaire donc ça va être difficile t'aider d'avantage.

                -
                Edité par lorrio 2 avril 2015 à 17:25:33

                • Partager sur Facebook
                • Partager sur Twitter
                  11 avril 2015 à 19:48:42

                  Bonjour Mr lorrio, je suis en 3éme année (Faculté des Sciences et Techniques)(Ingénieurie Electronique et Télécommunication). Je dois, pour mon projet de fin d’étude, Réaliser un serveur web à base du Arduino.

                  Le projet consiste à utiliser la carte fille Ethernet de l’ARDUINO pour communiquer avec ce dernier via Internet,et pouvoir gérer ces E/S à distance..

                  Plan du travail :+ se familiariser avec le langage C/C++

                                              + se familiariser avec le langage HTML

                  J'arrive parfaitement a afficher les variables d'arduino sur le site (je précise que j'utilise une carte SD sur mon Seild Ethernet, laquelle contient les pages web).. mon prof m'a dit d'utiliser HTML..

                  Donc j’ai commencé à écrire mon code sur ARDUINO mais j’ai pas encore terminer mon programme. C’est pour cela je veux demander svp pour tu m’aider si possible.

                  Code Arduino :

                  #include <SPI.h>

                  #include <Ethernet.h>

                  #include <SD.h>

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

                  IPAddress ip(172,16,22,249);

                  EthernetServer server(80);

                  void setup() {

                   Serial.begin(9600);

                     while (!Serial) {

                      ;

                    }

                    pinMode(10, OUTPUT);

                    Ethernet.begin(mac,ip);

                    server.begin();

                    Serial.print("server is at ");

                    Serial.println(Ethernet.localIP());

                    if (!SD.begin(4)) {

                      Serial.println("initialization SD failed!");

                      return;

                    }else{

                        Serial.println("SD ok .");

                    }

                  }

                  #define BUFFER_SIZE 128

                  #define PATH_SIZE 128

                  #define PARAMS_SIZE 128

                  char buffer[BUFFER_SIZE];

                  char tmp[BUFFER_SIZE];

                  struct HTTPDATA {

                    boolean isGET;

                    char path[PATH_SIZE];

                    char params[PARAMS_SIZE];

                  };

                  File myFile;

                  char sending;

                  void loop() {

                   EthernetClient client = server.available();

                    if (client) {

                      Serial.println("---");

                      HTTPDATA info=httpRequest(client);

                      if(info.isGET){

                        sendPage(info.path,client,0);

                      }

                      Serial.println(info.isGET);

                      Serial.println(info.path);

                      Serial.println(info.params);

                      Serial.println("---");

                      client.stop();

                    }

                  }

                  struct HTTPDATA httpRequest(EthernetClient client){

                    while (client.connected()) {

                        if (client.available()) {

                          int bufferIndex;

                          char c;

                          HTTPDATA data;

                          data.isGET=true;

                          data.path[0]='\0';

                          data.params[0]='\0';

                          buffer[0]=client.read();

                          buffer[1]=client.read();

                          bufferIndex=2;

                          while(buffer[bufferIndex-2] !='\r' && buffer[bufferIndex-1] != '\n'){

                            c=client.read();

                           if(bufferIndex<BUFFER_SIZE) buffer[bufferIndex]=c;

                            bufferIndex++;

                          }

                          if (strncmp(buffer,"GET ",4)==0){

                            data.isGET=true;

                            strncpy(data.path,(buffer+4),bufferIndex-11);

                            data.path[bufferIndex-15]='\0';

                            bufferIndex=bufferIndex-15;

                            int pos=0;

                            while(data.path[pos]!='?'){

                              pos++;

                              if(pos==bufferIndex) break;

                            }

                            strncpy(data.params,(data.path+pos),bufferIndex-pos);

                            data.params[bufferIndex-pos]='\0';

                            data.path[pos]='\0';

                            return data;

                          }else if(strncmp(buffer,"POST ",5)==0){

                            data.isGET=false;

                            strncpy(data.path,(buffer+5),bufferIndex-11);

                            data.path[bufferIndex-16]='\0';

                            return data;

                          }

                        }

                    }

                  }

                  void sendPage(char *path, EthernetClient client, int len){

                    File myFile = SD.open(path);

                    char sp;

                     if (myFile) {

                       if(len==0){

                         while(myFile.available()){

                          sp=myFile.read();

                                  client.print(sp);

                        }

                       }else{

                         for(int j=0; j<len;j++){

                           sp=myFile.read();

                                    client.print(sp);

                         }

                       }

                        myFile.close();

                     }else{

                       client.print("NOT FOUND");

                     }

                  }

                  //fin du programme

                  //ici des commentaires

                  /*Serial.println(path);

                          myFile = SD.open(path);

                          if (myFile) {

                            while (myFile.available()) {

                              c=myFile.read();

                                      client.print(c);

                            }

                            myFile.close();

                          }else{

                            myFile = SD.open("index.htm");

                            while (myFile.available()) {

                              c=myFile.read();

                                      client.print(c);

                            }

                          }

                          Serial.println("--------------------------");

                          buffer[0]=client.read();

                          buffer[1]=client.read();

                          buffer[2]=client.read();

                          buffer[3]=client.read();

                          bufferIndex=4;

                          while(buffer[bufferIndex-4] !='\r' && buffer[bufferIndex-3] != '\n' && buffer[bufferIndex-2] != '\r' && buffer[bufferIndex-1] != '\n'){

                            c=client.read();

                            //if(bufferIndex<BUFFER_SIZE) buffer[bufferIndex]=c;

                            bufferIndex++;

                          }

                          Serial.println(bufferIndex);

                          Serial.println("--------------------------");

                          while(client.available()){

                            c=client.read();

                            if(bufferIndex<BUFFER_SIZE) buffer[bufferIndex]=c;

                            bufferIndex++;

                          }*/

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 avril 2015 à 20:20:46

                    Sans la balise code, c'est tout simplement illisible, on ne peut rien rien.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      12 avril 2015 à 3:12:52

                      'vaudrait pas mieux lui dire de faire son propre topic? enfin j'dis ça...
                      • Partager sur Facebook
                      • Partager sur Twitter

                      oui. non. enfin je regarde et je te dis.

                        12 avril 2015 à 11:27:30

                        Ah oui tient, j'avais fait attention à ça.

                        @faiçalrouchmi : afin que l'on puisse te répondre correctement, il te faut ouvrir ton propre sujet (parce que là, tu es en train de squatter un sujet qui ne t'appartient pas) et que tu utilises la balises code (le bouton </> au dessus de l'éditeur).

                        • Partager sur Facebook
                        • Partager sur Twitter
                          13 avril 2015 à 17:06:50

                          d'accord Monsieur..est ce que tu peut m'aider pour réaliser ça correctement svp et mrc

                          • Partager sur Facebook
                          • Partager sur Twitter
                            13 avril 2015 à 18:53:18

                            faiçalrouchmi: pour créer un sujet, c'est là (clique c'est un lien) et tu clique sur le bouton bleu "créer un sujet". ensuite, ça se passe en bas de la page.

                            pour mettre ton code entre balises code, c'est le bouton qui ressemble à ça: </>

                            et pour poser une question, tu sais faire, donc je t'explique pas.

                            -
                            Edité par remace 13 avril 2015 à 18:54:52

                            • Partager sur Facebook
                            • Partager sur Twitter

                            oui. non. enfin je regarde et je te dis.

                            Arduino PhP

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown