Problème de découpage en plusieurs fichiers

Bonsoir,

J'ai un code monolithique (ESP32) qui commence à devenir trop grop et que je veux structurer en plusieurs fichiers. Je commence à comprendre la logique (enfin je pense) et je suis arrivé à extraire une partie du code...

J'ai fait une version simplifiée du code pour la poster ici, sinon c'est trop long
Le fichier .ino

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <LittleFS.h> 

#include "servweb.h"

#define LED_BUILTIN  15
volatile bool ledState;
volatile bool rafraichir;
volatile int valeur;


// Réseau perso
String ssid = "xxxxxxxx";
String pass = "xxxxxxxxxxxxxxxx";
String hostname = "ESP32-WS";
String AP_ssid = "AP_EST32";
String AP_pass = "";
byte AP_canal = 7;
int periode = 1000;



// ------------------------------ PROCESSOR --------------------------------------

String processor(const String& var){
  if(var == "VALEUR"){
    return (String)valeur;
  }

  return String();
}

// ------------------------------ INTERRUPTIONS ----------------------------------
hw_timer_t * timer = NULL;

void IRAM_ATTR timer_isr() {
  // code du timer ici
  ledState = !ledState;
  if (ledState) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
  valeur = random(6) + 1; // tirage du dé
  rafraichir = true;      // pour dire à la loop() qu'il y a de nouvelles données
}


// ------------------------------ SETUP ------------------------------------------
void setup(){
  Serial.begin(115200);
  delay(2000); // laisse moi le temps de démarrer la console série
  
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("démarrage");
  randomSeed(analogRead(13));   // 13 = broche en l'air, sel aléatoire

  if(!LittleFS.begin(1)){  
     Serial.println("erreur de montage LittleFS");
     return;
  }
 

  // wifi avec fall-back en AP si erreur

  WiFi.setAutoConnect(false);

  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
  WiFi.setHostname(hostname.c_str());  // pour définir le hostname vu par le réseau wifi

    Serial.printf("Recherche du réseau %s\r\n", ssid); // réseau prédéfini (non vide)
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(200);
    int nbwifi = WiFi.scanNetworks();
    for (int n = 0; n < nbwifi; ++n) {
      if (WiFi.SSID(n) == ssid) {  // trouvé le bon réseau dans la liste
        WiFi.mode(WIFI_STA); //Mode Station seulement
        // WiFi.config(ip, gateway, subnet); // pour IP fixe
        WiFi.begin(ssid, pass);
        
        ulong timeout = millis();
        Serial.print("Connexion au wifi en cours.");
        while ((WiFi.status() != WL_CONNECTED) and (millis()-timeout < 10000)) {
          digitalWrite(LED_BUILTIN, HIGH);  
          delay(100);
          digitalWrite(LED_BUILTIN, LOW);
          delay(100);
          Serial.print(".");
        }
      }
      delay(100);
    }


  if (WiFi.status() == WL_CONNECTED) {
    // la connexion a réussi
    Serial.println(" Connecté au wifi maison !");
    Serial.print("Serveur accessible à l'adresse : ");  
    Serial.println(WiFi.localIP());

    WiFi.setAutoReconnect(false);  // pas sur que ce soit nécessaire, mais vu dans plusieurs exemples
  } else {
    // echec de connexion
    Serial.println(" Échec de connexion au wifi maison - Fallback en AP");
    
    WiFi.mode(WIFI_AP); // drop station mode if LAN/WiFi is down
    WiFi.softAP(AP_ssid, AP_pass);
    Serial.printf("AP : %s | Adresse IP :  %s\r\n", AP_ssid, WiFi.softAPIP().toString().c_str());

  }
 
  initWebSocket(); 

  // Chemin vers les fichiers... 
  // pour la racine, servir index.html en GET
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, processor);
  });
  // répondre aussi pour index.html appelé explicitement (c'est ballot sinon)
  server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, processor);
  });
  server.on("/apropos.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/apropos.html", String(), false, processor);
  });
  
  AsyncElegantOTA.begin(&server);  // OTA c'est cool
  server.begin();


// interruptions 
  // timer 
  uint8_t timer_id = 0;
  uint16_t prescaler = 80; // CPU à 80MHz ça simplifie les calculs
  int threshold = periode * 1000; // nbr de µs

  timer = timerBegin(timer_id, prescaler, true);
  timerAttachInterrupt(timer, &timer_isr, true);
  timerAlarmWrite(timer, threshold, true);
  timerAlarmEnable(timer);
}
// ------------------------------ FIN DU SETUP -----------------------------------

// ------------------------------ LOOP -------------------------------------------
void loop(){

  ws.cleanupClients();

  if (rafraichir) {
    rafraichir = false;
    ws.textAll(String(valeur));
  }
}

Je voudrais sortir tout ce qui se rapporte au serveur web, j'ai un fichier servweb.h :

#include <Arduino.h>
#include <ESPAsyncWebServer.h>

// ------------------------------ DÉFINITIONS ------------------------------------
extern volatile bool ledState;
extern volatile int valeur;

extern AsyncWebServer server;
extern AsyncWebSocket ws;

// ------------------------------ ROUTINES DE WEBSOCKET --------------------------

void notifyClients();
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
  void *arg, uint8_t *data, size_t len);
void initWebSocket();

et le fichier servweb.cpp correspondant :

#include <Arduino.h>
#include <ESPAsyncWebServer.h>

// ------------------------------ DÉFINITIONS ------------------------------------
extern volatile bool ledState;
extern volatile int valeur;

// ------------------------------ ROUTINES DE WEBSOCKET --------------------------
// copiées collées de https://randomnerdtutorials.com/esp32-websocket-server-arduino/ 

// Le serveur port 80 et la chaussette
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");


void notifyClients() {
  ws.textAll(String(valeur));
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  // pas utilisé puisque pas de bouton dans ma page
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledState = !ledState;
      notifyClients();
    }
  }
}

// pour recevoir les eventements du client
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
//      globalClient = client;
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
//      globalClient = NULL;
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      Serial.printf("WS_EVT_DATA\n", client->id());
      // à priori rien non plus ici puisque rien sur la page (pour le moment)
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

Tout ça c'est OK, ça compile et ça fonctionne...

Mais j'aimerai aussi sortir du code principal la partie String processor(const String& var){} parce que dans le "vrai" code, elle fait quand même 50 lignes et aussi toute la partie qui est dans le setup() avec les fonctions server.on() (200 lignes dans le vrai code)

J'ai essayé de faire un couper-coller de la partie String processor(const String& var){} dans le fichier .cpp et j'ai ajouté String processor(); dans le fichier .h mais la ça compile plus.

Les messages d'erreurs :

/home/christian/Arduino/problemeWS/problemeWS.ino: In lambda function:
problemeWS:111:70: error: no matching function for call to 'AsyncWebServerRequest::send(fs::LittleFSFS&, const char [12], String, bool, String (&)())'
     request->send(LittleFS, "/index.html", String(), false, processor);
                                                                      ^
In file included from /home/christian/Arduino/problemeWS/problemeWS.ino:3:
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:236:10: note: candidate: 'void AsyncWebServerRequest::send(AsyncWebServerResponse*)'
     void send(AsyncWebServerResponse *response);
          ^~~~
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:236:10: note:   candidate expects 1 argument, 5 provided
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:237:10: note: candidate: 'void AsyncWebServerRequest::send(int, const String&, const String&)'
     void send(int code, const String& contentType=String(), const String& content=String());
          ^~~~
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:237:10: note:   candidate expects 3 arguments, 5 provided
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:238:10: note: candidate: 'void AsyncWebServerRequest::send(AsyncWebServerRequest::FS&, const String&, const String&, bool, AwsTemplateProcessor)'
     void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
          ^~~~

(je coupe pour pas faire trop long)

Et là je ne comprend pas les messages d'erreur ni ce qu'il faut faire...

Deuxième souci, je ne vois pas du tout comment sortir également toute la partie qui est dans le setup() ! :question: :question:

Sans tout le code c'est un peu compliqué.

L'erreur t'indique que le compilateur ne trouve de fonction Send qui correspond au type de variable que tu utilise.

processor du coup ne devrais pas prendre en paramètre une String ?

pour la fonction setup, tu peux normalement la déclarer dans n'importe quel .h et implémenter dans n'importe quel .cpp.

Tu peux aussi passer par une autre fonction appelé dans la fonction setup du .ino

J'ai mis tout mon code en version simplifiée (il y a moins de pages HTML et pas de formulaires ce qui limite grandement toute la partie avec les server.on() mais c'est bien ce code complet (mais plus simple) qui ne compile pas.

OK mais send() semble déclaré dans ESPAsyncWebServer.h qui est appelé par #include <ESPAsyncWebServer.h> dans les trois fichiers...

Ca doit venir du fait que tu déclares server dans servweb.cpp. Peut-être que le
extern AsyncWebServer server;
ne suffit pas pour qu'il soit connu dans le fichier ino.

Ok, j'au dû louper un truc.
dans le code que tu as posté processor est dans le point ino, il ne devrait pas être dans tes nouveaux fichiers ?

Tu peux faire un truc simple, pour bien vérifier que l'erreur est sur le dernier paramètre, remplacer processor par null

Bonjour ProfesseurMephisto

Tu mets tout ce qui se trouve dans setup() dans un fichier (setupParametres.h par ex.) que tu mets dans le même répertoire que le INO de l'application.

Dans setup() tu remplaces ce que tu as mis dans le fichier par:
#include "setupParametres.h"

Tu peux employer cette "mécanique" pour tout les bouts de programme que tu veux mettre à l'extérieur.

Cordialement
jpbbricole

Merci de te pencher sur mon cas :wink:
Je suis peut-être pas clair, je vais préciser :

dans le premier message, le code compile et processor est dans le .ino
Si je déplace processor dans le fichier .cpp ça ne compile plus.

C'est pas super beau de mettre du code dans un .h et encore moins de faire du remplacement de corps de fonction :smiley:
le mieux serait dans ce cas de mettre la fonction setup, directement dans le cpp non ?

Merci de ton aide... juste pour vérifier que j'ai bien compris : il n'est pas nécessaire de commencer le fichier .ino par tous les #include ?
Je peux donc faire un truc du genre :

void setup(){
  Serial.begin(115200);
  delay(2000); // laisse moi le temps de démarrer la console série
  
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("démarrage");
  randomSeed(analogRead(13));   // 13 = broche en l'air, sel aléatoire

  if(!LittleFS.begin(1)){  
     Serial.println("erreur de montage LittleFS");
     return;
  }

// des includes en plein milieu du setup() ??
#include "partie_wifi.h"
#include "partie_GET_POST.h" 

}

Oui, c'est ce que j'en avais plus ou moins déduis, mais du coup on ne voit pas vraiment ce que tu as fait et en plus du parlais d'un "String processor();" dans le fichier d'en-tête.
Je voulais juste indiqué que c'est plus simple, si tu donne directement ton code qui ne marche pas, cela évite les manipulations qui peuvent être différente suivant chacun.

Tu as essayé de mettre null à la place de ta callback ?

le code est dans le .cpp non ? C'est sale quand même ce que j'ai proposé juste avant ?

Oui, tu peux les mettre n'importe ou et déstructurer tes fichiers :face_with_hand_over_mouth:
Conventionnellement on les regroupes au début, car plus facile à trouver, plutôt qu'en plein milieu d'un fichier de plusieurs milliers de lignes.

Il y a quelques cas ou des includes doivent être placés en plein milieu

Non, ton code me parais bien, c'est la solution de @jpbbricole qui est "sale", mais fonctionnel.

C'était juste pour ne pas allonger kilométriquement le fil :wink:

fichier .ino

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#include <LittleFS.h> 

#include "servweb.h"
extern AsyncWebServer server;


#define LED_BUILTIN  15
volatile bool ledState;
volatile bool rafraichir;
volatile int valeur;


// Réseau perso
String ssid = "*********";
String pass = "***********";
String hostname = "ESP32-WS";
String AP_ssid = "AP_ESP32";
String AP_pass = "";
byte AP_canal = 7;
int periode = 1000;



// ------------------------------ INTERRUPTIONS ----------------------------------
hw_timer_t * timer = NULL;

void IRAM_ATTR timer_isr() {
  // code du timer ici
  ledState = !ledState;
  if (ledState) {
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    digitalWrite(LED_BUILTIN, LOW);
  }
  valeur = random(6) + 1; // tirage du dé
  rafraichir = true;      // pour dire à la loop() qu'il y a de nouvelles données
}


// ------------------------------ SETUP ------------------------------------------
void setup(){
  Serial.begin(115200);
  delay(2000); // laisse moi le temps de démarrer la console série
  
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("démarrage");
  randomSeed(analogRead(13));   // 13 = broche en l'air, sel aléatoire

  if(!LittleFS.begin(1)){  
     Serial.println("erreur de montage LittleFS");
     return;
  }
 

  // wifi avec fall-back en AP si erreur

  WiFi.setAutoConnect(false);

  WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE, INADDR_NONE);
  WiFi.setHostname(hostname.c_str());  // pour définir le hostname vu par le réseau wifi

    Serial.printf("Recherche du réseau %s\r\n", ssid); // réseau prédéfini (non vide)
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(200);
    int nbwifi = WiFi.scanNetworks();
    for (int n = 0; n < nbwifi; ++n) {
      if (WiFi.SSID(n) == ssid) {  // trouvé le bon réseau dans la liste
        WiFi.mode(WIFI_STA); //Mode Station seulement
        // WiFi.config(ip, gateway, subnet); // pour IP fixe
        WiFi.begin(ssid, pass);
        
        ulong timeout = millis();
        Serial.print("Connexion au wifi en cours.");
        while ((WiFi.status() != WL_CONNECTED) and (millis()-timeout < 10000)) {
          digitalWrite(LED_BUILTIN, HIGH);  
          delay(100);
          digitalWrite(LED_BUILTIN, LOW);
          delay(100);
          Serial.print(".");
        }
      }
      delay(100);
    }


  if (WiFi.status() == WL_CONNECTED) {
    // la connexion a réussi
    Serial.println(" Connecté au wifi maison !");
    Serial.print("Serveur accessible à l'adresse : ");  
    Serial.println(WiFi.localIP());

    WiFi.setAutoReconnect(false);  // pas sur que ce soit nécessaire, mais vu dans plusieurs exemples
  } else {
    // echec de connexion
    Serial.println(" Échec de connexion au wifi maison - Fallback en AP");
    
    WiFi.mode(WIFI_AP); // drop station mode if LAN/WiFi is down
    WiFi.softAP(AP_ssid, AP_pass);
    Serial.printf("AP : %s | Adresse IP :  %s\r\n", AP_ssid, WiFi.softAPIP().toString().c_str());

  }
 
  initWebSocket(); 

  // Chemin vers les fichiers... 
  // pour la racine, servir index.html en GET
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, processor);
  });
  // répondre aussi pour index.html appelé explicitement (c'est ballot sinon)
  server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, processor);
  });
  server.on("/apropos.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/apropos.html", String(), false, processor);
  });
  
  AsyncElegantOTA.begin(&server);  // OTA c'est cool
  server.begin();


// interruptions 
  // timer 
  uint8_t timer_id = 0;
  uint16_t prescaler = 80; // CPU à 80MHz ça simplifie les calculs
  int threshold = periode * 1000; // nbr de µs

  timer = timerBegin(timer_id, prescaler, true);
  timerAttachInterrupt(timer, &timer_isr, true);
  timerAlarmWrite(timer, threshold, true);
  timerAlarmEnable(timer);
}
// ------------------------------ FIN DU SETUP -----------------------------------

// ------------------------------ LOOP -------------------------------------------
void loop(){

  ws.cleanupClients();

  if (rafraichir) {
    rafraichir = false;
    ws.textAll(String(valeur));
  }
}

fichier servweb.cpp :

#include <Arduino.h>
#include <ESPAsyncWebServer.h>

// ------------------------------ DÉFINITIONS ------------------------------------
extern volatile bool ledState;
extern volatile int valeur;

// ------------------------------ ROUTINES DE WEBSOCKET --------------------------
// copiées collées de https://randomnerdtutorials.com/esp32-websocket-server-arduino/ 

// Le serveur port 80 et la chaussette
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");


void notifyClients() {
  ws.textAll(String(valeur));
}

void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
  // pas utilisé puisque pas de bouton dans ma page
  AwsFrameInfo *info = (AwsFrameInfo*)arg;
  if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
    data[len] = 0;
    if (strcmp((char*)data, "toggle") == 0) {
      ledState = !ledState;
      notifyClients();
    }
  }
}

// pour recevoir les eventements du client
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
             void *arg, uint8_t *data, size_t len) {
  switch (type) {
    case WS_EVT_CONNECT:
      Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
//      globalClient = client;
      break;
    case WS_EVT_DISCONNECT:
      Serial.printf("WebSocket client #%u disconnected\n", client->id());
//      globalClient = NULL;
      break;
    case WS_EVT_DATA:
      handleWebSocketMessage(arg, data, len);
      Serial.printf("WS_EVT_DATA\n", client->id());
      // à priori rien non plus ici puisque rien sur la page (pour le moment)
      break;
    case WS_EVT_PONG:
    case WS_EVT_ERROR:
      break;
  }
}

void initWebSocket() {
  ws.onEvent(onEvent);
  server.addHandler(&ws);
}

// ------------------------------ PROCESSOR --------------------------------------

String processor(const String& var){
  if(var == "VALEUR"){
    return (String)valeur;
  }

  return String();
}

fichier servweb.h

#include <Arduino.h>
#include <ESPAsyncWebServer.h>

// ------------------------------ DÉFINITIONS ------------------------------------
extern volatile bool ledState;
extern volatile int valeur;

extern AsyncWebServer server;
extern AsyncWebSocket ws;

// ------------------------------ ROUTINES DE WEBSOCKET --------------------------

void notifyClients();
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len);
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type,
  void *arg, uint8_t *data, size_t len);
void initWebSocket();

String processor();

Message d'erreur :

/home/christian/Arduino/problemeWS/problemeWS.ino: In lambda function:
problemeWS:113:70: error: no matching function for call to 'AsyncWebServerRequest::send(fs::LittleFSFS&, const char [12], String, bool, String (&)())'
     request->send(LittleFS, "/index.html", String(), false, processor);
                                                                      ^
In file included from /home/christian/Arduino/problemeWS/problemeWS.ino:3:
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:236:10: note: candidate: 'void AsyncWebServerRequest::send(AsyncWebServerResponse*)'
     void send(AsyncWebServerResponse *response);
          ^~~~
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:236:10: note:   candidate expects 1 argument, 5 provided
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:237:10: note: candidate: 'void AsyncWebServerRequest::send(int, const String&, const String&)'
     void send(int code, const String& contentType=String(), const String& content=String());
          ^~~~
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:237:10: note:   candidate expects 3 arguments, 5 provided
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:238:10: note: candidate: 'void AsyncWebServerRequest::send(AsyncWebServerRequest::FS&, const String&, const String&, bool, AwsTemplateProcessor)'
     void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr);
          ^~~~
/home/christian/Arduino/libraries/ESP_Async_WebServer/src/ESPAsyncWebServer.h:238:10: note:   no known conversion for argument 5 from 'String()' to 'AwsTemplateProcessor' {aka 'std::function<String(const String&)>'}

je ne sais pas si la suite est importante ou pas... 

La compilation s'arrête alors sur null :

La partie du code modifiée dans le .ino

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, null);
  });
  // répondre aussi pour index.html appelé explicitement (c'est ballot sinon)
  server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/index.html", String(), false, null);
  });
  server.on("/apropos.html", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(LittleFS, "/apropos.html", String(), false, null);
  });

Message d'erreur :

/home/christian/Arduino/problemeWS/problemeWS.ino: In lambda function:
problemeWS:114:61: error: 'null' was not declared in this scope
     request->send(LittleFS, "/index.html", String(), false, null);
                                                             ^~~~
/home/christian/Arduino/problemeWS/problemeWS.ino:114:61: note: suggested alternative: 'kill'

Une fois, j’avais repris un exemple où le code html était dans le fichier principal.
C’etait difficile a lire, la partie html n’ayant aucune coloration syntaxique.

Pour alléger la lecture j’avais transféré le code html dans un fichier code.html.
L’include #include ”code.html” était placé à l’emplacement où était le code.
Include n’est pas limité au fichier header (*.h).

J’utilisais plateformIO.
Dans le repertoire du projet j’avais un fichier main.cpp et le fichier code.html.

J’ai eu l’agréable surprise de voir que Vscode/PIO apportaient la coloration syntaxique adaptée html au fichier code.html.
C’est un confort qui m’est devenu indispensable.

1 Like

Salut.

servweb.h : le prototype de cette méthode n'est pas le bon.

String processor(const String& var)

Par contre dans le fichier .cpp c'est correct.

Oui c'est ce que je parlais dans le post #10, c'est pour ça que je voulais qu'il teste avec null.
Mais bizarrement null n'est pas connu.

@ProfesseurMephisto j'ai essayé de compiler ton code, mais tu ne semble pas utiliser les même librairies que j'ai trouvé.

En C / C++ : NULL

Je croyais que dans le fichier .h il ne fallait pas remettre els paramètres des fonctions... C'est pour ça que j'ai mis void notifyClients(); etc.

Je devine une incompréhension de ma part :wink:

Incompréhension confirmée : je les ai laissé pour void handleWebSocketMessage()...