Introduction
Water is one of the most essential resources, yet its management often remains inefficient. To address this, we introduce an IoT-Based Water Tank Monitoring System Using ESP8266 and Solar Power. This system provides real-time monitoring of water levels and flow rates, helping optimize water usage. Powered by solar energy, it’s cost-effective, environmentally friendly, and suitable for various applications such as homes, agriculture, and remote areas. With this system, you can improve water management and contribute to sustainable resource usage.
Watch it on YouTube.
Project Overview
The IoT-Based Water Tank Monitoring System is designed to:
- Monitor the water level in a tank using an ultrasonic sensor.
- Measure the water flow rate using a flow sensor.
- Display real-time data on a web interface hosted by the ESP8266 microcontroller.
- Operate on solar power, making it suitable for remote locations.
Components Used
- FireBeetle ESP8266 IoT Microcontroller
- Product Link
- A low-power microcontroller with Wi-Fi capability, ideal for IoT projects.
- Alternatively you can use any other ESP8266 microcontroller like NodeMCU, D1 Mini, or any other ESP8266-based boards.
- You can also use an ESP32 (just update the pins used in the code).
- Solar Power Manager 5V
- Product Link
- Manages solar power input and provides stable 5V output for connected devices.
- Monocrystalline Solar Panel (5V 1A)
- Product Link
- Efficient solar panel to power the system.
- Water Flow Sensor YF-S201
- Product Link
- Measures the flow rate of water in liters per minute.
- Waterproof Ultrasonic Distance Sensor JSN-SR04T
- Product Link
- Measures the distance between the sensor and the water surface.
- 3.7V Lithium-ion Battery
- Provides backup power for the system, ensuring uninterrupted operation.
- Weatherproof Box
- Protects the components from environmental elements.
- Jumper Wires
- For electrical connections between components.
Hardware Setup
Wiring Diagram
Below is the wiring diagram for the project. Follow it to ensure accurate connections between the components.

Connecting the Sensors
- Ultrasonic Sensor (JSN-SR04T):
- Connect the Trig pin to
D5
. - Connect the Echo pin to
D6
.
- Connect the Trig pin to
- Flow Sensor (YF-S201):
- Connect the signal pin to
D1
.
- Connect the signal pin to
Power Management
- Use the Solar Power Manager to regulate the power from the solar panel.
- Connect the output of the power manager to the ESP8266.
- Connect the 3.7V Lithium-ion battery to the Solar Power Manager for backup power.
Housing the Components
- Place all components inside a weatherproof box to ensure durability.
Mounting the Sensors
- Position the ultrasonic sensor above the water tank.
- Install the flow sensor on the inlet pipeline for accurate water flow measurement.
Software Setup
Arduino Code
The provided code, written for the Arduino IDE, uses libraries for Wi-Fi and web server functionality. Key features include:
- Ultrasonic Sensor: Measures water level and converts it to a percentage based on distance.
- Flow Sensor: Calculates water flow rate in liters per minute using pulse counting.
- Web Interface: Displays real-time water level and flow rate on a local webpage via an ESP8266-hosted asynchronous web server.
// IoT-Based Water Tank Monitoring Using ESP8266 and Solar Power
// By ArduinoYard.com
#ifdef ESP32
#include "WiFi.h"
#include <SPIFFS.h>
#include <ESPmDNS.h>
#else
#include "ESP8266WiFi.h"
#include <FS.h>
#include <ESP8266mDNS.h>
#endif
#include "ESPAsyncWebServer.h"
#include <movingAvg.h>
movingAvg distanceAvg(10); // Take average of 10 readings for ultrasonic sensor
movingAvg frAvg(10); // Take average of 10 readings for flow sensor
// Pin assignments
const int trigPin = D5; // Ultrasonic Trigger pin
const int echoPin = D6; // Ultrasonic Echo pin
const int flowSensorPin = D1; // Flow sensor signal pin
// Sensor Variables:
float CalibrationFactor = 7.5; //This is the calibration factor for my flow rate sensor you can adjust it for better results
// Tank Variables for Ultrasonic sensor
int minHeight = 25; // It is the distance from ultrasonic sensor to the water when tank is full
int maxHeight = 115; // It is the distance from ultrasonic sensor to the bottom of the tank or min water level
// WiFi network credentials
const char* ssid = "YourWifiSSID"; // Add your Wi-Fi SSID here
const char* password = "YourWifiPassword"; // Add your Wi-Fi password here
// Create AsyncWeb object on port 80
AsyncWebServer server(80);
// Variables for flow rate sensor
volatile int pulseCount = 0;
float flowRate = 0.0;
unsigned long oldTime = 0, readingInterval = millis();
int percentage;
float dAvg;
// If we use any placeholder in html code then this function is useful
String processor(const String& var) {
return String();
}
// Checks if motion was detected, sets LED HIGH and starts a timer
ICACHE_RAM_ATTR void pulseCounter() {
pulseCount++; // Increment pulse count whenever a pulse is detected
}
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
if (!SPIFFS.begin()) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
pinMode(D4, OUTPUT);
digitalWrite(D4, LOW);
distanceAvg.begin();
frAvg.begin();
WiFi.begin(ssid, password);
Serial.print("Connecting..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.println("connected");
digitalWrite(D4, HIGH);
// Initialize mDNS
if (MDNS.begin("watertank")) { // Replace with your preferred hostname
Serial.println("mDNS responder started");
Serial.println("You can access the server at http://watertank.local");
} else {
Serial.println("Error setting up mDNS responder!");
}
// Set up ultrasonic sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
// Set up flow sensor pin
pinMode(flowSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowSensorPin), pulseCounter, FALLING); // Interrupt for flow sensor
// Initialize flow rate calculation
oldTime = millis();
//Calling the files from SPIFFS memory of esp32
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, "/index.html", String(), false, processor);
});
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, "/style.css", "text/css");
});
// Serve the JavaScript file
server.on("/script.js", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, "/script.js", "application/javascript");
});
// sending the required data on paths /distance and /frate
server.on("/distance", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/plain", String(percentage));
});
server.on("/frate", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(200, "text/plain", String( frAvg.reading(flowRate)));
});
// Start server
server.begin();
}
void loop() {
#ifdef ESP8266
MDNS.update(); // Add this to keep mDNS running smoothly
#endif
if (WiFi.status() != WL_CONNECTED) //If WiFi network stopped working
{
WiFi.reconnect(); //trying reconnecting the same previous network
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.println("connected");
}
if ( millis() - readingInterval > 1000) //reading the sensor values with 1 second interval
{
readingInterval = millis();
distance();
flowrate();
}
}
// Function to measure distance using ultrasonic sensor
String distance() {
long duration;
float distanceCm;
// Send a 10us pulse to trigger the sensor
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Measure the time for the echo to return
duration = pulseIn(echoPin, HIGH);
// Convert time to distance in cm
distanceCm = duration * 0.034 / 2;
if (distanceCm >= minHeight && distanceCm <= maxHeight)
{
percentage = map(distanceAvg.reading(distanceCm), minHeight, maxHeight, 0, 100);
if (percentage < 0 ) percentage = 0;
else if (percentage > 100 ) percentage = 100;
percentage = 100 - percentage;
}
Serial.println(percentage);
return String(percentage);
}
// Function to calculate flow rate using flow rate sensor
String flowrate() {
unsigned long currentTime = millis();
unsigned long timeInterval = currentTime - oldTime;
// Calculate flow rate based on pulse count
if (timeInterval > 1000) { // Calculate every 1 second
flowRate = (pulseCount / CalibrationFactor); // Formula for YF-S201 flow sensor (adjust based on your sensor)
oldTime = currentTime; // Reset time interval
pulseCount = 0; // Reset pulse count for next interval
}
Serial.println(flowRate);
return String(frAvg.reading(flowRate));
}
You can download the code and webpage design files using the button below:
Changes to Make in Code
Before uploading the provided code to your ESP8266, you’ll need to make a few adjustments to personalize it for your setup. Below are the parameters you need to modify in the code:
- Wi-Fi SSID and Password
To connect your ESP8266 to your local Wi-Fi network, replace the placeholder text with your network’s SSID and password. - Tank Minimum and Maximum Height
These values represent the height in centimeters from the ultrasonic sensor to the water level. Set the minimum height (the distance when the tank is full) and the maximum height (the distance from the ultrasonic sensor to the bottom of the tank). - Calibration Factor for Flow Rate Sensor
The flow rate sensor might need calibration to accurately measure water flow. Adjust theCalibrationFactor
variable based on your specific sensor to fine-tune the flow rate calculations. - Local Webpage Hostname
By default, the ESP8266 will use the hostname “watertank” for the local network. If you don’t want to change it, you can leave the code as is and access the server viahttp://watertank.local
on your local network.
After making the necessary changes (or keeping the default values), save the code and proceed with the next steps.
Library Setup and File Upload
Adding Libraries:
To ensure the code works seamlessly, you’ll need to install the following libraries in your Arduino IDE:
- ESPAsyncWebServer
- This library enables the ESP8266 to host an asynchronous web server for serving the water tank monitoring data.
- MovingAvg
- This library helps smooth out sensor readings by applying a moving average algorithm.
Steps to Install Libraries:
- Open Arduino IDE.
- Navigate to Sketch > Include Library > Manage Libraries.
- Search for ESPAsyncWebServer and MovingAvg in the Library Manager.
- Click the Install button for both libraries.
Alternatively, download them as ZIP files from their GitHub repositories:
Once downloaded, add them using Sketch > Include Library > Add .ZIP Library.
Adding the SPIFFS Filesystem Uploader:
To host the web interface files, we use the SPIFFS filesystem. Here’s how to set it up:
- Download the Project Files:
- Get the provided ZIP file containing the Arduino code and the
data
folder.
- Get the provided ZIP file containing the Arduino code and the
- Unzip the Files:
- Extract the ZIP file into a folder.
- You’ll see the Arduino sketch and a
data
folder with the web interface files (index.html
,style.css
,script.js
).
- Upload Files to SPIFFS:
- Open the Arduino sketch in the folder using Arduino IDE.
- Ensure the
data
folder is in the same directory as the sketch. - Go to Tools > ESP8266 Sketch Data Upload and upload the files to the ESP8266.

Note:
If you haven’t installed the SPIFFS uploader tool yet, check out this guide for installation steps: SPIFFS Filesystem Uploader in Arduino IDE.
Web Interface Design
The web interface consists of three files:
- index.html:
- Displays the water level and flow rate visually.
- style.css:
- Provides a clean and modern design for the interface.
- script.js:
- Handles fetching and updating data from the ESP8266 server.
The interface updates every second to provide real-time monitoring. It features:
- A graphical representation of the water level in the tank.
- A flow rate display to show water supply in liters per minute.
How It Works
- Ultrasonic Sensor:
- The sensor emits ultrasonic pulses and measures the time it takes for the echo to return.
- The distance is calculated and converted into a percentage based on predefined tank dimensions.
- Flow Sensor:
- The sensor generates pulses proportional to the water flow rate.
- The ESP8266 calculates the flow rate using a calibration factor.
- ESP8266 Web Server:
- Hosts the web interface.
- Sends real-time water level and flow rate data to the interface.
- Solar Power System:
- Powers the entire setup using the Solar Power Manager, solar panel, and Lithium-ion battery.
Demonstration
To view the real-time water tank data, follow these steps after setting up the hardware and uploading the code:
- Upload the Arduino Code:
- Ensure the correct board (e.g., FireBeetle ESP8266, NodeMCU, or D1 Mini) and port are selected in the Arduino IDE.
- Compile and upload the Arduino sketch to the ESP8266.
- Connect to Wi-Fi:
- Once powered, the ESP8266 will connect to the Wi-Fi network configured in the code.
- Access the Web Interface:
- Open a web browser on your phone or computer connected to the same network.
- Enter the hostname you set in the code, e.g.,
watertank.local
, or the IP address assigned to the ESP8266 by you. - The interface will display real-time data about your water tank, including water level and flow rate.
On mobile phone:

On Desktop:

Challenges and Solutions
- Wi-Fi Connectivity Issues:
- If the ESP8266 struggles to connect to Wi-Fi, ensure it has a stable power supply.
- Reconnect automatically using the provided
WiFi.reconnect()
code.
- Power Management:
- Ensure the solar panel and battery can provide sufficient power for the ESP8266 and sensors.
- Accuracy of Sensors:
- Calibrate the flow sensor for accurate readings.
- Average ultrasonic sensor readings to minimize fluctuations.
Conclusion
This IoT-Based Water Tank Monitoring System Using ESP8266 and Solar Power is an efficient, solar-powered solution for real-time monitoring of water levels and flow rates. The detailed design ensures reliability and accuracy, making it ideal for various applications. By following this guide, you can build and customize your own system to meet specific needs.
Applications:
- Residential water tank monitoring.
- Agricultural irrigation systems.
- Remote water supply management.
Feel free to share your feedback or ask questions in the comments section. Happy building!
Detailed YouTube Video
Here is the detailed YouTube video for this project: