Creation reseau wifi

Bonjour

J'ai actuellement 2 programmes qui tournent correctement,
et totalement indépendants (ESP32-1) et (ESP32-2).

J'aimerais accéder a leurs variables (environ une dizaine chacun et des Int et Float)
et les envoyer sur L'ESP32-3, a des fins de visualisation, sur un nextion et/ou une page internet.

Après avoir parcouru beaucoup de tutos, je dois reconnaitre que je suis perdu.

Déjà, pensez-vous que mon idée soit réalisable ?

Dans tous les tutos que j'ai vu, pas un seul ne parlait d'envoyer des int et floats
seulement des strings (générateurs de problèmes de mémoire).

ps: Ce sont des ESP32-Wroom-32D

gandalf60:
Dans tous les tutos que j'ai vu, pas un seul ne parlait d'envoyer des int et floats
seulement des strings (générateurs de problèmes de mémoire).

Bonjour,
Faut pas généraliser. La classe String est un problème sur des processeurs comme ATmega328 où il y a très peu de ressources et où l'allocation dynamique devient rapidement un problème en fractionnant la mémoire. Sur l'ESP32 qui dispose de beaucoup plus de mémoire cela ne devrait pas être une problème.

De plus, il ne faut pas confondre String et string.

  • String est une classe qui simplifie la manipulation des chaînes de caractères. Mais en contrepartie elle est gourmande en ressources mémoire.
  • Une "string" c'est juste une chaîne de caractères (char *) et là il n'y a pas de problème avec la mémoire. Par contre la manipulation est un peu plus difficile, mais pas insurmontable.

Bonjour

Il s'agit bien de String.

Si je comprend bien, je ne peux pas envoyer directement des variables "nombre",
je dois les convertir en chaines de caractères ?

vous pouvez envoyer ce que vous voulez, ce sont des octets qui circulent...

Votre communication "Wi-Fi" entre [(ESP32-1) / (ESP32-2)] avec (ESP32-3) ne veut pas dire grand chose. Ce qui compte c'est le protocole que vous allez utiliser pour transporter l'information sur le réseau.

Si [(ESP32-1) / (ESP32-2)] offrent une interface de type HTTP, alors vous enverrez une requête de type GET ou POST à vos ESP qui vont fabriquer une réponse HTTP par exemple. (ESP32-3) va récupérer cette réponse et la traiter. cf ESPAsyncWebServer)

Vous pouvez aussi utiliser juste une connexion TCP pour discuter entre les modules => cf AsyncClient et AsyncServer dans AsyncTCP) où vous pourrez passer des trames de données sous forme de buffer (donc envoyer une structure qui contient toutes vos valeurs par exemple).

Je ne vois pas l'intérêt du 3ème ESP32, à moins que les deux autres soient dans des endroits peu accessibles. Un ESP32 peut certainement supporter l'une de tes applis et faire l'affichage sur le Nextion, qui demande peu de ressources.

La bibliothèque painlessmesh permet de créer un réseau maillé avec des ESPxx. Elle permet de simplifier les passages de messages et de données entre nœuds du réseau.
L'ESP3 peut être déclaré root et héberger le serveur Web ainsi que l'affichage Nextion. Si tu utilises 2 EPS seulement, cette bibli ne se justifie pas vraiment.

La première chose à faire est d'analyser les flux de données. Comme dit plus haut, peu importe quoi, mais ce qui est important est qui prend l'initiative d'un transfert (conséquence qui est client / qui est serveur). On peut avoir une même machine (par exemple ESP32) qui est client sur un flux de données, serveur sur un autre. Une fois que c'est fait, on choisit un protocole (TCP, UDP, propriétaire sur socket). A mon avis, dans un cas comme ça, UDP est le mieux adapté. Puis on installe les couches de logiciel nécessaires. Enfin on programme la logique de contrôle des échanges.

Tout ça me parait bien compliqué pour lire des températures et régler des radiateurs. Même dans les grosses GTC de bâtiments tertiaires on essaie de faire plus simple.

Merci pour vos réponses très pertinentes.

@J-M-L merci pour les liens, que j'ai parcourus, et qui pour l'instant, m'embrouillent encore plus.
Je ne suis pas au niveau pour comprendre.

@ Lesept En effet les ESP32-1 et le 2 sont éloignés de 15m.

Comme tu le fait remarquer, je pourrais peut-être me passer du 3eme ESP, si le 2eme

  • gère les échanges avec le nano de la chambre 1 (émission et réception)
  • Gère son propre programme
  • gère le nextion (émission et réception)
  • et (si j'y arrive un jours) gérer une petite page (pour l'instant juste de la visu de valeurs).
    Ce n'est pas un peu beaucoup pour lui?

Sinon une autre idée
L'ESP-3 ne gère plus de nextion, seulement la page web.
Je vais creuser la bib painlessmesh, qui a l'air très intéressante
mais je me rend compte que je suis très loin de pouvoir mettre cela en œuvre.

@JiPe38 Pourquoi faire simple quand on peut faire compliqué? :))

C'est vrai que mon dessin prête a confusion.

En fait l'ESP32-1 et l'ESP32-2 gèrent 2 choses totalement différentes et ne sont pas interconnectés.

Le 1 est au RDC pour des raisons pratiques (proche de la cave).

Le 2 gère en effet le chauffage du RDC et de l'étage.

Mon idée était que l'ESP32-3 "récolte" les informations des 2 autres ESP pour y accéder depuis une tablette ou un pc.
Mais uniquement pour visualiser des données.

Mon idée était que l'ESP32-3 "récolte" les informations des 2 autres ESP pour y accéder depuis une tablette ou un pc.
Mais uniquement pour visualiser des données.

un des 2 ESP pourrait jouer ce rôle, à moins bien sûr que vous ne fassiez énormément de choses déjà avec le processeur

Bonjour

Au final l'ESP32-1 serait le plus a même de gérer cela, ça vaut le coup d'essayer.

Je peux faire des essais facilement, car L'esp32-2 n'est pas encore installé (c'est encore un mega a la place).

De toute façon ce ne sont pas des données critiques, je peux me permettre de ne rafraichir la page qu'une fois toutes les minutes.

Je désire afficher environ une dizaine de variables issues de chaque esp, donc une vingtaine.

Pour faire des essais, je pense que l'esp 2 qui est libre; peut jouer le rôle de "récolteur"
et d’échanger une ou deux variables pour mettre au point le bazar...

Je vais essayer de trouver un exemple de com, et aussi de créer une petite page web....

Bonne journée

Pour me donner une idée j'ai fait un essai de page html avec un petit programme que j'ai trouvé sur le net.
Celui-ci allume et éteint une led.

Je vais m'en servir de base pour créer ma 1ere page pour afficher 2 variables.

Je suis sidéré par la place en mémoire qu'occupe ce petit programme.
54% de l'espace stockage programme et 12% de mémoire dynamique.

Bon, j'ai la place car mon prog prend (pour l'instant) 18% et 5%.

Voici le programme en question:

#include <WiFi.h>  // Librairie Wifi.h
#include <WebServer.h>  // Librairie WebServer.h

const char* ssid = "Livebox******";
const char* password = "**************";
WebServer server(80);

const int led = 5;  // Led sur GPIO5
bool etatLed = 0;
char texteEtatLed[2][10] = {"ÉTEINTE","ALLUMÉE"};  // Affichage ETEINTE ou ALLUMEE

void handleRoot(){   // Début de la page HTML
  String page = "<!DOCTYPE html>";
    page += "<html lang='fr'>";
    
    page += "<head>";
    page += "    <title>Serveur ESP32</title>";
    page += "    <meta http-equiv='refresh' content='60' name='viewport' content='width=device-width, initial-scale=1' charset='UTF-8'/>";
    page += "    <link rel='stylesheet' href='https://www.w3schools.com/w3css/4/w3.css'>";  //# Utilisation du css 
    page += "</head>";

    page += "<body>";
    page += "    <div class='w3-card w3-blue w3-padding-small w3-jumbo w3-center'>";
    page += "        <p>ÉTAT LED: "; page += texteEtatLed[etatLed]; page += "</p>";
    page += "    </div>";

    page += "    <div class='w3-bar'>";
    page += "        <a href='/on' class='w3-bar-item w3-button w3-border w3-jumbo' style='width:50%; height:50%;'>ON</a>";
    page += "        <a href='/off' class='w3-bar-item w3-button w3-border w3-jumbo' style='width:50%; height:50%;'>OFF</a>";
    page += "    </div>";

    page += "    <div class='w3-center w3-padding-16'>";
    page += "        <p>Ce serveur est hébergé sur un ESP32</p>";
    page += "        <i>Créé par Tommy Desrochers</i>";
    page += "    </div>";

    page += "</body>";
    page += "</html>";  // Fin de la page HTML

    server.setContentLength(page.length());  // Permet l'affichage plus rapide après chaque clic sur les boutons
    server.send(200, "text/html", page);
}

void handleOn(){  // Code pour allumer la led
    etatLed = 1;
    digitalWrite(led, HIGH);
    server.sendHeader("Location","/");
    server.send(303);
}

void handleOff(){   // Code pour éteindre la led
    etatLed = 0;
    digitalWrite(led, LOW);
    server.sendHeader("Location","/");
    server.send(303);
}

void handleNotFound(){  // Page Not found
  server.send(404, "text/plain","404: Not found");
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("\n");

  pinMode(led, OUTPUT); // Définition de la led en OUTPUT
  digitalWrite(led, 0);  // Initialisation de la led à 0 (éteinte)

  WiFi.persistent(false);
  WiFi.begin(ssid, password);
  Serial.print("Attente de connexion ...");

  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(100);
  }

  Serial.println("\n");
  Serial.println("Connexion etablie !");
  Serial.print("Adresse IP: ");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);  // Chargement de la page accueil
  server.on("/on", handleOn);  // Chargement du handleOn - Allumée la led
  server.on("/off", handleOff);  // Chargement du handleOff - Eteindre la led
  server.onNotFound(handleNotFound);  // Chargement de la page Not found
  server.begin();

  Serial.println("Serveur web actif");
}

void loop() {
  server.handleClient();
}

/*
Vérifier et téléverser le code dans l'Esp32

Ouvrir le moniteur série pour visualiser les informations et l'adresse IP de l'Esp32

Ouvir un navigateur et saisir l'adresse IP de l'Esp32
*/

Je suis sidéré par la place en mémoire qu'occupe ce petit programme.

Oui mais il faut quand même gérer tout le protocole HTTP sur votre ESP et avoir des buffers de travail... c'est ce que fait la bibliothèque

Avec un ESP32 je vous recommanderais de prendre ESPAsyncWebServer plutôt que la librairie WebServer.h

la même gestion de LED ressemblerait par exemple à cela

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
AsyncWebServer server(80);

const char* ssid = "xxx";  // A REMPLIR
const char* password = "xxx";  // A REMPLIR

const byte ledPin = 2; // led bleue embarquée sur ma carte ESP32
const char index_html[] PROGMEM = "<p>GESTION DE LA LED:</p><ul><li><a href=\"/on\">Led ON</a></li><li><a href=\"/off\">Led OFF</a></li></ul>";
const char ledon_html[] PROGMEM = "<p>LA LED EST ON</p><ul><li><a href=\"/off\">Led OFF</a></li></ul>";
const char ledoff_html[] PROGMEM = "<p>LA LED EST OFF</p><ul><li><a href=\"/on\">Led ON</a></li></ul>";

void allumer() {
  digitalWrite(ledPin, HIGH);
}

void eteindre() {
  digitalWrite(ledPin, LOW);
}

void notFound(AsyncWebServerRequest *request) {
  request->send_P(200, "text/html", index_html);
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("Erreur connexion WiFi\n");
    while (true) yield();
  }

  Serial.print("site web: http://"); Serial.println(WiFi.localIP());

  // définition des pages
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });

  server.on("/on", HTTP_GET, [](AsyncWebServerRequest * request) {
    allumer();
    request->send_P(200, "text/html", ledon_html);
  });

  server.on("/off", HTTP_GET, [](AsyncWebServerRequest * request) {
    eteindre();
    request->send_P(200, "text/html", ledoff_html);
  });

  server.onNotFound(notFound);

  server.begin();
}

void loop() {}

c'est à peine plus gourmand - 55% de l'espace de stockage de programmes, 12% de mémoire ram - mais c'est ensuite plus puissant et flexible

Bonjour

J’essaie votre code

j'ai bien chargé la librairie ESPAsyncWebServer
Mais a la compil il ne trouve pas AsyncTCP

s'agit-il de celle-ci sur github?
AsyncTCP=GitHub - Bmooij/AsyncTCP: Async TCP Library for ESP32

J'avais réussi a me faire une petite page (3 lignes)avec l'autre.

Salut

oui oui, votre autre code est très bien et fonctionnel. La bibliothèque ESPAsyncWebServer est juste plus riche / performante sur ESP32

effectivement il faut installer ESPAsyncTCP --> il faut aller regarder sur la page origine

For ESP8266 it requires ESPAsyncTCP To use this library you might need to have the latest git versions of ESP8266 Arduino Core

For ESP32 it requires AsyncTCP to work To use this library you might need to have the latest git versions of ESP32 Arduino Core

c'est le lien vers la seconde dont vous avez besoin

Un mal de chien pour accéder au site, sur les 2 pc

Entre temps j'avais installé la librairie que j'avais cité, et ca marche

Bon, en même temps le but n'est pas d'allumer une led, mais d'afficher des données issue de l'autre esp.
D'ailleurs, je vais libérer l'autre esp pour les essais de transmission, comme ça il n'y aura que la partie "web".

si vous avez un exemple pour lire une variable je suis preneur.

Merci de votre implication

Vous ne trouverez pas de bibliothèque qui vous offre toute faite une fonction pour "lire une variable" sur une autre machine à travers une liaison wifi. Pas plus pour l'écrire. Il vous faut gérer une transaction dans laquelle une des machines lit une variable et l'envoie sur l'autre, qui la reçoit et en fait ce qu'elle veut. Et ça, il vous faut le coder. Donc mettre en place un serveur, un client, et coder le fait que le client interroge le serveur qui répond. La transmission de votre information (la variable) peut être dans le sens client->serveur, ou serveur->client. A vous de voir, sachant que c'est le client qui a l'initiative de l'échange.

si vous avez un exemple pour lire une variable je suis preneur.

Voici un exemple qui n'utilise pas le serveur HTTP pour faire les demandes mais juste la connexion TCP

Vous avez un ESP32 principal qui veut lire des données (c'est un client) et un autre qui fournit des données (c'est un serveur).

Pour que la communication TCP fonctionne entre 2 ordinateurs sur un réseau IP, il faut que le client connaisse l'adresse du serveur --> Pour simplifier l'exemple, j'ai câblé en dur l'adresse du serveur

L'idée de cet exemple c'est que le client envoie une requête TCP au serveur qui ne contient qu'un seul octet: un caractère qui sera le nom de la variable attendue ('x' par exemple).

Le serveur va recevoir cette demande et va fabriquer une réponse qui sera un texte ASCII
"[color=blue]x[/color] = [color=purple]1234[/color]"
on reprendra donc le x et comme je n'ai pas voulu rendre compliqué le code, la valeur retournée pour la variable sera simplement millis() à l'instant de la requête.

Donc pour résumer: l'utilisateur tape x dans la console série du client, le caractère 'x' est envoyé dans une requête TCP au serveur qui fabrique une réponse "x = 1234" et la retourne au client qui nous l'affiche.

Voici le code du serveur:

// FOURNISSEUR DE DONNEES

#include <WiFi.h>
#include <AsyncTCP.h>

const uint16_t serverPort = 7050;
AsyncServer server(serverPort); // écoute le port tcp 7050

const char* ssid = "*********";  // A REMPLIR
const char* password = "*********";  // A REMPLIR

void reception(void* arg, AsyncClient* client, void *data, size_t len) {
  char reponse[30];
  Serial.print(F("Demande ")); Serial.println(((char*)data)[0]);

  if (client->space() > sizeof(reponse) && client->canSend()) {
    snprintf(reponse, 30, "%c = %lu", ((char*)data)[0], millis()); // fabique "x = 1000" par exemple
    client->add(reponse, strlen(reponse));
    client->send();
  }
}

void gestionClient(void* arg, AsyncClient* client) {
  Serial.print(F("Nouveau client: "));  Serial.println(client->remoteIP());
  client->onData(&reception, NULL);  // attacher le callback appeler reception() quand on reçoit des données
}

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("Serveur: Erreur connexion WiFi\n");
    while (true) yield();
  }
  Serial.print("Serveur IP: "); Serial.println(WiFi.localIP());

  server.onClient(gestionClient, &server);
  server.begin();
}

void loop() {}

Le code devrait se comprendre assez aisément

  • on a une variable globale server de type AsyncServer qui écoute sur le port 7050
  • dans le setup on se connecte au Wi-Fi, puis on attache la fonction gestionClient() si on a un événement de type 'nouvelle Connection' sur notre serveur. et on active le serveur.

Quand un client se connecte, la fonction est déclenchée et on attache à ce client un callback qui s'appelle reception(). Dès que ce client envoie une requête, la fonction reception() est appelée avec les bons paramètres (on peut avoir plusieurs clients).

Dans cette fonction reception(), on prépare simplement une petite réponse en ASCII du type "x = 1234" où x est le caractère reçu dans la requête et le nombre la valeur de millis(). C'est fait par

snprintf(reponse, 30, "%c = %lu", ((char*)data)[0], millis());

puis on envoie cela au client.

Vous chargez donc ce code sur votre premier ESP32
Vous ouvrez la console série à 115200 bauds et regardez ce qu'il s'affiche.
Le mien dit [color=purple]Serveur IP: 10.0.0.23[/color]
==> Prenez note de cette adresse IP car on en a besoin pour le code du client (MASTER)

Voici le code du client

// DEMANDE DE DONNEES

#include <WiFi.h>
#include <AsyncTCP.h>


IPAddress serverIP(10, 0, 0, 23); // <<=== ICI RENTRER L'ADRESSE IP DU SERVEUR
const uint16_t serverPort = 7050;

AsyncClient client;

const char* ssid = "*********";  // A REMPLIR
const char* password = "*********";  // A REMPLIR

void demande(char variable) {
  if (client.space() > sizeof(variable) && client.canSend()) {
    Serial.print(F("envoi req pour ")); Serial.println(variable);
    client.add(&variable, sizeof(variable));
    client.send();
  } else Serial.println(F("MASTER: CAN'T SEND A REQUEST"));
}

void reception(void* arg, AsyncClient* client, void *data, size_t len) {
  Serial.write('\t');
  Serial.write((uint8_t*)data, len); // la réponse
  Serial.write('\n');
}

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("Master: Erreur connexion WiFi\n");
    while (true) yield();
  }

  client.onData(&reception, &client); // appeler reception() quand on reçoit des données
  client.connect(serverIP, serverPort);

  Serial.println(F("\n-----\nEntrez une variable entre 'a' et 'z'\n"));
}

void loop() {
  int r = Serial.read();
  if ((r >= 'a') && (r <= 'z')) demande(r); // simulation de demande d'une variable
}

Notez la ligne IPAddress serverIP([color=red]10, 0, 0, 23[/color]); où j'ai codé en dur l'adresse du serveur (attention séparation par des virgules, pas des points).

Le code devrait se comprendre assez aisément

  • on a une variable globale client de type AsyncClient qui va représenter notre connexion au serveur.
  • dans le setup on se connecte au Wi-Fi, puis on attache la fonction reception() si on a un événement de type "réception de données" sur ce client puis on se connecte au serveur sur le bon port.
  • la loop ne fait qu'écouter le port série et si le caractère reçu est entre 'a' et 'z' alors on appelle la fonction demande()
  • cette fonction demande() construit une requête de taille 1 octet (la taille d'un char), puis l'envoie au serveur
  • le système est asynchrone donc la fonction est terminée, mais quand le serveur répond, notre fonction reception() est appelée et les data[] contiennent le message préparé par le serveur, que l'on imprime.

Vous chargez ce ce code sur le second ESP32 et dans la console à 115200 bauds vous allez voir

[color=purple]-----
Entrez une variable entre 'a' et 'z'[/color]

tapez x par exemple dans la console, vous devriez voir

[color=purple]envoi req pour x
 x = 279076[/color]

tapez maintenant y dans la console, vous devriez voir

[color=purple]envoi req pour y
 y = 306119[/color]

Bien sûr la valeur de la variable va changer en fonction de millis() sur le serveur, les vôtres seront différentes.
Vous verrez que ce n'est pas toujours instantané, il y a bien envoi de la demande et un peu plus tard la réponse arrive.

pour adapter ce code à votre besoin, vous aurez un client (le master) qui va juste balancer 1 octet à différents serveurs (faudra connaître leur IP ou utiliser le DNS). Chaque serveur reçoit la demande, va bâtir une réponse qui sera simplement une structure qui contient tous les paramètres y compris son identifiant (puisque vous allez recevoir les réponse de manière asynchrone, il faudra savoir si c'est la chambre ou le salon qui vous répond) et envoyer (c'est en binaire) la structure.

La fonction de reception() du master va donc être appelée plusieurs fois avec des réponses des différents serveurs, vous recevez les data[] dans une structure similaire à celle du serveur et vous pouvez comme cela extraire facilement les données et les stocker ou les afficher.

PS/ ici je fais la connexion au serveur dans le setup(), en dur et qu'une seule fois. Si pour une raison ou pour une autre cette connexion tombe, ça ne fonctionne plus et faut rebooter. Votre code devra donc être plus solide et se connecter à la demande, puis une fois obtenu la réponse clore la connection par exemple.

Merci infiniment

Plus le temps ce week-end, mais je m'y colle des Lundi.

Bon Dimanche a vous.

@ jiPe38

Je suis conscient que je ne trouverais pas un truc clé en main.
Je vois le "principe" des transactions a effectuer, mais la syntaxe a employer.......

Je connais bien la programmation des automates industrielles (siemens), mais là, je découvre ce genre d'échange.

Merci a vous et bon Dimanche

avec la bibliothèque ce n'est pas super compliqué on établit la connexion client.connect(serverIP, serverPort);puis on envoie un paquet d'octets pour la requête

client.add(adresseDuMessage, tailleDuMessage));
client.send();

et on reçoit un paquet de len octets dans le buffer data[] pour la réponse dans le call back. void reception(void* arg, AsyncClient* client, void *data, size_t len) {

le serveur de son côté a reçu la demande et a préparé l'envoi exactement de la même façon avec

client.add(adresseDuMessage, tailleDuMessage));
client.send();

Faut juste que vous décidiez quoi mettre dans le Message et une structure c'est super pratique pour envoyer des données

struct {
  int a;
  long b;
  float c;
} maStructure;
...
client.add((const char*) &maStructure, sizeof(maStructure)));
client.send();

Bonjour

J'ai essayé les exemples serveur et client, et ça fonctionne.

Dans le serveur j'ai créé une petite structure, et essayé de l'envoyer
J'ai un défaut a la compil

"no matching function for call to 'AsyncClient::add(Send&, unsigned int)'"

Sur la ligne

 client->add(maStructure, sizeof (maStructure));

Je remet le code complet, au cas ou.

//Voici le code du serveur:==========================================================

// FOURNISSEUR DE DONNEES

#include <WiFi.h>
#include <AsyncTCP.h>

const uint16_t serverPort = 7050;
AsyncServer server(serverPort); // écoute le port tcp 7050

const char* ssid = "Livebox-XXX";
const char* password = "XXXXXXXXXXXXXXXX";

float envoi1 = 12.3;
int envoi2 = 258;

struct Send // Infos a envoyer
{
  float val1;
  int val2;
};

void reception(void* arg, AsyncClient* client, void *data, size_t len) {
  char reponse[30];
  Serial.print(F("Demande ")); Serial.println(((char*)data)[0]);

  if (client->space() > sizeof(reponse) && client->canSend()) {

    //snprintf(reponse, 30, "%c = %lu", ((char*)data)[0], millis()); // fabrique "x = 1000" par exemple
    //client->add(reponse, strlen(reponse));
    Send maStructure;
    maStructure.val1 = envoi1;
    maStructure.val2 = envoi2;
    client->add(maStructure, sizeof (maStructure));
    client->send();
  }
}

void gestionClient(void* arg, AsyncClient* client) {
  Serial.print(F("Nouveau client: "));  Serial.println(client->remoteIP());
  client->onData(&reception, NULL);  // attacher le callback appeler reception() quand on reçoit des données
}

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("Serveur: Erreur connexion WiFi\n");
    while (true) yield();
  }
  Serial.print("Serveur IP: "); Serial.println(WiFi.localIP());

  server.onClient(gestionClient, &server);
  server.begin();
}

void loop() {

}

Merci de votre compréhension.