Go Down

Topic: [Résolu] Serveur Arduino qui renvoie une page web bizarre ! (Read 231 times) previous topic - next topic

pierregrenoble

Jun 29, 2019, 05:42 pm Last Edit: Jun 30, 2019, 08:26 pm by pierregrenoble
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 :

Code: [Select]


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







Voici celle que je reçois !!

Code: [Select]



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
<br /><br />
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


Code: [Select]



// 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<br /><br />\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

J-M-L

N'allouez pas un buffer global comme cela:
Code: [Select]
char *url = (char *)malloc(100);
 surtout si après quand vous avez une requête vous faites
Code: [Select]
url = "";
ce qui a pour effet de faire pointer votre pointeur ailleurs...

utilisez simplement
Code: [Select]
char url[100];
et pour mettre votre chaine à vide, mettez un caractère nul en première position
Code: [Select]
url[0]='\0';

vous pouvez éventuellement jeter un oeil à mon tuto
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

lesept

Est-ce qu'il ne faudrait pas passer l'argument par adresse ici ?
Code: [Select]
repondre(&client);
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

pierregrenoble

Bonjour,

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


M... çaaa maaarche !


Merci


Pierre Grenoble

J-M-L

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up