Niveau cuve avec ESP8266 et AJ-SR04M

Bonjour, j'avais posté il y a quelque temps sur ce sujet ... non résolu. J'ai repris le sketch en question (niveau d'eau cuve en mode AP (access point) et branché un capteur à ultrasons étanche de type AJ-SR04M alimenté en 3,3V.
J'ai bien les mesures espérées dans le moniteur série (%, litres et distance) mais l'affichage sur le smartphone est sur une seule ligne avec uniquement le pourcentage de remplissage.
En regardant la partie "HTML" du sketch les balises

me semblent bien placées et en recopiant cette partie dans un browser l'affichage est correct.
Je suis donc dans le brouillard !

Une idée ? (le site original est dans l'entête du sketch)

// version AP mode NodeMCU et AJ-SR04M
// site origine : https://blog.etechpath.com/water-tank-level-automation-using-esp8266-and-hc-sr04-ultrasonic-sensor/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <HCSR04.h>

const char* ssid     = "WaterLevel"; //Access point ssid
const char* password = "12341234";   //Access point password

float lit = 0.0;       // litres 
float pourcent = 0.0;  // pourcentage 
float distcm = 0;      // distance 

// Rectangular Tank dimentions in cm
float longueurcm = 200;  // longueur
float largeurcm  = 200;  // largeur
float hauteurcm  = 130;  // Hauteur, du capteur au fond de citerne

/*
HCSR04(trigger, echo, temperature, distance)

trigger     - trigger pin*
echo        - echo pin*
temperature - ambient temperature, in C
distance    - maximun measuring distance, in cm

*most boards has 10-12kOhm pullup-up resistor on GPIO2/D4 & GPIO0/D3
 ESP8266 fails to BOOT/FLASH if D3 or D4 is LOW, use with with caution!
*/

HCSR04 ultrasonicSensor(D6, D5, 20, 300);
AsyncWebServer server(80);
unsigned long previousMillis = 0;
const long interval = 1000;  // intervalle de mesure 

const char index_html[] PROGMEM = R"rawliteral(

<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; Color:DodgerBlue; }
    h3 { font-size: 1.5rem; Color:Tomato; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .temp-labels{
      font-size: 1.5rem;
      vertical-align:middle;
      padding-bottom: 10px;
    }
  </style>
</head>
<body>
  <h2>Niveau citerne</h2>        
  
  <p>
    <span id="permap">%PERMAP%</span>
    <sup class="units">%</sup> 
  </p>
   <p>
   <span id="litre">%LITRE%</span>  
    <sup class="units">Litre</sup> 
  </p>
   <p>
    <span id="distance">%DISTANCE%</span>
    <sup class="units">Cm</sup>
  </p>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("permap").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/permap", true);
  xhttp.send();
}, 1000 ) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("litre").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/litre", true);
  xhttp.send();
}, 1000 ) ;
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("distance").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/distance", true);
  xhttp.send();
}, 1000 ) ;
</script>
</html>)rawliteral";

// Replaces placeholders with sensor values
String processor(const String& var){
 
  if(var == "DISTANCE"){
    return String(distcm);
  }
  else if(var == "LITRE"){
    return String(lit);
  }
  else if(var == "PERMAP"){
    return String(pourcent);
  }
  return String();
}

void setup(){
  Serial.begin(115200);  
  ultrasonicSensor.begin(); //set trigger as output & echo pin as input
  Serial.print("Setting AP (Access Point)…");
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  Serial.println(WiFi.localIP());

  // Route for root
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  server.on("/permap", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(pourcent).c_str());
  });
  server.on("/litre", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(lit).c_str());
  });
  server.on("/distance", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(distcm).c_str());
  });
  server.begin();
} 

void loop()
{  
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) 
  {
    previousMillis = currentMillis;
     float newdistance = ultrasonicSensor.getMedianFilterDistance(); //pass 3 measurements through median filter, better result on moving obstacles
    if (newdistance != HCSR04_OUT_OF_RANGE)
    {
      Serial.print("sensor raw value:");
      Serial.println(newdistance);
      distcm = hauteurcm - newdistance;
      float v = distcm * longueurcm * largeurcm ; // volume
      lit = v / 1000;
      pourcent = map(distcm, 0, hauteurcm, 0, 100);
      Serial.println(pourcent);
      Serial.println(lit);
      Serial.println(distcm);     
    }
    else 
    {
      Serial.println(F("out of range"));
    }     
  }
}

avec quelle URL?

le code HTML semble être prévu pour utiliser AJAX mais côté ESP32 vous semblez utiliser la fonction processor de la bibliothèque qui remplace à la volée dans le HTML le code avec balises

faut faire l'un ou l'autre, pas les 2

l'URL est celle proposé par le smartphone (192.168.4.1).
l'affichage est comme ci dessous. Pour le code, je me suis contenté de modifier celui indiqué sur le site à l'origine du projet : Water Tank Level Automation using ESP8266 and HC-SR04 Ultrasonic Sensor. – Blog eTechPath car je ne suis pas un spécialiste du sujet (loin de là !). Sur ce site il est simplement question de smartphone et d'affichage dans le browser ...

Le problème est ici : le caractère % que tu veux afficher perturbe le mécanisme de la fonction processor

Il faut soit le doubler ( %% ) soit, mieux encore, utiliser l'entité HTML &#37;

Je ne suis pas du tout à l'aise avec ajax mais j'ai déjà vu ça quand même. Ensuite je suppose qu'il y a moyen de faire plus propre...

processor() servait à avoir l'affichage à jour à l'affichage de la page (ou rafraîchissement par F5) et le javascript servait à la mise à jour régulière (par ex. toutes les secondes) des seules valeurs pour éviter un rechargement complet de la page.

Encore un fois, sans y comprendre grand chose à AJAX, j'ai l'intuition que ça fait un peu bricolo.

Oui, j'ai déjà eu ce problème avec ESPAsyncWebServer.
On peut aussi redéfinir TEMPLATE_PLACEHOLDER pour utiliser un caractère à sa convenance à la place de % :
#define TEMPLATE_PLACEHOLDER '$'

1 Like

mais ça se rafraîchit tout seul toutes les secondes, on pourrait juste faire un truc comme cela (non testé tapé ici)

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <HCSR04.h>

const char* ssid     = "WaterLevel"; //Access point ssid
const char* password = "12341234";   //Access point password

// Déclarations globales initialisées à zéro
float volume    = 0.0;     // volume en litres
float pourcent  = 0.0;     // pourcentage
float distance  = 0.0;     // distance en cm

// dimensions de la cuve en cm
float longueur = 200;  // longueur
float largeur  = 200;  // largeur
float hauteur  = 130;  // Hauteur, du capteur au fond de citerne
HCSR04 ultrasonicSensor(D6, D5, 20, 300);
AsyncWebServer server(80);

unsigned long previousMillis = 0;
const unsigned long intervalle = 1000;  // intervallele de mesure

const char index_html[] PROGMEM = R"rawliteral(<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Niveau de la citerne</title>
  <style>
    html { font-family: Arial; display: inline-block; margin: 0 auto; text-align: center; }
    h2 { font-size: 3.0rem; color: DodgerBlue; }
    h3 { font-size: 1.5rem; color: Tomato; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .temp-labels { font-size: 1.5rem; vertical-align: middle; padding-bottom: 10px; }
  </style>
</head>

<body>
  <h2>Niveau de la citerne</h2>
  <p><span id="permap">--</span><sup class="units">%</sup></p>
  <p><span id="litre">--</span><sup class="units">Litre</sup></p>
  <p><span id="distance">--</span><sup class="units">Cm</sup></p>
</body>

<script>
function updateValues() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var data = JSON.parse(this.responseText);
      document.getElementById("permap").innerHTML = data.permap;
      document.getElementById("litre").innerHTML = data.litre;
      document.getElementById("distance").innerHTML = data.distance;
    }
  };
  xhttp.open("GET", "/values", true);
  xhttp.send();
}

setInterval(updateValues, 1000);
</script>

</html>

)rawliteral";

void setup() {
  Serial.begin(115200);
  ultrasonicSensor.begin(); //set trigger as output & echo pin as input
  Serial.print("Setting AP (Access Point)…");
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  Serial.println(WiFi.localIP());

  // Route for root
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
  
  server.on("/values", HTTP_GET, [](AsyncWebServerRequest * request) {
    // Create a buffer for JSON response
    const size_t bufferSize = 256; // devrait suffire
    char responseBuffer[bufferSize];
    snprintf(responseBuffer, bufferSize, "{\"distance\": %.2f, \"pourcentage\": %.2f, \"litres\": %.2f}", distance, pourcent, volume);
    request->send(200, "application/json", responseBuffer);
  });

  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervalle) {
    previousMillis = currentMillis;
    float newdistance = ultrasonicSensor.getMedianFilterDistance(); //pass 3 measurements through median filter, better result on moving obstacles
    if (newdistance != HCSR04_OUT_OF_RANGE) {
      Serial.print("sensor raw value:");  Serial.println(newdistance);
      distance = hauteur - newdistance;
      float v = distance * longueur * largeur ; // volume
      volume = v / 1000.0;
      pourcent = map(distance, 0, hauteur, 0, 100);
  }
}

toutes les secondes, le javascript setInterval(updateValues, 1000); appelle la fonction updateValues qui déclenche une requête GET qui retourne un JSON qui contient les 3 valeurs à afficher. Le Javascript extrait les valeurs et remplace dans le DOM le contenu des éléments identifiés (permap, litre et distance) qui avaient été déclarés comme texte "vide" (les --) lors du premier chargement.

  <p><span id="permap">--</span><sup class="units">%</sup></p>
  <p><span id="litre">--</span><sup class="units">Litre</sup></p>
  <p><span id="distance">--</span><sup class="units">Cm</sup></p>

Merci pour toutes vos réponses,

En utilisant la solution de Professeur Mephisto (%%) l'affichage est correct sur le smartphone :grinning: (3 lignes différentes, reflet du moniteur série).
Par contre les mesures sont incohérentes : en mettant le capteur à 40 cm d'une surface plane j'ai 90 cm affichés sur le smartphone. Par ailleurs, en rapprochant le capteur US la distance augmente (mais le volume augmente alors qu'il devrait diminuer puisque le volume est calculé sur la distance entre surface de l'eau et capteur)
??? Je n'ai pas encore essayé la solution de J.M.L.

Je n’ai pas modifié les formules

Ceci semble calculer le volume vide au dessus de la cuve en cm3

Pour moi la formule de calcul du volume est correcte : à la ligne 103 (ci-dessous) la formule retranche la distance mesurée à la hauteur totale (distcm = hauteur - newdistance). Celà n'explique pas la mesure étrange de distance affichée sur le smartphone comparée avec la distance réelle mesurée à la règle :grinning:

j'ai essayé ton sketch et l'affichage est celui ci dessous. A noter dans ce cas que j'ai l'affichage réel de la distance en mode "raw" dans le moniteur série (que je n'ai pas avec le sketch précédent et qui confirme que le capteur à ultrasons n'est pas en cause).

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <HCSR04.h>

const char* ssid     = "WaterLevel"; //Access point ssid
const char* password = "12341234";   //Access point password

// Déclarations globales initialisées à zéro
float lit    = 0.0;     // volume en litres
float pourcent  = 0.0;     // pourcentage
float distcm  = 0.0;     // distance en cm

// dimensions de la cuve en cm
float longueur = 200;  // longueur
float largeur  = 200;  // largeur
float hauteur  = 130;  // Hauteur, du capteur au fond de citerne
HCSR04 ultrasonicSensor(D6, D5, 20, 300);
AsyncWebServer server(80);

unsigned long previousMillis = 0;
const unsigned long intervalle = 1000;  // intervalle de mesure

const char index_html[] PROGMEM = R"rawliteral(<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Niveau de la citerne</title>
  <style>
    html { font-family: Arial; display: inline-block; margin: 0 auto; text-align: center; }
    h2 { font-size: 3.0rem; color: DodgerBlue; }
    h3 { font-size: 1.5rem; color: Tomato; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .temp-labels { font-size: 1.5rem; vertical-align: middle; padding-bottom: 10px; }
  </style>
</head>

<body>
  <h2>Niveau de la citerne</h2>
  <p><span id="permap">--</span><sup class="units">%</sup></p>
  <p><span id="litre">--</span><sup class="units">Litre</sup></p>
  <p><span id="distance">--</span><sup class="units">Cm</sup></p>
</body>

<script>
function updateValues() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var data = JSON.parse(this.responseText);
      document.getElementById("permap").innerHTML = data.permap;
      document.getElementById("litre").innerHTML = data.litre;
      document.getElementById("distance").innerHTML = data.distance;
    }
  };
  xhttp.open("GET", "/values", true);
  xhttp.send();
}

setInterval(updateValues, 1000);
</script>

</html>

)rawliteral";

void setup() {
  Serial.begin(115200);
  ultrasonicSensor.begin(); //set trigger as output & echo pin as input
  Serial.print("Setting AP (Access Point)…");
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  Serial.println(WiFi.localIP());

  // Route for root
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
  
  server.on("/values", HTTP_GET, [](AsyncWebServerRequest * request) {
    // Create a buffer for JSON response
    const size_t bufferSize = 256; // devrait suffire
    char responseBuffer[bufferSize];
    snprintf(responseBuffer, bufferSize, "{\"distance\": %.2f, \"pourcentage\": %.2f, \"litres\": %.2f}", distcm, pourcent, lit);
    request->send(200, "application/json", responseBuffer);
  });

  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervalle) {
    previousMillis = currentMillis;
    float newdistance = ultrasonicSensor.getMedianFilterDistance(); //pass 3 measurements through median filter, better result on moving obstacles
    if (newdistance != HCSR04_OUT_OF_RANGE) {
      Serial.print("sensor raw value:"); 
      Serial.println(newdistance);
      distcm = hauteur - newdistance;
      float v = distcm * longueur * largeur ; // volume
      lit = v / 1000.0;
      pourcent = map(distcm, 0, hauteur, 0, 100);
   Serial.println(pourcent);
      Serial.println(lit);
      Serial.println(distcm);     
    }
    else 
    {
      Serial.println(F("out of range"));
    }     
  }
}


L'affichage de la distance sur le smartphone n'est pas celui mesuré.

Pour le souci d'affichage, J'ai tapé cela trop vite, les étiquettes du JSON ne correspondent pas au décodage en javascript

voici les champs du JSON :

et voici le décodage :

distance est OK mais dans le snprintf() il faut mettre permap au lieu de pourcentage et litre (sans le s)

    snprintf(responseBuffer, bufferSize, "{\"distance\": %.2f, \"permap\": %.2f, \"litre\": %.2f}", distcm, pourcent, lit);

(le style pour les unités laisse à désirer, il faudra affiner le CSS).


Je n'avais pas vu la soustraction - ça devrait être OK si votre fonction getMedianFilterDistance() vous donne bien une mesure en cm.

J'imagine que votre capteur n'est pas au niveau 0 du trop plein, la formule devrait donc comprendre cette distance à la surface (surtout que la plupart des capteurs ne savent pas mesurer une distance de 0)

Après les modifs indiquées, l'affichage est maintenant correct (en tout cas merci pour les infos : çà dépasse largement mes compétences et j'avoue ne pas tout comprendre :crazy_face:).
Les données en % et litres semblent cohérents mais la distance affichée sur le smartphone est bizarre : elle n'a rien avoir avec la distance capteur/surface et augmente quand on rapproche le capteur alors qu'elle devrait diminuer. (la valeur "raw" dans le moniteur série est correcte et correspond à la distance capteur/surface). J'ai bien compris que le capteur ne peut pas mesurer moins de 20 cm mais quelque chose ne va pas quelque part ...

postez votre dernier code

Voici le code. Question : la distance pourrait elle correspondre en fait à la hauteur d'eau ? (du fond à la surface). Ce serait un peu bizarre comme raisonnement ...

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <HCSR04.h>

const char* ssid     = "WaterLevel"; //Access point ssid
const char* password = "12341234";   //Access point password

// Déclarations globales initialisées à zéro
float lit    = 0.0;     // volume en litres
float pourcent  = 0.0;     // pourcentage
float distcm  = 0.0;     // distance en cm

// dimensions de la cuve en cm
float longueur = 200;  // longueur
float largeur  = 200;  // largeur
float hauteur  = 130;  // Hauteur, du capteur au fond de citerne
HCSR04 ultrasonicSensor(D6, D5, 20, 300);
AsyncWebServer server(80);

unsigned long previousMillis = 0;
const unsigned long intervalle = 1000;  // intervalle de mesure

const char index_html[] PROGMEM = R"rawliteral(<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Niveau de la citerne</title>
  <style>
    html { font-family: Arial; display: inline-block; margin: 0 auto; text-align: center; }
    h2 { font-size: 3.0rem; color: DodgerBlue; }
    h3 { font-size: 1.5rem; color: Tomato; }
    p { font-size: 3.0rem; }
    .units { font-size: 1.2rem; }
    .temp-labels { font-size: 1.5rem; vertical-align: middle; padding-bottom: 10px; }
  </style>
</head>

<body>
  <h2>Niveau de la citerne</h2>
  <p><span id="permap">--</span><sup class="units">%</sup></p>
  <p><span id="litre">--</span><sup class="units">Litre</sup></p>
  <p><span id="distance">--</span><sup class="units">Cm</sup></p>
</body>

<script>
function updateValues() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var data = JSON.parse(this.responseText);
      
      document.getElementById("permap").innerHTML = data.permap;
      document.getElementById("litre").innerHTML = data.litre;
      document.getElementById("distance").innerHTML = data.distance;
          
    }
  };
  xhttp.open("GET", "/values", true);
  xhttp.send();
}

setInterval(updateValues, 1000);
</script>

</html>

)rawliteral";

void setup() {
  Serial.begin(115200);
  ultrasonicSensor.begin(); //set trigger as output & echo pin as input
  Serial.print("Setting AP (Access Point)…");
  WiFi.softAP(ssid, password);
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);
  Serial.println(WiFi.localIP());

  // Route for root
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });
  
  server.on("/values", HTTP_GET, [](AsyncWebServerRequest * request) {
    // Create a buffer for JSON response
    const size_t bufferSize = 256; // devrait suffire
    char responseBuffer[bufferSize];
     snprintf(responseBuffer, bufferSize, "{\"distance\": %.2f, \"permap\": %.2f, \"litre\": %.2f}", distcm, pourcent, lit);
  
    request->send(200, "application/json", responseBuffer);
  });

  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= intervalle) {
    previousMillis = currentMillis;
    float newdistance = ultrasonicSensor.getMedianFilterDistance(); //pass 3 measurements through median filter, better result on moving obstacles
    if (newdistance != HCSR04_OUT_OF_RANGE) {
      Serial.print("sensor raw value:"); 
      Serial.println(newdistance);
      distcm = hauteur - newdistance;
      float v = distcm * longueur * largeur ; // volume
      lit = v / 1000.0;
      pourcent = map(distcm, 0, hauteur, 0, 100);
      Serial.println(pourcent);
      Serial.println(lit);
      Serial.println(distcm);     
    }
    else 
    {
      Serial.println(F("out of range"));
    }     
  }
}

Défaut de débutant.
Les problèmes se règlent un par un, quand tout est Ok, on peut assembler.
La mise au point est alors beaucoup plus facile.

  1. On s'assure que la mesure est bonne, sans s'occuper du WiFi
  2. On s'assure que l'on peut transmettre sans erreur une quantité par le WiFi.
  3. on assemble

cf mon dessin

si vous considérez que Dcapteur est 0 la formule pour la hauteur d'eau est

Heau = Hcuve - distance

et dans votre code vous faites

      distcm = hauteur - newdistance;

donc oui, c'est la hauteur d'eau à peu près que vous mesurez, ce qui est raisonnable si vous voulez calculer ensuite le volume d'eau dans la cuve comme vous le faites avec

      float v = distcm * longueur * largeur ; // volume

donc non ce n'est pas bizarre

OK, merci pour l'info. C'est le mot "distance" qui m'a induit en erreur. Hauteur d'eau serait plus parlant. Après, c'est une question de philosophie : hauteur d'eau ou distance eau/capteur ? That is the question :grinning:

Il me reste à faire une petite alimentation solaire secourue par batterie et installer le tout dans le jardin ...
Un grand merci, j'y serais pas arrivé seul. Le mode AP me permet d'éviter de passer par un cloud genre blynk ou autre et les exemples sur le net ne sont pas nombreux (en AP).

disons qu'au début newdistance c'est bien ce que voit le capteur

mais ensuite vous faites cela

et donc distcm devient (quasiment - il manque la distance entre le capteur et la surface quand c'est plein) la hauteur d'eau)

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