This website uses cookies to ensure you get the best experience on our website.
Make an ESP8266 Water Level Monitor

This Arduino code is for a rain harvesting water tank monitor that measures the distance of the water level in the tank using an ultrasonic sensor. It then calculates the amount of water in the tank and sends the data to ThingSpeak, an IoT platform, via Wi-Fi.

The code begins by including several libraries for Wi-Fi connectivity, OTA updates, and ThingSpeak communication. It then defines the Wi-Fi SSID, password, and ThingSpeak API key for sending data to the platform.

Next, the code defines the pins for the ultrasonic sensor and initializes the Wi-Fi connection and OTA updates. The loop function continuously reads the distance from the ultrasonic sensor and calculates the amount of water in the tank in liters and percentage.

The code then establishes a TCP connection to the ThingSpeak server and sends the distance, liters, and percentage data to the server using an HTTP GET request. Finally, the loop function waits for a specified update period before repeating the process.

Overall, this code allows for remote monitoring of a rain harvesting water tank and provides real-time data on the amount of water stored in the tank. This information can be used to optimize water usage and prevent overflows or shortages.


#include <ESP8266WiFi.h>

#include <ESP8266WebServer.h>

#include <ESP8266mDNS.h>

#include <WiFiUdp.h>

#include <ArduinoOTA.h>

const char* ssid = "xxxxxxxxx";

const char* password = "xxxxxxxxxx";

char host[] = "";

String ApiKey = "xxxxxxxxxxxxxx";

String path = "/update?key=" + ApiKey + "&field1=";

#define ECHOPIN 5                                                 //Pin to receive echo pulse

#define TRIGPIN 4                                                 //Pin to send trigger pulse 

#define PI 3.1415926535898


#define R_POZZO 0.66                                              //raggio pozzo (m)

#define H_POZZO 100.05                                            //Height of tank cm

long distance;

int litres;

float percentage = 0;

//unsigned long updateSensor = 0;

int updatePeriod = 15;

void setup() {


  pinMode(ECHOPIN, INPUT);


  digitalWrite(ECHOPIN, HIGH);

  WiFi.begin(ssid, password);

  // Wait for connection

  while (WiFi.status() != WL_CONNECTED) {




  ArduinoOTA.onStart([]() {

    String type;

    if (ArduinoOTA.getCommand() == U_FLASH) {

      type = "sketch";

    } else { // U_SPIFFS

      type = "filesystem";


    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()

    Serial.println("Start updating " + type);


  ArduinoOTA.onEnd([]() {



  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {

    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));


  ArduinoOTA.onError([](ota_error_t error) {

    Serial.printf("Error[%u]: ", error);

    if (error == OTA_AUTH_ERROR) {

      Serial.println("Auth Failed");

    } else if (error == OTA_BEGIN_ERROR) {

      Serial.println("Begin Failed");

    } else if (error == OTA_CONNECT_ERROR) {

      Serial.println("Connect Failed");

    } else if (error == OTA_RECEIVE_ERROR) {

      Serial.println("Receive Failed");

    } else if (error == OTA_END_ERROR) {

      Serial.println("End Failed");




  Serial.print("Connected to ");


  Serial.print("IP address: ");



  Serial.print("MAC: ");



void loop() {

  //  if (millis() - updateSensor > 180 * 1000UL) {

  //   updateSensor = millis();

  //    delay(50);                                                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.

  //String v = String(distance);                                    //Is this needed at all? Freddie to find out


  digitalWrite(TRIGPIN, LOW);                                     //Set the trigger pin to low for 2uS


  digitalWrite(TRIGPIN, HIGH);                                    //Send a 10uS high to trigger ranging


  digitalWrite(TRIGPIN, LOW);                                     //Send pin low again

  distance = pulseIn(ECHOPIN, HIGH, 26000);                       //Read in times pulse

  distance = distance / 58;


  float distance2 = (H_POZZO - distance) + 20;                           //Height of tank

  Serial.println("   cm");

  litres = floor(SUPERFICE_BASE * distance2 * 10);


  percentage = (litres / 1380.0) * 100.0;


  // make TCP connections

  WiFiClient client;

  const int httpPort = 80;

  if (!client.connect(host, httpPort)) {



  String url = "/update?key=";

  url += ApiKey;

  url += "&field1=";

  url += String(distance);

  url += "&field2=";

  url += String(litres);

  url += "&field3=";

  url += String(percentage);

  url += "\r\n";

  // Request to the server

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +

               "Host: " + host + "\r\n" +

               "Connection: keep-alive\r\n\r\n");

  delay(updatePeriod * 1000);


Android app to display water tank water content level

ESP8266 Rain Harvesting Water Tank Monitor

Leave a Reply

Your email address will not be published. Required fields are marked *

Math Captcha
1 + 8 =