Deux objets « WifiClient »

Bonjour à tous,

j'arrive dans le monde de l'Arduino et j'y prends goût!
Pour commencer, j'emprunte du code ici et là et j'apprends.
C'est ce que j'ai fait ici avec, d'une part un code pour météo vers serveur web, d'autre part un code de serveur web local à ESP32.
Bref, j'ai ESP32 à programmer de la façon suivante:

  • il doit répondre aux visites sur le port 80
  • il doit aussi envoyer des informations à un site web externe où les données reçues depuis ESP32 seront traitées en PHP ( donc: un autre serveur lui aussi répondant au port 80).

Voici mon code résumé:

#include <ESP8266WiFi.h>
#include "SparkFunBME280.h"
#include <dhtnew.h>

const char* meteoHost   = "meteo.cartefoi.net"; //Site de destination des données
const int   meteoPort = 80;

void setup() {
//Rien de particulier ici

void loop() {
  WiFiClient client = server.available();
  if (client) {
///Le bout suivant fonctionne bien, la page web est bien affichée lorsque je visite le site depuis un ordinateur ... donc ESP32 réagit parfaitement
    Serial.println("Nous avons de la visite");
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println(""); 
    client.println("<!DOCTYPE HTML>");
   ////blabla ... on envoie le code de page web
    delay(1);
    Serial.println("Client disonnected");
    Serial.println("");
  }

  //Une fois par minute nous enregistrons les données sur cartefoi.net
  if ((millis() - precCartef) > intervalCarte) {
    msg = versCartefoiMeteo();
  }

}

String versCartefoiMeteo() {
  WiFiClient clientCarte;
  msg = "Tentative de pousser sur " + String(meteoHost) + " ...";
  if (!clientCarte.connect(meteoHost, meteoPort)) {
    msg += "&eacute;chou&eacute;e!";
  } else {
    msg += " amor&cedil;e";
    //blabla, ce que je dois faire pour enregistrer mes données sur le site
    //Mise à jour des informations sur cartefoi.net
    String url = "/update.php?key=";
    url += apiKeyIn;
    url += "\r\n";
    // Send request to the server
    clientCarte.print(String("GET ") + url + " HTTP/1.1\r\nHost: " + meteoHost + "\r\nConnection: close\r\n\r\n");
    msg += ", et ... ¡compl&eacute;t&eacute;e!";
  }
  precCartef = millis();
  return msg;
}

Le résultat obtenu (le contenu de la variable msg) est toujours: « Tentative de pousser sur meteo.cartefoi.net ...échouée! »

Donc ma connexion au serveur distant ne fonctionne pas. Pourquoi!?!?!

C'est ici que ça ne passe pas :

  WiFiClient clientCarte;

  if (!clientCarte.connect(meteoHost, meteoPort)) {
  }

Comme si je ne pouvais pas avoir deux objets de la classe WIFIClient.

Ce n'est pas une faute de frappe, une parenthèse manquante ni une variable non-définie, le correcteur de code l'aurait relevée au moment de compiler. Je bloque.

Merci de me lire et de m'aider.

Bonsoir @Patriboom ,
Peut être une problème de ce côté :
<ESP8266WiFi.h>

Il me semble que vous travaillez sur esp32 ?

Bonne soirée

M'inspirant de Maintien d'une connexion avec l'objet WifiClient - #5 by LS34200, j'ai créé un autre serveur - d'abord avec un port différent, puis avec le port 80 - mais ça ne fonctionne pas plus.
Ce que j'ai fait:
Dans les définitions initiales

WiFiServer serveurESP(80);
WiFiServer serveurCartes(80);

Dans setup()

  // Démarrage du serveur HTTP
  serveurESP.begin();
  Serial.println("Seveur web démarré");
  serveurCartes.begin();
  Serial.println("Communication vers CarteFoi préparée");

Puis dans ma sous-routine:

String versCartefoiMeteo() {
  WiFiClient clientCarte = serveurCartes.available();
  msg = "Tentative de pousser sur " + String(meteoHost) + " ...";
  if (!clientCarte.connect(meteoHost, meteoPort)) {
    msg += "&eacute;chou&eacute;e!";
  }

Et toujours le même résultat:
Tentative de pousser sur meteo.cartefoi.net ...échouée!

Merci encore de votre aide.

Peut être une problème de ce côté :
<ESP8266WiFi.h>
Il me semble que vous travaillez sur esp32 ?

Oui, j'ai deux projets semblables de front.
Un sur ESP32, l'autre sur ESP8266 . C'est bien vu, mais c'est une erreur dans mon titre ici, non dans mon code.

Est ce bien en http et pas https ?

Question très pertinente à laquelle je n'avais pas pensé.

Cependant, j'ai vérifié: https ET http répondent bien sur mon fureteur. Peut-être devrais-je alors me tourner vers https ( ¿ port 443 ? ) pour l'export, dans ce cas.

Je tenterai cette modification et vous reviendrai.

WiFiServer serveurESP(80);
WiFiServer serveurCartes(443);

Retour de test: échec (encore le même message « Tentative de pousser sur ... échouée! »

Je viens aussi d'essayer de modifier la commande de connexion, de façon à avoir les informations pertinentes en dur:

  WiFiClient clientCarte;
  msg = "Tentative de pousser sur " + String(hoteMeteo) + " ...";
  if (!clientCarte.connect("http://meteo.cartefoi.net", 80)) {
    msg += "&eacute;chou&eacute;e!";

et

  WiFiClient clientCarte;
  msg = "Tentative de pousser sur " + String(hoteMeteo) + " ...";
  if (!clientCarte.connect("https://meteo.cartefoi.net", 443)) {
    msg += "&eacute;chou&eacute;e!";

Toujours le même résultat: connexion échouée.

D'autres idées ?

Vous maîtrisez le serveur ou c’est un service tiers ?

Les navigateurs savent basculer automatiquement vers HTTPS suivant ce que répond le site web.

Si vous passez en mode développeur du navigateur pour voir les échanges ça pourrait vous en dire plus. Certains serveurs sont délicats et veulent un minimum de champs dans le header.

Ou alors Si vous faites un curl à la main pour simuler votre requête GET que voyez vous ? Est-ce que ça passe en HTTP ?

Je n'ai pas vu dans ton code la connexion à ton routeur WIFI?
tu es sûr d'être en mode station et d'avoir accroché ton routeur WIFI?

Bonne question, merci terwal

Voici mon code de connexion.

  WiFi.config(local_IP, gateway, subnet);
  WiFi.begin(ssid, password);

  // Wi-Fi connection
  Serial.print  ("Connexion Wifi ");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnexion WiFi réussie");
  
  // Démarrage du serveur HTTP
  serveurESP.begin();
  Serial.println("Seveur web démarré");
   
  // Afficher l'adresse IP dans la console arduino
  Serial.print("Veuillez consulter notre site à cette adresse: ");
  Serial.print(WiFi.localIP());
  Serial.println("/");

C'est un serveur chez un hébergeur, mais j'y ai accès de différentes manières dont cPanel et SSH en root.

Je ne connaissais pas la commande curl que je me suis empressé d'essayer.
Voilà les résultats:
curl http://meteo.cartefoi.net (http) me retourne le contenu de ma page d'accueil ( index.php )
curl https://meteo.cartefoi.net (https): même résultat ( la page index.php de mon site ).
curl Réception de données météo depuis des stations satellites.... (http) me retourne le contenu prévu par la page update.php pour la réception des données, de même aussi en https:
curl Réception de données météo depuis des stations satellites.... (https) me retourne le contenu prévu en guise de réponse à la réception de données.

Cependant, les commandes avec page précisée (update.php) ne retournent pas de fermeture de communication. Pour l'instant, ça importe peu, puis que la communication n'est pas encore établie.

Bonjour à tous,

merci de votre soutien.
Je suis revenu à la base : le fichier d'exemple fourni pour ES8266 dans l'IDE Arduino.
Exemples - ESP8266HTTPClien - PostHTTPClient
Encore là: le même problème. Il y a résolument quelque chose que je ne comprends pas!

Voici le code que je veux faire fonctionner (mon code) - du moins, ses parties pertinentes

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "SparkFunBME280.h"
#include <dhtnew.h>
#include <HttpClient.h>

const char* ssid = "SSID_WifiLocal";             // SSID
const char* password = "MotDePasseWifi";       // WIFI
////Les définitions suivantes ne seront utilisées qu'en cas de IP fixe --- en lien avec la commande WiFi.config() ci-bas
IPAddress local_IP(192, 168, 0, 106);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

WiFiServer serveurESP(80);


void setup()  {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("");
  Serial.setDebugOutput(false);
  //Connect to WiFi network
  WiFi.config(local_IP, gateway, subnet);
  WiFi.begin(ssid, password);

  // Wi-Fi connection
  Serial.print  ("Connexion Wifi ");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nConnexion WiFi réussie");
  
  // Démarrage du serveur HTTP
  serveurESP.begin();
  Serial.println("Seveur web démarré");
   
  // Afficher l'adresse IP dans la console arduino
  Serial.print("Veuillez consulter notre site à cette adresse: ");
  Serial.print(WiFi.localIP());
  Serial.println("/");

void loop() {
  WiFiClient client = serveurESP.available();
  if (client) {
    lisonsBME();
    Serial.println("Nous avons de la visite");
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println(""); 
    client.println("<!DOCTYPE HTML>");
    client.println("<html>");
    client.println("  <body>");
    client.println("    Contenu de la page web retournée par ESP8266 ");
    client.println("  </body>");
    client.println("</html>");
    delay(1);
    Serial.println("Client disonnected");
    Serial.println("");
  }
  //Une fois par minute nous enregistrons les données sur cartefoi.net
  if ((millis() - precCartef) > intervalCarte) {
    Serial.println("La minute est écoulée, nous tenterons de pousser vers cartefoi.net");
    msg = versCartefoiMeteo();
    precCartef = millis();
  }

String versCartefoiMeteo() {
  int err = 0;
  WiFiClient serveurESP;
  HttpClient http(serveurESP);


  err = http.get(hoteMeteo, "/update.php");
  if (err == 0) {
    err = http.responseStatusCode();
    if (err >= 0) {
      Serial.print("Got status code: ");
      Serial.println(err);

      // Usually you'd check that the response code is 200 or a
      // similar "success" code (200-299) before carrying on,
      // but we'll print out whatever response we get

      err = http.skipResponseHeaders();
      if (err == 200) {
        err = http.get(hoteMeteo, "/update.php?val=clevalf&valeur1=11&valeur2=22&valeur3=33&valeur4=44&valeur5=55&valeur6=66&valeur0=clef0");
      }
      if (err >= 0) {
        int bodyLen = http.contentLength();
        Serial.print("Content length is: ");
        Serial.println(bodyLen);
        Serial.println();
        Serial.println("Body returned follows:");
      
        // Now we've got to the body, so we can print it out
        unsigned long timeoutStart = millis();
        char c;
        // While we haven't timed out & haven't reached the end of the body
        while ( (http.connected() || http.available()) && ((millis() - timeoutStart) < kNetworkTimeout) ) {
            if (http.available()) {
                c = http.read();
                // Print out this character
                Serial.print(c);
               
                bodyLen--;
                // We read something, reset the timeout counter
                timeoutStart = millis();
            } else {
                // We haven't got any data, so let's pause to allow some to
                // arrive
                delay(kNetworkDelay);
            }
        }
      } else {
        Serial.print("Failed to skip response headers: ");
        Serial.println(err);
      }
    } else {    
      Serial.print("Getting response failed: ");
      Serial.println(err);
    }
  } else {
    Serial.print("Connect failed: ");
    Serial.println(err);
  }
  http.stop();

  // And just stop, now that we've tried a download
  while(1);
}
}

La connexion ne parvient jamais à se faire.
J'ai pourtant testé mon accès au site directement en fureteur: parfait; j'ai aussi inséré l'équivalent d'un iframe dans mon code de page: parfait aussi.

Ce que je soupçonne incorrect est ici:

  WiFiClient serveurESP;
  HttpClient http(serveurESP);

Mon serveur web s'appelle serveurESP
Fais-je la bonne chose en comptant passer par mon serveur web pour accéder à une page externe ?

C'est ce que je crois comprendre de l'exemple mentionné ci-haut où j'ai emprunté le code suivant:

void loop() {
  // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {
    int err = 0;
    WiFiClient client;
    HTTPClient http;

    http.begin(client, "http://" SERVER_IP "/postplain/"); //HTTP
    http.addHeader("Content-Type", "application/json");
    int httpCode = http.POST("{\"hello\":\"world\"}");
    if (httpCode > 0) {
    } else {
      Serial.printf("[HTTP] POST... failed, error: %s\n   ... C'est ici que j`aboutis à chaque fois", http.errorToString(httpCode).c_str());
    }

}

Merci.

Bonjour à tous,

je progresse vers la résolution du problème. Je suis revenu à la base:
Wifi
WifiClient
WifiClient.connect()

Trois choses encore à régler.

  1. La connexion fonctionne - enfin! - lorsque je laisse le serveur DHCP m'attribuer une adresse.
    Qu'y a-t-il donc de mal fait dans ma définition (ci-bas) ? J'ai besoin d'un IP fixe pour la suite de chose. Je ne veux donc pas d'une adresse attribuée par DHCP.
IPAddress local_IP(192, 168, 0, 106);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
  1. Lorsque ça connecte (en DHCP), la commande « clientCartes.println("GET ... » n'est pas prise par le serveur distant.
loop() {
  if ((millis() - precCartef) > intervalCarte) {
    Serial.println("La minute est écoulée, nous tenterons de pousser vers cartefoi.net");
    msg = versCartefoiMeteo();
    precCartef = millis();
  }
}

String versCartefoiMeteo() {
  int err = 0;
  Serial.println("Commencement de la procédure de transfert vers cartefoi");
  if (clientCartes.connect(hoteMeteo, 80)) {
    Serial.println("Nous sommes occupés à faire cela en ligne 236");
    clientCartes.println("GET /page.php?key=clef&valeur1=4.26&valeur2=4,36&valeur3=99.12&valeur4=44&valeur5=77&valeur6=88&valeur0=valeur0 HTTP/1.0");
    clientCartes.println();
  } else {
    Serial.println("Connexion échouée");
  }
  Serial.println("Nous sommes ici en ligne 240 et devrions connaître le résultat du test");

  // And just stop, now that we've tried a download
  return "Avons-nous réussi ou non?";
}

Devrais-je limiter à un le nombre de valeurs transmises à chaque commande GET ? Si oui ... comment ?

    clientCartes.println("GET /page.php?key=cle HTTP/1.0");
    clientCartes.println("GET /page.php?valeur1=4.26 HTTP/1.0");
    clientCartes.println("GET /page.php?valeur2=4,36 HTTP/1.0");
    clientCartes.println("GET /page.php?valeur3=99.12 HTTP/1.0");
    clientCartes.println("GET /page.php?valeur4=44 HTTP/1.0");
    clientCartes.println("GET /page.php?valeur5=77 HTTP/1.0");
    clientCartes.println("GET /page.php?valeur0=valeur0 HTTP/1.0");
    clientCartes.println();

Avec la référence à udapte.php répétée ou non ?
Avec des println ou des print à chaque GET ?

  1. Après connexion au serveur distant, mon serveur local est redémarré.
    Comment interprété / comprendre les codes retournés ?
11:17:36.974 -> Nous sommes ici en ligne 240 et devrions connaître le résultat du test
11:17:39.433 -> 
11:17:39.433 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
11:17:39.433 -> 
11:17:39.433 -> Soft WDT reset
11:17:39.433 -> 
11:17:39.433 -> >>>stack>>>
11:17:39.433 -> 
11:17:39.433 -> ctx: cont
11:17:39.433 -> sp: 3ffffd90 end: 3fffffc0 offset: 01a0
11:17:39.433 -> 3fffff30:  3fffdad0 3ffef9c0 3ffefb90 40201575  
11:17:39.433 -> 3fffff40:  3fffdad0 00000000 3ffefa08 40201972  
11:17:39.433 -> 3fffff50:  40208cf4 00000000 00001388 3ffefc1c  
11:17:39.433 -> 3fffff60:  00000000 3ffef9c0 00000000 00000000  
11:17:39.433 -> 3fffff70:  00000000 00cd00cf 00000000 00000000  
11:17:39.466 -> 3fffff80:  00000000 00000000 00000001 40100164  
11:17:39.466 -> 3fffff90:  3fffdad0 00000000 3ffefc08 40100185  
11:17:39.466 -> 3fffffa0:  3fffdad0 00000000 3ffefc08 402054f0  
11:17:39.466 -> 3fffffb0:  feefeffe feefeffe 3ffe85ec 40100e71  
11:17:39.466 -> <<<stack<<<
11:17:39.466 -> 
11:17:39.466 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
11:17:39.499 -> 
11:17:39.499 ->  ets Jan  8 2013,rst cause:1, boot mode:(3,2)
11:17:39.499 -> 
11:17:39.499 -> load 0x4010f000, len 3460, room 16 
11:17:39.499 -> tail 4
11:17:39.499 -> chksum 0xcc
11:17:39.499 -> load 0x3fff20b8, len 40, room 4 
11:17:39.499 -> tail 4
11:17:39.499 -> chksum 0xc9
11:17:39.499 -> csum 0xc9
11:17:39.499 -> v00048a80
11:17:39.499 -> ~ld
11:17:39.565 -> 

Merci.

Encore du progrès aujourd'hui. À l'attention de ceux qui chercheront à reproduire ceci, je crois que nous sommes près de la solution finale.

Voici ma sous-routine qui arrive à transmettre à mon site en ligne.

String versCartefoiMeteo() {
  int err = 0;
  Serial.println("Commencement de la procédure de transfert vers cartefoi");
  if (clientCartes.connect(hoteMeteo, 80)) {
    Serial.println("Nous sommes occupés à faire cela en ligne 236");
    clientCartes.print  ("GET http://meteo.cartefoi.net/page.php?key=clef");
    clientCartes.print  ("&valeur1=4.26");
    clientCartes.print  ("&valeur2=4,36");
    clientCartes.print  ("&valeur3=99.12");
    clientCartes.print  ("&valeur4=44");
    clientCartes.print  ("&valeur5=77");
    clientCartes.print  ("&valeur6=88");
    clientCartes.println("&valeur0=valeur0 HTTP/1.0");
    clientCartes.println();
  } else {
    Serial.println("Connexion échouée");
  }
  Serial.println("Nous sommes ici en ligne 240 et devrions connaître le résultat du test");

  // And just stop, now that we've tried a download
  return "Avons-nous réussi ou non?";
} 

La clef de la chose: donner l'URL complet après une première connexion réussie au site.
Première connexion:
clientCartes.connect(hoteMeteo, 80)

Tranfert de données:
clientCartes.print ("GET http://meteo.cartefoi.net/page.php?key ... suivie des variables en GET comme on le fait habituellement en PHP ou autres langages web.

Cette réussite semble en entraîner une autre: plus de déconnexion wifi, plus de message d'erreur. Il faut croire, donc, que la mauvaise connexion entraînait une perte de contact du serveur à lui-même.

Notons aussi que - source de confusion possible - les en-têtes ont été grandement simplifiées. Il ne reste que:

#include <ESP8266WiFi.h>

car je travaillle avec une carte ESP8266. Si vous travaillez avec une autre carte, il est probable que la bibliothèque WiFi.h suffira.

Bonjour à tous,

je n'arrive toujours pas à régler la question de l'IP fixe.

Selon Manuel Arduino - Wifi.config, je devrais pouvoir donner une adresse IP fixe sans autre information.

Wifi.config(ip);

Mais voilà que ce m'est refusé. Voici le message d'erreur retourné:

no matching function for call to 'WiFiClass::config(IPAddress&)'

Quand je donnais ceci:

WiFi.config(local_IP, gateway, subnet);

J'obtenais une adresse fixe, mais je n'arrivais pas communiquer avec l'extérieur. Maintenant, je comprends: il manquait un DNS, car la bonne commande aurait dû être comme

WiFi.config(local_IP, dns, gateway, subnet);

Mais voilà que l'adresse IP refusée nette, alors que c'est conforme au manuel d'usager!
Y comprenez-vous quelque chose ?

Notons ici que je suis avec une autre carte, même config, la carte ESP32-cam et la bibliothèque WiFi.h

Merci

Ça, c'est la doc de la librairie pour le shield Arduino WiFi.

Pour un ESP8266 tu ferais mieux de lire cette doc
https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#config

Oui merci fdufnews,
je tente maintenant le coup avec un ESP32-cam, c'est pourquoi je consulte la docu citée.

Voir ici

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.