[Résolu] Serveur Arduino qui renvoie une page web bizarre !

Bonjour,

Je suis débutant et j’ai cherché un peu partout sans trouvé la solution à mon problème.
J’utilise Arduino uno et un shield Ethernet pour envoyer/recevoir des infos d’un navigateur
à mon Arduino qui fait office de serveur.

Voici les formats de la commande envoyée par un navigateur client
vers le routeur de ma box :

http://oct1.oct2.oct3.oct4:5011/?b=3&p=200

ou

http://oct1.oct2.oct3.oct4:5011/?b=3,4&p=200

ou

http://oct1.oct2.oct3.oct4:5011/?b=3,4,5&p=200

etc…

5011 port choisi arbitrairement

b=3 signifie broche 3 à 5v (à 0 si elle n’est pas citée)

b=3,5 signifie broche 3 et 5 à 5v

etc, etc

p= valeur pwm sur sortie 6

Je développe sous W10. Ma redirection de port fonctionne aux petits oignons
et la requete GET est parfaitement interprétée : les sorties 3,4 et 5 et… 6 (pwm) sont mises à jour comme
il se doit. Tout va donc très bien MAIS ma page WEB MINIMALISTE (pour causes d’erreurs répétées) a un bien drôle de format :

Voici la page minimaliste attendue :

<!DOCTYPE HTML>
<html>
<head>
</head>
<body>BOOOOOF



</body>
</html>

Voici celle que je reçois !!

ET /?b=4,5&p=200 HTTP/1.1

GET /?b=4,5&p=200 HTTP/1.1
 HTTP/1.1

GET /?b=4,5&p=200 HTTP/1.1

GET /?b=4,5&p=200 HTTP/1.1
<!DOCTYPE HTML>
<html>
<head>
GET /?b=4,5&p=200 HTTP/1.1

</head>
<body>BOOOOOF



GET /?b=4,5&p=200 HTTP/1.1
</body>
</html>
GET /?b=4,5&p=200 HTTP/1.1

En clair, la requête recueillie par le serveur “GET /?b=4,5&p=200 HTTP/1.1” (par ex)
se trouve plusieurs fois au sein du code de la page HTML renvoyée !
Je suppose que cela est un cas classique et que ça vous
parle… moi je ne comprends pas.

VOICI LE CODE ARDUINO QUI RECUP LA REQUETE ET RENVOIE LA PAGE

// Ces deux bibliothèques sont indispensables pour le shield
#include <SPI.h>
#include <Ethernet.h>


byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

IPAddress ip(192,168,1,16);

// Initialise notre serveur
EthernetServer serveur(5011);

// L'url reçu à stocker
char *url = (char *)malloc(100); 

// index indiquant où l'on est dans la chaîne
char index = 0;
 
boolean etats[3] = {LOW, LOW, LOW}; // états broches 3,4 et 5

unsigned char pwm = 0;


void setup()
{

   // Configure et initialise les broches
   pinMode(3, OUTPUT); digitalWrite(3, LOW);
   pinMode(4, OUTPUT); digitalWrite(4, LOW);
   pinMode(5, OUTPUT); digitalWrite(5, LOW);
   pinMode(6, OUTPUT); analogWrite (6, 0);


   Ethernet.begin(mac, ip);

   // Donne une seconde au shield pour s'initialiser
   delay(1000);

   serveur.begin();
  
}





void loop() 
{
   // Regarde si un client est connecté et attend une réponse
   EthernetClient client = serveur.available();
   
   if (client) 
   { 
       //Serial.println("Ping !");
       url = "";
       index = 0;
       while(client.connected()) 
       {   // Tant que le client est connecté
           if(client.available()) 
           {   // A-t-il des choses à dire ?
               // traitement des infos du client
               // on lit ce qu'il raconte
               char carlu = client.read(); 
               
               if(carlu != '\n') 
               {   // On est en fin de chaîne ?
                   // non ! alors on stocke le caractère
                   // Serial.print(carlu);
                   url[index] = carlu;
                   index++;
               } 
               else 
               {
                   // on a fini de lire ce qui nous intéresse
                   // on marque la fin de l'url (caractère de fin de chaîne)
                   url[index] = '\0';
                   
                   // essaie d'interpréter la chaîne
                   boolean ok = interpreter(); 
                   if(ok) 
                   {
                        // tout s'est bien passé alors on met à jour les broches
                        action();
                   }
                   // et dans tous les cas on répond au client
                   repondre(client);

                   // on quitte le while
                   break;
                   

               }
                    


           }


       }

   }

   // Donne le temps au client de prendre les données
   delay(1);

   // Ferme la connexion avec le client
   client.stop();


}



void rafraichir() 
{
   // Rafraichit l'etat des broches / PWM
   digitalWrite(3, etats[0]);
   digitalWrite(4, etats[1]);
   digitalWrite(5, etats[2]);
   analogWrite (6, pwm);
}


void repondre(EthernetClient myclient) 
{
         myclient.println("HTTP/1.1 200 OK");

         myclient.println("Content-Type: text/html");

         // On envoie une ligne vide pour signaler la fin du header
         myclient.println();

         //page MINIMALISTE CAR J'AI TROP D'ERREURS ICI !!

         myclient.println(F("<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n")); 
         myclient.println(F("\r\n</head>\r\n<body>BOOOOOF\r\n

\r\n"));
         myclient.println(F("</body>\r\n</html>"));
}



boolean interpreter() 
{  // elle fonctionne très bien...

   // On commence par mettre à zéro tous les états
   etats[0] = LOW;
   etats[1] = LOW;
   etats[2] = LOW;
   pwm = 0;

   // Puis maintenant on va chercher les caractères/marqueurs un par un.
   // Index pour se promener dans la chaîne (commence à 4 pour enlever "GET "
   index = 0; 
   while(url[index-1] != 'b' && url[index] != '=') 
   {   // On commence par chercher le "b="
       // Passe au caractère suivant
       index++; 
       if(index == 100) 
       {
           // On est rendu trop loin !
           //Serial.println("Oups, probleme dans la recherche de 'b='");
           return false;
       }
   }

   // Puis on lit jusqu’à trouver le '&' séparant les broches de p = ....
   while(url[index] != '&') 
   {   
       if(url[index] >= '3' && url[index] <= '5') 
       {
           // On a trouvé un chiffre identifiant une broche
           // On ramène ça au format décimal
           char broche = url[index]-'0';
           // Puis on met la broche dans un futur état haut
           etats[broche-3] = HIGH; 
       }

       index++; // Passe au caractère suivant
       if(index == 100) 
       {
           // On est rendu trop loin !
           //Serial.println("Oups, probleme dans la lecture des broches");
           return false;
       }
       // NOTE : Les virgules séparatrices sont ignorées
   }

   // On a les broches, reste plus que la valeur de la PWM
   // On cherche le "p="
   while(url[index-1] != 'p' && url[index] != '=' && index<100) 
   {
       // Passe au caractère suivant
       index++; 
       if(index == 100) 
       {
           // On est rendu trop loin !
           //Serial.println("Oups, probleme dans la recherche de 'p='");
           return false;
       }
   }

   // Maintenant, on va fouiller jusqu'a trouver un espace
   while(url[index] != ' ') 
   {   // On cherche le ' ' final
       if(url[index] >= '0' && url[index] <= '9') 
       {
           // On a trouve un chiffre !
           // On ramene ca au format decimal
           char val = url[index]-'0'; 
           // On stocke dans la pwm
           pwm = (pwm*10) + val; 
       }

       index++; // Passe au caractère suivant
       if(index == 100) 
       {
           // On est rendu trop loin !
           //Serial.println("Oups, probleme dans la lecture de la pwm");
           return false;
       }
       // NOTE : Les virgules séparatrices sont ignorées
   }

   // on a trouvé toutes les informations utiles !
   return true;
}



void action() 
{
   // On met à jour nos broches
   digitalWrite(3, etats[0]);
   digitalWrite(4, etats[1]);
   digitalWrite(5, etats[2]);
   // Et la PWM
   analogWrite(6, pwm);
}

Merci à tous

Pierre Grenoble

N'allouez pas un buffer global comme cela:

char *url = (char *)malloc(100);

surtout si après quand vous avez une requête vous faites

url = "";

ce qui a pour effet de faire pointer votre pointeur ailleurs...

utilisez simplement

char url[100];

et pour mettre votre chaine à vide, mettez un caractère nul en première position

url[0]='\0';

vous pouvez éventuellement jeter un oeil à mon tuto

Est-ce qu'il ne faudrait pas passer l'argument par adresse ici ?

repondre(&client);

Bonjour,

Merci pour la réponse et notamment pour le : url[0]='\0';

M... çaaa maaarche !

Merci

Pierre Grenoble

cool :wink: