Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Arduino] Data et post ne fonctionne pas

    17 juin 2020 à 18:58:21

    Bonjour,

    J'ai créé un sketch pour envoyer une variable appelée "temp" en GET :cela marche.

    client.print( "GET /yun/add.php?");
    client.print("temp=");
    client.print(temp);

    J'ai ensuite passé 5 heures à essayer d'envoyer plusieurs données avec data sans y parvenir:

    Voici un exemple de Sketch arduino que je n'arrive pas à faire marcher :

    #include <SPI.h>
    #include <Ethernet.h> 
    
    static uint8_t mac[] = { 0xA8, 0xAA, 0x0A, 0xXX, 0x65, 0xXX };   
    char server [] = "www.aaa.com";
    
    int CAPTEUR_TEMP_PIN = 0; // adressage du capteur de temperature (PIN) //
    int t ; //définition de la variable entière (integer) //
      int h;
      String data;
    
    
    EthernetClient client;
    
    
    void setup()
    {
    ///////////////// On teste la connexion au shield
    
    // On démarre la voie série pour déboguer
      Serial.begin(9600);
    
      char erreur = 0;
      // On démarre le shield Ethernet SANS adresse IP (donc donnée via DHCP)
      erreur = Ethernet.begin(mac);
    
      if (erreur == 0) {
        Serial.println("Parametrage avec ip fixe nécessaire ... Le shield n'est pas prêt");
        // si une erreur a eu lieu cela signifie que l'attribution DHCP
        // ne fonctionne pas. On initialise donc en forçant une IP
    
      }
      Serial.println("Init...");
      // Donne une seconde au shield pour s'initialiser
      delay(1000);
      Serial.println("Le Shield est Pret !");
    
    ///////////////// Fin
    
    
    }
    void loop(){
    
    
      t = 10;
      h = 24;
    
      data = "temp=";
    
      data.concat(t);
    
      data.concat("&hum1=");
    
      data.concat(h);
    
    
        if (client.connect("www.aaa.com",80)) {
          Serial.println("1. Connecté à aaa.com");
          Serial.println(data);
          client.print("GET /yun/add.php? HTTP/1.1");
          client.print("Host: www.aaa.com");
          client.print("Connection: close");
          client.print("Content-Type: application/x-www-form-urlencoded");
          client.print("Content-Length: ");
          client.println(data.length());
          client.println();
          client.print(data);
        
        client.println(); 
    Serial.print("2. Donnee ecrite = ");
    Serial.println(t);
    
    
    } 
    else
    {
     Serial.println("problème de connection");        
     }
     if (client.connected()) { 
     client.stop();// DISCONNECT FROM THE SERVER
     Serial.println("3. Déconnexion ");
     }
     delay(300); // attente en millisecondes
     }

    Page add.php (qui tente d'insérer "temp" dans la bdd) :

    <?php 
    include ('identifiants.php');
    
    /* connexion à la bdd */
    include ('identifiants.php');
    /* connexion à la bdd */
    $link = mysqli_connect($host,$user,$secret,$base);
    if (mysqli_connect_errno())
    {
    echo "Failed to connect to MySQL: " . mysqli_connect_error();
    }
    if (!$link)
    die('Echec de connexion au serveur de base de données : ' .
    mysqli_connect_error() . '(' . mysqli_connect_errno() . ') ');
    echo 'base connectée ... <br/>';
    
    $valeur = $_GET['temp'];
    if (isset($_GET['temp'])) // test si la variable existe 
    { 
    
    $valeur = $_GET['temp'];
    
    $sql = "INSERT INTO $table (date, heure, temperature) VALUES ('9','9', $valeur)";     // 
    if (mysqli_query($link, $sql)) {
          echo "New record created successfully";
    } else {
          echo "Error: " . $sql . "<br>" . mysqli_error($link);
    }
    mysqli_close($link);
    } 
    ?>


    Auriez-vous une idée de la raison pour laquelle cela ne marche pas?

    J'utilise un uno + shield ethernet.

    J'ai déjà essayé de remplacer POST par GET et inversement.

    Merci pour votre attention

    -
    Edité par PierreAndrou 17 juin 2020 à 19:18:31

    • Partager sur Facebook
    • Partager sur Twitter
      18 juin 2020 à 16:15:32

      Salut,

      Pour envoyer des données au serveur comme tu le fais, je pense qu'un POST est plus approprié (REST).

      Dans le code arduino j'ai l'impression que le dernier retour à la ligne est en trop. Le serveur reçoit plus de données que data.length() l'a annoncé.

      Serial.println("1. Connecté à aaa.com");
      Serial.println(data);
      
      client.print("GET /yun/add.php? HTTP/1.1"); //remplacer GET par POST
      client.print("Host: www.aaa.com");
      client.print("Connection: close");
      client.print("Content-Type: application/x-www-form-urlencoded");
      client.print("Content-Length: ");
      client.println(data.length());
      client.println();
      //Fin du header
      
      client.print(data);
           
      client.println(); <---- peut être en trop.
      //TODO: Ici lire et afficher ce que le serveur a renvoyé, il peut renvoyer une erreur intéressante.
      if (client.available()) {
         char c = client.read();
         Serial.write(c);
      }


      Dans le php, attention le include est en double, et $valeur = $_GET['temp']; aussi. Remplace le $_GET par $_POST pour récupérer les variables envoyées en POST avec le content type x-www-form-urlencoded.



      • Partager sur Facebook
      • Partager sur Twitter
        Staff 18 juin 2020 à 19:42:58

        Je confirme, le dernier println est de trop, celui-ci va rajouter 2 octets (CR et LF) qui peuvent perturber le serveur.

        Afficher la réponse du serveur est une bonne idée mais il faudrait mettre un petit delay avant histoire de laisser un peu de temps au serveur de traiter la requête et renvoyer la réponse contenant le message d'erreur.

        Ou encore mieux : un timer qui scrute la réponse pendant 5 secondes, ce qui permet de lire progressivement sans avoir de saturation des buffers.

        Mais le gros du problème vient très certainement d'une mauvaise gestion des sauts de ligne dans le reste du header.

        Avec ce code :

        client.print("GET /yun/add.php? HTTP/1.1");
        client.print("Host: www.aaa.com");
        client.print("Connection: close");
        client.print("Content-Type: application/x-www-form-urlencoded");
        client.print("Content-Length: ");
        client.println(data.length());
        client.println();
        client.print(data);
        client.println();

        On va se retrouver avec ce header :

        GET /yun/add.php? HTTP/1.1Host: www.aaa.comConnection: closeContent-Type: application/x-www-form-urlencodedContent-Length: 15
        
        temp=10&hum1=24
        
        

        Clairement, ce n'est pas top car il faudrait ceci :

        GET /yun/add.php? HTTP/1.1
        Host: www.aaa.com
        Connection: close
        Content-Type: application/x-www-form-urlencoded
        Content-Length: 15
        
        temp=10&hum1=24

        Donc il va falloir remplacer des print par des println, mais pas tous !

        Au final, on devrait avoir ceci :

        // Envoie du header
        client.println("POST /yun/add.php? HTTP/1.1"); // POST !
        client.println("Host: www.aaa.com");
        client.println("Connection: close");
        client.println("Content-Type: application/x-www-form-urlencoded");
        client.print("Content-Length: ");
        client.println(data.length());
        client.println(); // Ligne vide indiquant la fin du header
        
        // Envoie des données
        client.print(data);
        
        // Réception de la réponse (pendant 5 secondes maxi)
        uint32_t starttime = millis();
        while ( client.connected() && ((millis() - starttime) < 5000) ) {
        	if (client.available()) {
        		Serial.write(client.read());
        	}
        }
        
        



        -
        Edité par lorrio 18 juin 2020 à 19:44:35

        • Partager sur Facebook
        • Partager sur Twitter

        [Arduino] Data et post ne fonctionne pas

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown