Serveur web sur Wemos D1 Mini

Bonsoir à tous,
Newbee sur Arduino et encore plus sur WEMOS, je me suis lancé dans un projet de lecture de température d'une piscine.
La lecture et l'affichage sur un PC ou un mobile fonctionne.
Ayant vu une jauge pour une cuve d'eau de pluie avec un beau camembert réalisé en javascript, je l'ai testé et cela fonctionne donc, j'ai cherché et trouvé un joli thermomètre en java aussi.
J'ai modifié un peu le fichier index.html pour qu'il corresponde à mon besoin. J'ai placé tout ça dans un répertoire data sous mon projet et quand je lance index.html, il m'affiche bien mon thermomètre sur le PC, par contre quand je le télécharge sur la mémoire flash du Wemos, il ne trouve pas un fichier css (qui pourtant est bien sous data) et me mets des messages d'erreur sur le fichier js.
Quelqu'un peut-il m'expliquer un peu le fonctionnement de ce système ?
Merci pour vos réponses

Tu ne nous dis pas ce que tu utilise comme serveur web sur ton µc

Je pars sur ESPAsyncWebServer parce que c’est celui que j’utilise :wink:

Est-ce que tu as bien mis les « routes » pour les différents fichiers problématique ?

Il s’agit des lignes du genre :

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(LittleFS, "/index.html", "text/html", false, processor);
  });

ou alors une route plus générale :

server.serveStatic

Voici le code du fichier index.html

<!DOCTYPE html >
<html>
<head>
    <link rel="stylesheet" href="demos.css" type="text/css" media="screen" />
    
    <script src="/RGraph.common.core.js" ></script>
    <script src="/RGraph.thermometer.js" ></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <!--[if lt IE 9]><script src="../excanvas/excanvas.js"></script><![endif]-->
    
    <title>A basic Thermometer chart</title>
    
    <meta name="robots" content="noindex,nofollow" />
    <meta name="description" content="A basic Thermometer chart" />
     
</head>
<body>
	<div style="text-align: center">

    <h1>Temp&eacute;rature Bassin</h1>
    <canvas id="cvs" width="100" height="500">[No canvas support]</canvas>
    
    <script>
        $(document).ready(function ()
        {
            var thermometer = new RGraph.Thermometer({
                id: 'cvs',
                min: 0,
                max: 50,
<!--                value: %TEMPERATURE%-->
				value: 28 
            }).draw()
        })
    </script>
<h3>Boot %BOOT%</h3>
<h3>Connections %CONNECTIONS%</h3>
<h3>RSSI %RSSI% dBm</h3>  
</body>
</html>

et c'est bien ESPAsyncWebServer qui est utilisé

Les adresses de tes fichiers ne sont pas cohérentes, si effectivement tu as tout mis à la racine de data

c’est href="/demos.css"

et pour le javascript qui fait défaut, c’est lequel ?

Si tu es bien à la racine de data, il ne pourra pas remonter ( .. ) d’un répertoire pour aller dans excanvas

Quel est l’arborescence de data ?

Quel est le code C++ des différents server.on() ?

enfin une remarque :

ne sert à rien si ton ESP32 est dans un réseau local sans être accessible de l’extérieur

Merci pour tes réponses, comme je l'ai dit je suis un newbee, donc il y a pas mal de lacunes....
Le code des serveur on()

void setup(void)
{
  Serial.begin(115200);
  log_println("");
  SPIFFS.begin();
  stationConnectedHandler = WiFi.onStationModeConnected(onStationConnected);
  stationDisconnectedHandler = WiFi.onStationModeDisconnected(onStationDisconnected);
  stationGotIpHandler = WiFi.onStationModeGotIP(onStationGotIP);
  configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.begin(ssid, password);
  log_print("\nConnecting to "); log_println(ssid);
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", "text/html", false, templateProcessor);
  });
  server.on("/RGraph.thermometer.js", HTTP_GET, [](AsyncWebServerRequest * request) {
    log_println("serving RGraph.thermometer.js");
    if (!SPIFFS.exists("/RGraph.thermometer.js")) {
      log_println("RGraph.thermometer.js not found");
    }
    request->send(SPIFFS, "/RGraph.thermometer.js", "text/javascript");
  });
  server.on("/RGraph.common.core.js", HTTP_GET, [](AsyncWebServerRequest * request) {
    log_println("serving RGraph.common.core.js");
  });
  server.onNotFound(handleNotFound);
  server.begin();
  log_println("HTTP server started");
}

et les messages d'erreur dans la console

demos.css:1  Failed to load resource: the server responded with a status of 404 (Not Found)
RGraph.common.core.js:1  Failed to load resource: the server responded with a status of 501 (Not Implemented)
RGraph.thermometer.js:61 Uncaught TypeError: RGraph.CreateUID is not a function
    at new RGraph.Thermometer (RGraph.thermometer.js:61:41)
    at HTMLDocument.<anonymous> ((index):26:31)
    at c (jquery.min.js:4:26036)
    at Object.fireWith [as resolveWith] (jquery.min.js:4:26840)
    at x.ready (jquery.min.js:4:3305)
    at HTMLDocument.q (jquery.min.js:4:717)
demos.css:1  Failed to load resource: the server responded with a status of 404 (Not Found)

Normal : le serveur ne « sert » pas le fichier. Il manque un

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/demos.css", "text/css");
    });

Et là il manque la réponse du serveur :

request->send(SPIFFS, "/RGraph.common.core.js", "text/javascript");

Merci pour ces corrections.
J'affiche bien le thermomètre.
Par contre j'ai toujours l'erreur demos.css qui apparemment ne gène pas le fonctionnement.
il me reste maintenant plus qu'a faire passer la valeur récupérée avec le lm35 au Thermomètre, car pour les test, j'avais mis une valeur fixe ( value : 28) dans le fichier index.html.
J'ai testé pas mal de variable, mais cela plante le thermomètre...

Si tu veux de l’aide, il va falloir être plus précis :wink:

Dans le fichier index.html, si je mets une valeur à 'value', mon thermomètre se dessine bien et m'affiche la valeur que j'ai mis.
Maintenant, il faut que je récupère la valeur que j'ai dans le sketch et que je passe cette valeur dans le fichier index.html.
Voilà la boucle ou je récupère la valeur "temp"

void loop(void){
 analog=analogRead(17);
 float temp= 0.322*analog;
 Serial.print("Temperature:");
 Serial.println(temp);
 delay(5000);
  
}

Ton code ne va faire que la mise à jour de la variable temp. Pour le moment ton interface web n’en a pas connaissance.

Là tu semble parti pour utiliser les « processor placeholders » (je ne sais pas trop comment traduire ça en français)
Au moment du chargement de la page, tu peux demander au serveur de substituer %TEMPERATURE% par … autre chose. Au hasard, la valeur de la température.

String processor(const String& var){
  if(var == "TEMPERATURE"){
    return String(temp);
  }
  return String();
}

Attention, cela ne marche que lors du chargement de la page. Si tu veux une actualisation de l’affichage en temps réel, il faudra faire autrement (mais c’est un peu plus complexe)

J'avais déjà testé cela dans le code, mais il ne récupère pas la valeur "temp", je n'ai pas de message d'erreur, mais une valeur "0.00"
Ce que je ne comprends pas, c'est que ma valeur temp est calculée dans le loop et que la variable %TEMPERATURE% est calculée dans la fonction

Attention, chez toi la fonction doit s’appeler

Mets un

Serial.println(temp); 

dans cette fonction pour vérifier que tu y passes bien.

C'est normal : au moment de servir la page, le serveur web demande à la fonction templateProcessor de transformer, à la volée, les chaines %BLABLA% avec la fonction indiquée dans les paramètres du server.on()

Il doit manquer quelque chose dans le server on

void setup(void){
  Serial.begin(115200);
  log_println("");
  SPIFFS.begin();
  stationConnectedHandler = WiFi.onStationModeConnected(onStationConnected);
  stationDisconnectedHandler = WiFi.onStationModeDisconnected(onStationDisconnected);
  stationGotIpHandler = WiFi.onStationModeGotIP(onStationGotIP);
  configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  WiFi.begin(ssid, password);
  log_print("\nConnecting to "); log_println(ssid);
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", "text/html", false, templateProcessor);
  });
   server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/demos.css", "text/css");
    });
  server.on("/RGraph.thermometer.js", HTTP_GET, [](AsyncWebServerRequest * request) {
    log_println("serving RGraph.thermometer.js");
    if (!SPIFFS.exists("/RGraph.thermometer.js")) {
      log_println("RGraph.thermometer.js not found");
    }
    request->send(SPIFFS, "/RGraph.thermometer.js", "text/javascript");
  });
  server.on("/RGraph.common.core.js", HTTP_GET, [](AsyncWebServerRequest * request) {
    log_println("serving RGraph.common.core.js");
    if (!SPIFFS.exists("/RGraph.common.core.js")) {
      log_println("RGraph.common.core.js not found");
    }
    request->send(SPIFFS, "/RGraph.common.core.js", "text/javascript");
	
  });
  server.onNotFound(handleNotFound);
  server.begin();
  log_println("HTTP server started");
}

car le println ne me renvoie rien

Quelle est l'URL que tu demandes sur ton navigateur ?

Il y a une erreur là déjà :

 server.on("/demos.css", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/demos.css", "text/css");
    });

Je n'ai plus l'erreur demos.css absent :slightly_smiling_face:

je mets simplement l'adresse IP, et si je mets index.html, il ne me le trouve pas...

Je viens de modifier

server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", "text/html", false, templateProcessor);

Par

server.on("/index.html", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(SPIFFS, "/index.html", "text/html", false, templateProcessor);

et là, si je ne mets que l'adresse IP, je n'ai plus rien et si je mets index.html j'ai bien mon thermomètre, mais toujours à 0.00... :grimacing:

Je viens de regarder le moniteur série, quand j'actualise la page, j'ai les messages serving Rgraph.common.core.js et serving Rgraph.thermometer.js

Si tu veux que ça réponde dans les 2 cas mets les deux lignes.