Problème ethernet client.stop()

Bonjour,

J'aimerais vous demander de l'aide. Cela fait 4 mois que mon prof' et moi nous penchons sur le problème et on n'arrive à rien ... C'est dans le cadre du projet du bac STI2D qu'on utilise l'Arduino.

Dans mon cas, je l'utilise couple à son module Ethernet pour envoyer des requêtes vers mon serveur local WAMP (sur Windows).

Donc, j'utilise la librairie Ethernet et le WebClient, sur lequel j'ai bien mis l'adresse MAC de l'Arduino, définit une IP pour lui, et définit l'IP du serveur.

Le soucis rencontré est que la connexion ne marchait qu'une fois sur 10, ou aléatoirement. Après des semaines à bidouiller le script, on a simplement retiré la ligne "client.stop()" et le problème a disparu. Maintenant, à chaque RESET, la connexion marche parfaitement et la requête est bien envoyée.

Ce soucis du client.stop est très gênant dans la mesure où j'ai besoin d’exécuter plusieurs requêtes, donc faire plusieurs connexions ...

J'ai tenté toutes les solutions trouvées sur le net, rien à faire, ça ne fonctionne pas.

Ce qui est curieux, c'est que quand je n'enlève pas le client.stop(), mais que le serveur est non pas WAMP mais un deuxième Arduino qui joue le rôle du WebServer, là ça marche impeccable, pas de problème avec le client.stop(). Donc je me demande si le soucis vient de WAMP ou de l'Arduino. Des personnes ont rencontré ce problème sur le net, mais jamais trouvés de solutions.

Je peux vous fournir mon code si vous souhaitez y jeter un coup d'oeil :

/*
 * Client WEB
 */

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xAA, 0xF5 }; // Adresse MAC de l'Arduino
IPAddress server(172, 16, 119, 5); // Adresse du serveur. Ici il s'agit de l'IP locale de l'ordinateur, pour se connecter à WAMP
byte ip[] = {172, 16, 119, 95}; // IP attribuée à l'Arduino manuellement car le DHCP est désactivé

char table[10] = {'1', '2', '4', '5', '6', '4', '5', '6', '4' ,'5'}; // Tag RFID de la carte

String code = ""; // Code qui sera completé par les valeurs du tableau 'table'

char *p, *i;
int x;

String reponse = "";

// Initialisation
EthernetClient client;

void setup()
{
  Serial.begin(9600);
  pinMode(2, OUTPUT); // LED Rouge
  
  /* Pour désactiver la carte SD */
  pinMode(4,OUTPUT);
  digitalWrite(4,LOW);
  
  /* ---------------------------------------- */
  
  Ethernet.begin(mac, ip); // Initialisation
  
  delay(2000);
  Serial.println("Connexion en cours ...");
  
  if (client.connect(server, 80))
  {
    Serial.println("connected");
    
    /* Envoie de Requêtes GET HTTP */
    
    // On attache chaque caractère du tableau à la variable 'code'
    for(int i; i<= 9 ; i++)
    {
      code += table[i]; 
    }
    
    client.println("GET /NASA/query/test/?tagID=" + code + " HTTP/1.0");
    client.println();
    
    code = "";
  }
  else
  {
    // Connexion non réussie
    Serial.println("Erreur de connexion.");
  }
}

void loop()
  {
  // Afficher une réponse si réponse est
  if (client.available()) {
    
    char c = client.read();
    reponse = reponse + c;
    
    // Delete HTTP headers
    if(reponse.endsWith("[PARSELIMIT]"))
    {
      reponse = "";
    }
    
    if(client.available() == 0){
      //Serial.print("Réponse : ");
      //Serial.println(reponse);
      
      if(reponse.startsWith("<Welcome>")){
        String reponseParse = getValue(reponse, '<Welcome>', 1);
        Serial.println(reponseParse);
        digitalWrite(2, HIGH);
      }
      
      if(reponse.startsWith("<Error_Not_Allowed>")){
        String reponseParse = getValue(reponse, '<Error_Not_Allowed>', 1);
        Serial.println(reponseParse);
        digitalWrite(2, LOW);
      }
      
    }
    
    /*
    char c = client.read(); // Récupération du caractère reçu de type char
    
    // On parse la réponse + les headers à partir d'un nombre de données inférieur à 50
    if(client.available() < 50){
      inData += c; // On l'ajoute dans la variable String inData
    }
    
    // Si on ne reçoit plus de réponses, donc = 0, on affiche la variable String qui contient tous les caractères
    if(client.available() == 0){
      //Serial.println(inData); // Afficher le String
      String reponseParse = getValue(inData, '[PARSE]', 1);

    String reponseTexte = getValue(reponseParse, '<Welcome>', 1);
      
    }
    */
    
  }
  
  if (!client.connected()) {
    Serial.println();
    Serial.println("Deconnexion.");
    
    //client.stop(); // Cette ligne est problématique
    
    // Ne pas toucher
    for(;;)
      ;
  }
  
}

/**************************
***************************
**************************/

/* Fonction pour la délimitation, dite "split" dans les languages */

String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
		found++;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}

J'espère qu'on trouvera une solution, car il s'agit du bac et je peux pas me permettre de rater ça à cause d'une ligne de code ... :~ Merci à vous !

Nardoum:
...

Ce soucis du client.stop est très gênant dans la mesure où j'ai besoin d’exécuter plusieurs requêtes, donc faire plusieurs connexions ...

...

J'espère qu'on trouvera une solution, car il s'agit du bac et je peux pas me permettre de rater ça à cause d'une ligne de code ... :~ Merci à vous !

bonjour
Tu aura surement des meilleurs réponses que la mienne, je ne sais pas si dans ton cas (process) cela à une importance, mais le shield ethernet "wiznet officiel " est limité il me semble à 4 connections , et je ne suis pas assez "reseau" pour savoir ce que recouvre exactement cette "limitation" dans ton cas

Par 4 connexions, tu veux dire 4 connexions simultanées ou comment ? Parce que logiquement si on ferme une connexion, pour en rouvrir une autre, ça doit marcher non ?

Ou bien 4 connexions au maximum, qui partent au RESET ?

Nardoum:
Par 4 connexions, tu veux dire 4 connexions simultanées ou comment ? Parce que logiquement si on ferme une connexion, pour en rouvrir une autre, ça doit marcher non ?

Ou bien 4 connexions au maximum, qui partent au RESET ?

comme exposé plus haut, j'ai un ethernet shield, mais la gestion reseau n'est pas mon meilleur coté :grin:

la seule chose sur ce "facteur" 4 que j'avais vu passé

le chip wiznet

  • Support Hardwired TCP/IP Protocols TCP, UDP, ICMP, IPv4 ARP, IGMP, PPPoE, Ethernet
  • 10BaseT/100BaseTX Ethernet PHY embedded
  • Support Auto Negotiation (Full-duplex and half duplex)
  • Support Auto MDI/MDIX
  • Support ADSL connection (with support PPPoE Protocol with PAP/CHAP Authentication mode)
    - Supports 4 independent sockets simultaneously
  • Not support IP Fragmentation
  • Internal 16Kbytes Memory for Tx/Rx Buffers
  • 0.18 ?m CMOS technology
  • 3.3V operation with 5V I/O signal tolerance
  • Small 80 Pin LQFP Package
  • Lead-Free Package
  • Support Serial Peripheral Interface(SPI MODE 0, 3)Multi-function LED outputs (TX, RX, Full/Half duplex, Collision, Link, Speed)

Il me semble que d'habitude la variable ip est du type IPAddress.

J'a mis IPAdress mais c'est la même chose que ma variable ip (c'était dans l'exemple de base du WebClient).

Je continue de chercher, je viens de tester sur un autre ordinateur avec Wamp d'installé et ça fait la même chose.

Dès qu'il s'agit de dé commenté le client.stop() , la connexion foire et marche une fois sur 10, ou aléatoirement.

J'ai donc modifié un maximum de choses côté Wamp, afin de mettre un grand nombre de connexions autorisées, etc, etc, et ça ne change rien. J'ai aussi regardé le log de WAMP.

Donc quand arduino affiche "connexion en cours ..." puis rien après, c'est que la connexion échoue, et Wamp ne reçoit absolument aucune tentative d'accès dans le log.

Donc la connexion échoue bel et bien. J'ai essayé de mettre un delay(10000) au début du setup, en me disant que peut-être que lorsqu'on appuie sur le reset, il faut laisser le temps à Windows de reconnecter le port ethernet à la carte réseau.

Ça ne change rien .. :cry:

Salut, tu devrais prendre un exemple de client ethernet donné en exemple avec la librairie pour mettre un peu d'ordre dans ton programme ...
Dans ton programme tu fais le client.stop dans la boucle ou tu vérifies ... If !client.connected ...
Pas de bras, pas de chocolat ... Pas de client, pas de client à stopper !

A mon avis l'erreur est ici...

Je m'étais posé la question et j'avais déplacé le client.stop() à plusieurs endroits dans le code, pour tester. Mais pourtant, la façon dont j'ai mis le client.stop() est exactement la même que dans l'exemple de la librairie :

// if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    for(;;)
      ;
  }

Ça me paraît pas logique, mais même en essayant sans, ça déconne. C'est vraiment bizarre que ça marche une fois, et qu'après ça ne marche plus. En enlevant le client.stop(), j'ai beau faire autant de RESET que je veux, ça marche. Avec le client.stop(), ça marche pas.

Je pourrais le placer où par exemple ? Après ma requête, ou à la fin du client.available() ?

Bonjour,

Essaye d'ajouter un delay(100); avant le if qui test la déconnexion du serveur (histoire de lancer le temps au serveur web de réagir).

Sinon je vois des String et des trucs du genre : "str += c;".
En gros à chaque fois tu fait une (ré)allocation dynamique (caché par la bibliothèque String) d'un octet ... pas cool.
La bibliothèque String est une pure saloperie à éviter.

Fait un bête tableau de char[] statique.
C'est pas plus compliqué mais si ça ce trouve ça réglera ton probléme si c'est un crash du à une fragmentation mémoire.