Depth Gauge

Hi, I have built a depth gauge for a water tank and all is nearly working well, but i have one problem.
sometimes the value comes back wrong (either my cable is too long or it just cant hear the echo) and it comes up with a figure like 13mtrs or 8mtrs it does not do this often, maybe once every 2 days but it messes up my thingspeak chart.
Im just not sure the best way to stop it. i am guessing i need to say to not print a figure if it is over 4mtrs (the tank is only 4m deep) but im not sure where to process this command.

below is my code? any ideas before i break what was working lol?

/*
 *  Distance measurement with HC-SR04 ultrasonic sensor and Wemos D1 Mini, a web-based server
 *  by author Irwan
 *  published on www.likecircuit.com
 *  version 1.0
 */
 
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

const char* ssid = "xxxx";
const char* password = "xxxxx";

ESP8266WebServer server(80);

// defines pins numbers trigger and echo
const int trigPin = 14;  //Digital port D5
const int echoPin = 12;  //Digital port D6

// defines variables
long duration;
float distance;
float depth;

const int led = LED_BUILTIN;

void setup(void){
  pinMode(led, OUTPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", webserver);
  server.onNotFound(handleNotFound);
  server.begin();
  Serial.println("HTTP server started");
}

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

void distanceData(){
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculating the distance
  distance= (duration*0.034)/2;
  depth= 494-distance;
}

void webserver() {
  digitalWrite(led, !digitalRead(led));
  distanceData();
  String content = "<html> <head> <meta http-equiv='refresh' content='1'> </head><body>";
  content += "<center><h2>The depth is: ";
  content += depth;
  content += " cm </h2></center> </body></html>";
  server.send(200, "text/html", content);
}

void handleNotFound(){
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

The distanceData() function sets the depth variable then the webserver() function sends data to the server.

So, if you test the value of depth at the start of the webserver() function and only execute the code in the function if the depth is in a reasonable range you will not see unreasonable values.

In order that you are aware of problems it would be better if you sent a different message when the depth is out of range.

I note that you are using Strings (capital S) in the program which can lead to memory fragmentation. It would be better to use C style strings (lowercase s)

thank you,

I thought stopping the web server would create undesirable results. so probably best i put a message instead. (begins head scratching as im less of a programmer and more a cut and paste lol) the string issue is interesting. the program is one published online. I will lowercase all the strings in it :)

I will lowercase all the strings in it

Then it won't compile. There are fundamental differences between Strings and strings

Apologies, but when I wrote

if you test the value of depth at the start of the webserver() function and only execute the code in the function if the depth is in a reasonable range you will not see unreasonable values.

I should have said, if you test the value of depth in the webserver() function after the call to distanceData() and only execute the code in the function if the depth is in a reasonable range you will not see unreasonable values.

Another tip when working with sensors it to take multiple (3-5) readings and calculate the average of those readings. This will produce a more robust result from the sensor(s) since any bad readings will be leveled out by the good readings.

Most people find that a median filter is the best way to remove strong outlier measurements.

A 1D filter is easy to implement, using a simple sort function.