Pb de connection WAN avec W5500 sur MEGA 2560 PRO

Bonjour,
j'ai un souci de connexion WAN lorsque je me connecte avec une IP fixe, alors que tout fonctionne bien en DHCP.
J'ai beau tout essayer ça ne veut rien savoir.
Quelqu'un aurait une idée à me soumettre ???
Merci d'avance
Patrick

#include <SPI.h> //For the selection of the key
#include <Ethernet2.h>          //gestion réseau WS5500

#define DEBUG
//#define T_DHCP    //connection par DHCP sinon IPfixe
#define WAN        //CONNECTION WAN sinon LAN

#define SS_IP 53  //connection SS sur mega2560pro

//variables pour la construction de la trame d'interrogation
const char sep = '¤';  //¤ séparateur de trame
const char FT = 253;   //  fin de trame
int value = 0;
String trame1;
int TR0;
int TR1;
int TR2;
int TR3;
String code;
String carte;

EthernetClient client;  //ETHERNET INSTANCE
  signed long next;
  //adresse mac du module IP
  byte mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};
  IPAddress IP(192,168,0,112);    //adresse fixe du module enregistrée sur le routeur
  
  IPAddress PAS(192,168,0,1);     //passerelle
  IPAddress DNS(192,168,0,254);   //dns
  IPAddress MAS(255,255,255,0);   //masque

  #ifdef WAN
    IPAddress SRV(91,160,17,23);    //IP WAN
    const long PORT = 33007;        //port WAN
  #else
    IPAddress SRV(192,168,0,65);    //IP LAN
    const long PORT = 10007;        //port LAN
  #endif

signed long timeout;              //TIMEOUT SO IT DOESN'T SIT THERE FOREVER

/*la connection fonctionne :
 * lorsque je me connecte sur le réseau local "PC2017 port 10007" en DHCP ou en IP fixe
 * lorsque je me connect par le WAN sur un entrée redirigée "LHD port 30007"  
 * 33007 est redirigée par le routeur sur 10007
 * en DHCP c'est ok mais impossible de se connecter en IP fixe ???
 */


void setup() {
  Serial.begin(115200);
  digitalWrite(SS_IP, 0);
  Ethernet.init(SS_IP);
  Serial.println  ("***************************************************************");
  Serial.println  ("********* CONNECTION SERVEUR **********************************");
  Serial.println  ("***************************************************************");
  
  #ifdef WAN
    Serial.print ("connection WAN :");
  #else
    Serial.print ("connection LAN :");
  #endif
  Serial.print (SRV);
  Serial.print(" - ");
  Serial.println (PORT);
  
  #ifdef T_DHCP   //CONNECTION QUI FONCTIONNE
    int rep=0;
    Serial.print("test en DHCP rep= ");
    rep=Ethernet.begin(mac);     //solution DHCP pour fonctionner sur tous les sites
    Serial.println(rep);
  #else           //CONNECTION QUI NE FONCTIONNE PAS!!!!!!!!
    Serial.print("test avec IP fixe : ");
    Serial.println(IP);
    
    //Ethernet.begin(mac, IP, DNS, PAS, MAS);
    //Ethernet.begin(mac, IP, DNS, PAS);
    //Ethernet.begin(mac, IP, DNS);
    Ethernet.begin(mac,IP);
  #endif
  delay(3000);

  #ifdef DEBUG     
    Serial.print("localIP: ");     Serial.println(Ethernet.localIP());
    Serial.print("subnetMask: ");  Serial.println(Ethernet.subnetMask());
    Serial.print("gatewayIP: ");   Serial.println(Ethernet.gatewayIP());
    Serial.print("dnsServerIP: "); Serial.println(Ethernet.dnsServerIP());
    Serial.print("Serveur : ");    Serial.print (SRV);
    Serial.print("  Port : ");     Serial.println (PORT);    
    Serial.println ("=================================================");
  #endif  

}

void loop() {
  
  Connect();
  delay(5000);

}

void Connect() {
++value;
TR0=99;
TR1=2;
TR3=3;
code="OSMOPUR";
    #ifdef DEBUG
      Serial.print("Connexion : "); Serial.print(SRV);Serial.print(" - Tentative: "); Serial.println(value);
    #endif
      int rep=0;   
      rep= (client.connect(SRV,PORT));
      if (rep==1)
        {
          #ifdef DEBUG
            Serial.println(" - OK");
            value=0;
          #endif
          // Créer la trame à envoyer
          trame1= TR0;
          trame1 += sep;trame1 += TR1;
          trame1 += sep;trame1 += TR2;
          trame1 += sep;trame1 += TR3;
          trame1 += sep;trame1 += code;
          trame1 += sep;trame1 += carte;    
          trame1 += FT;          
          client.print(trame1);
          //client.print("Des infos de la part du client - "); client.println(IP);
          unsigned long timeout = millis();
          while(client.available()==0) {
            if (millis() - timeout > 8000) {
              //pas de réponse du serveur
              #ifdef DEBUG 
                Serial.print(" >>> Client Timeout ! ");
              #endif
                           
              goto close;
            }
          }
          
          int size;
          while((size = client.available()) > 0) {
            {
              uint8_t* msg = (uint8_t*)malloc(size);
              size = client.read(msg,size);
              #ifdef DEBUG
                Serial.print(" - Réponse serveur: ");
                Serial.write(msg,size);
              #endif
              //Serial.println();
              free(msg);
            }
          }
close:
          //disconnect client
          #ifdef DEBUG
            Serial.println(" - Client déconnecté ");
          #endif
          client.stop();
        }else{
          
          #ifdef DEBUG
            Serial.println(" - Client connect Erreur ");
          #endif

        }
  delay(1000);

return;
}

Quelle est l'adresse obtenue en DHCP ?

En général il est beaucoup plus pertinent de fixer l'adresse IP pour une adresse MAC donnée sur la box, et laisser l'ARDUINO en DHCP. Cela évite de gérer différentes adresses IP en dur dans le code

Bonjour,
je suis entièrement d'accord, mais en l’occurrence il s'agit d'un groupe de commerçants et le mode de connexion m'est imposé.
Sur mon module de test, j'ai configuré le routeur de cette manière et en DHCP, j'obtiens bien l'adresse 112.
Si je modifie l'adresse MAC, dans ce cas je perd l'adresse fixe du routeur et je passe par DHCP qui me renvoie une adresse 43, normal, mon DHCP est limité entre 0 et 50.

Il y a un risque de doublon sur le réseau.

Deux remarques :

Ethernet2 est obsolète.

Deprecated/Archived Library

This library is no longer going to be used, since the official Arduino library has been updated and works great GitHub - arduino-libraries/Ethernet: Ethernet Library for Arduino

Il serait bien de tester la valeur retournée de Ethernet.begin() dans les deux cas.

Bonjour,
déjà merci pour l'info, en effet la nouvelle version d'Ethernet.h intègre correctement le W5500.
par contre, cela ne change rien au problème.
La valeur de retour de Ethernet.begin n'est disponible qu'en DHCP et elle renvoie 1 si le DHCP est validé ou 0 s'il y a un problème. Mais elle ne renvoi rien en IP fixe.
Que veux-tu dire par "il y a un risque de doublon sur le réseau" ?

Effectivement.

Deux nœuds de réseau peuvent avoir la même adresse IP.

Le seul essai que j'aie fait en IP fixe en dur, avec un W5100 :
https://bitbucket.org/henri_bachetti/w5100-ntp/src/master/examples/ntp/ntp.ino

J'ai vérifier, il n'y a pas de conflit d'IP j'ai tout de même essayé différentes adresses en vain.
j'ai changé de carte électronique, de câble IP, de connexion réseau, rien à faire.
ce qui me gène, c'est que tous les exemples sur le net utilisent une IP fixe.
J'ai chargé un bout de code basic dans les exemples de la librairie.
Si je l'utilise tel quel, cela ne fonctionne pas, si j'enlève ,ip dans ethernet.begin et que je ne laisse que mac, tout va bien, je récupère tout google...

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 115 };
byte server[] = { 64, 233, 187, 99 }; // Google

EthernetClient client;

void setup()
{
  Serial.begin(115200);
  digitalWrite(53, 0);
  Ethernet.init(53);

  Ethernet.begin(mac, ip);
  delay(3000);

  Serial.println("connecting...");

  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /search?q=arduino HTTP/1.0");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    for(;;)
      ;
  }
}

Ceci me semble anormal, attendu que les méthodes connect() sont les suivantes :

	virtual int connect(IPAddress ip, uint16_t port);
	virtual int connect(const char *host, uint16_t port);

Donc, sans DNS, la deuxième méthode devrait échouer.
Par contre essayer ceci :

IPAddress server(64, 233, 187, 99);

En effet, c'est le format que j'utilise en général pour déclarer mes adresses IP.
Mais ce code est un exemple de la version officielle de la librairie.
J'ai essayé la version IPAddress, mais le résultat est le même.

Le plus étrange, c'est que "client.connect" renvoi 0 alors qu'il devrait renvoyé 1 si tout va bien ou une valeur négative en cas d'échec, mais en aucun cas zéro...
Le problème semble venir de la fonction .begin, mais J'ai beau lire et relire la documentation, je ne vois vraiment pas ce qui coince.

Sauf dans ce cas :

	if (!dns.getHostByName(host, remote_addr)) return 0; // TODO: use _timeout

L'exemple du post #6 fonctionne. La seule différence est qu'il s'agit d'un serveur.
Il y a également ceci :

IPAddress dnsIp(192, 168, 0, 1);
// ...
  Ethernet.begin(mac, ip, dnsIp);

Je ne comprends pas à quoi sert la fonction .getHostByName !

oui le post #6 fonctionne en LAN

j'ai testé toutes les possibilités de la fonction .begin, ( mac,ip,dns, passerelle,masque) une à une sans plus de résultat.

Encore une fois, ce qui m'interpelle, c'est que tous les exemples du W500 sur le net utilisent cette méthode de connexion et personne n'a l'air de s'en plaindre.
Ou est la faille ?
Je pense avoir tout essayé, modification de l'adresse mac, de l'adresse IP, de la configuration du routeur, j'ai changé de serveur, la carte électronique, de module W5500, de câble réseau, de connexion sur le switch, j'ai testé différents programmes, modifié les temps d'attente, les formats des variables...
je ne sais plus quoi changer

C'est une fonction utilisée par la méthode connect(const char *host, uint16_t port) pour récupérer l'adresse IP d'un host, à partir de son nom.
Si connect() retourne ZERO, c'est que getHostByName() a échoué, ce qui n'est pas étonnant puisque tu lui passes une chaîne de bytes (64, 233, 187, 99), de plus non terminée par '\0'.
Tu devrais :

  • soit utiliser un objet du type IPAddress
  • soit utiliser un hostname et un DNS (adresse de ta box)

Comme j'avais un montage NANO + W5100 sous la main :
Avec ton code, à ceci près :

  • j'ai supprimé la manipulation de la pin 53. Normalement la pin 53 est SS par défaut sur la MEGA, et j'utilise une NANO, donc SS = 10
  • adresse IP = 192.168.1.115 (ma box est en 192.168.1.1)
#include <Ethernet.h>
#include <SPI.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192, 168, 1, 115};
byte dnsIp[] = {192, 168, 1, 1};
char server[] = "google.com";

EthernetClient client;

void setup()
{
  Serial.begin(115200);
  Ethernet.begin(mac, ip, dnsIp);
  Serial.print(F("client is at "));
  Serial.println(Ethernet.localIP());
  Serial.println("connecting...");
  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /search?q=arduino HTTP/1.0");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    for(;;);
  }
}

Le résultat :

client is at 192.168.1.115
connecting...
connected
HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Date: Tue, 16 Aug 2022 11:44:50 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Security-Policy: object-src 'none';base-uri 'self';script-src 'nonce-JvEuGb-8CKRFrCa8FFubpg' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/xsrp
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: AEC=AakniGPApv-VPc9MNgkxvNGYS0eKDpsaqZIUfOZD9IFMHOQMDmm7hz8GKg; expires=Sun, 12-Feb-2023 11:44:50 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
Accept-Ranges: none
Vary: Accept-Encoding
etc.
disconnecting.

Pour ip, dnsIp et server, l'utilisation de IPAddress à la place de byte fonctionne aussi.

char server[] = "google.com";
// ou
byte server[] = {64, 233, 187, 99}; // Google

Les deux versions "google.com" ou {64, 233, 187, 99} fonctionnent.

Si je remplace "google.com" par "goole.com", j'ai une erreur 404.
Si je remplace {64, 233, 187, 99} par {63, 233, 187, 99}, j'ai une erreur "connection failed".

Alors là, merci de ce test, j'avance sérieusement.
Parce que une fois remis ton code à jour pour ma box 0 à la place de 1, cela ne fonctionne pas du tout.
J'ai remis l'adresse mac et l'IP enregistré dans le DHCP au cas ou et cela ne fonctionne pas non plus.
Par contre si je retire " , ip, dnsIp" ça fonctionne ( j'ai du rajouter la manipulation du port 53, sinon rien ne fonctionne).

19:20:41.777 -> client is at 192.168.0.112
19:20:41.777 -> connecting...
19:20:42.802 -> connection failed
19:20:42.802 -> 
19:20:42.802 -> disconnecting.
19:21:35.943 -> client is at 192.168.0.115
19:21:35.943 -> connecting...
19:21:36.964 -> connection failed
19:21:36.964 -> 
19:21:36.964 -> disconnecting.

Je suis un peu rassuré, mon code n'était pas complètement pourri et cela vient bien probablement de ma configuration routeur.
Maintenant ou chercher, c'est une autre histoire, d'autant que le problème est similaire chez mon client.

PS:
Est-il possible que le problème vienne de la version W5500 au lieu de W5100 ???
j'ai un stock de W5500 mais je n'ai aucun W5100.
j'ai recherché sur le net "W5100 vs W5500" je n'ai rien trouvé sur une différence de code.

Merci mille fois de ce coup de main.

Je viens de relire la notice de la dernière version de la librairie Internet et une phrase me surprend

La carte Arduino communique avec le shield via le bus SPI. C'est sur les broches numériques 11, 12 et 13 sur l'Uno et les broches 50, 51 et 52 sur le Mega. Sur les deux cartes, la broche 10 est utilisée comme SS. Sur le Mega, la broche matérielle SS, 53, n'est pas utilisée pour sélectionner la puce du contrôleur Ethernet, mais elle doit être conservée comme sortie ou l'interface SPI ne fonctionnera pas.

Si c'est le cas, j'ai un problème sur mes circuits, j'ai toujours raccordé la pin SS du module à la sortie 53 sur le MEGA.
Est-ce que cela peut être un problème ?
Je vais essayer de modifier un circuit pour voir.(pas simple)

Si cela fonctionne en DHCP il n'y a aucune raison que le problème soit matériel. La pin SS n'est pas en cause.

Chez moi c'est le contraire. Aucun W5500 disponible.

Oui, effectivement dans Ethernet.h on voit :

	static void init(uint8_t sspin = 10);

La pin 10 est donc SS par défaut quelque soit la carte.
Mais comme tu appelles init() comme ceci :

  Ethernet.init(53);

SS devient donc 53.
De plus si cela fonctionne en DHCP, cela prouve bien que la pin 53 est bien prise en compte par la librairie.