IoT Based Water Level Monitoring System

In this post we are going to build a water level monitoring system which can log water level data of an overhead or an underground tank to an IoT cloud called Thingspeak where we can monitor the current level of water and consumption overtime. In a previous water level monitoring system project we used GSM module (SMS) and ultrasonic sensor to render water level of a tank, here we are using IoT and the same ultrasonic technology to measure water level precisely.

We will see:

  • Why should we use IoT for monitoring water level?
  • How to measure water level using ultrasonic?
  • Setting up your Thingspeak account.
  • Circuit diagram.
  • Program code for IoT based water level monitor.
  • Prototype and demonstration.

Why should we use IoT for monitoring water level?

Due to exploitation of water resources and speeding of climate change due to human activities, water becoming a luxury these days and keeping tab on water consumption is a necessity now. We know that water conservation starts from a family and a person in a family can easily track their water consumption either by observing day to day activities or checking water level of their overhead tank every day.

But for a municipal government who is concerned about the areas they governing cannot track each and every family’s water consumption by physically sending a person every day. Instead they can check level of municipal supply tanks where the level of water is direct reflection of water consumed by the people in the area. Again we have to deploy several people to take readings of tens of municipal overhead tanks several times a day.

It is a human nature to get inert sometimes or many times and one could manipulate the readings and could push the idea of water consumption of an area in wrong direction and this could also delay the water supply because the actual water level could vary significantly from the manipulated readings which could lead to unexpected shutdown of water supply.    

By installing IoT based water level monitoring systems in all the important municipal water tanks the local government can know the level of water in real time and they can fill the tank on time and also can understand the consumption of water in the area. The collected data can be sent to higher level governments where they can draw national level conclusions on water consumption.

IoT based water level monitoring system can also be installed on individual houses / apartments so that one can check water level of their tank in real time from their own comfort and also track their consumption overtime. 

Now you know why we are sending tank’s water level data over internet.

How to measure water level using ultrasonic sensor, and why?

Ultrasonic Sensor
Ultrasonic Sensor

In the previous water level indicator project we used an ultrasonic distance sensor to measure water level, here we are also going to use the same non-contact method because of its convenience and accuracy in reading water level.

When we decide to make any water level indicator project the first thing that comes to our mind is the electrodes that are we are going immerse in the water. Traditionally several metallic electrode are immersed in the water at different levels and some voltage is passed. The problem with this method in a long run is that, no matter how the electrodes were refined before installing, it will get corroded due to electrochemical reaction due to passing of electric current through water which reacts with some minerals present in the water and it is a bad idea to consume such contaminated water.

The resolution of the reading is limited to how many electrodes immersed in the water. The ultrasonic based measurement overcomes all the disadvantages that arise due to utilizing traditional electrode method. The accuracy of readings is +/- 3mm and can be used to tanks that are up to 4 meter deep.

Water level indicator using ultrasonic sensor
Water level indicator using ultrasonic sensor

Measuring water level is same as measuring distance of solid surfaces, the ultrasonic transducer outputs a train of ultrasonic bursts at 40 KHz which will hit the water surface and reflect back to the sensor. The time taken between sent and received ultrasonic waves are calculated by a microcontroller such as Arduino. The measured distance is converted in to percentage.

The tank has two heights the actual water holding capacity and the total height of the tank. In any overhead tank there will be overflow and inlet tube, the point just below the overflow tube is the end of water holding capacity. You need to measure these two heights and enter it in the given program code in centimetre.

Setting up Thingspeak account to receive water level of a tank:

  • You need to sign up for Thingspeak, if you haven’t done yet.
  • Click on “New channel” and do the following.
  • Go to channel settings and change the name as “water level” and tick field 1 and name it as “percentage”. Note down your channel ID.
  • Scroll down and click save.
  • Now click on API keys tab and take note of your “write API key” which must be inserted in the given program code.

Now your Thingspeak account is ready to receive water level of a tank.

Circuit diagram:

Ultrasonic Sensor with NodeMCU
Ultrasonic Sensor with NodeMCU

The circuit is hilariously simple we just have two components: HC-SR04 ultrasonic sensor and ESP8266 NodeMCU. The Trigger pin of ultrasonic sensor is connected to D0 and echo pin is connected to D1. The ultrasonic sensor requires 5V supply which can be obtained from VU pin (for LOLin ).

NodeMCU with Ultrasonic sensor
NodeMCU with Ultrasonic sensor
Measuring Water Level Using Ultrasonic
Measuring Water Level Using Ultrasonic

Download and install Thingspeak library to IDE: Click here

Note: You should have installed ESP8266 board package to Arduino IDE before you compile the code. 

Program code:

#include "ThingSpeak.h"
#include <ESP8266WiFi.h>

//----------- Enter you Wi-Fi Details---------//
char ssid[] = "XXXXXX"; //SSID
char pass[] = "YYYYYY"; // Password
//-------------------------------------------//

// --------------- Tank details --------------//
const int total_height = 30; // Tank height in CM
const int hold_height = 25;// Water hold height in CM
//-------------------------------------------//

//----- minutes -----//
int minute = 1; // Data update in min.
//------------------//

//----------- Channel Details -------------//
unsigned long Channel_ID = 12345; // Channel ID
const int Field_number = 1; // To which field to write data (don't change)
const char * WriteAPIKey = "ACBCDEFGHI"; // Your write API Key
// ----------------------------------------//

const int trigger = 16;
const int echo = 5;
long Time;
int x;
int i;
int distanceCM;
int resultCM;
int tnk_lvl = 0;
int sensr_to_wtr = 0;
WiFiClient  client;


void setup()
{
  Serial.begin(115200);
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  WiFi.mode(WIFI_STA);
  ThingSpeak.begin(client);
  sensr_to_wtr = total_height - hold_height;
}
void loop()
{
  internet();
  for (i = 0; i < minute; i++)
  {
    Serial.println("System Standby....");
    Serial.print(i);
    Serial.println(" Minutes elapsed.");
    delay(20000);
    delay(20000);
    delay(20000);
  }
  measure();
  Serial.print("Tank Level:");
  Serial.print(tnk_lvl);
  Serial.println("%");
  upload();
}
void upload()
{
  internet();
  x = ThingSpeak.writeField(Channel_ID, Field_number, tnk_lvl, WriteAPIKey);
  if (x == 200)Serial.println("Data Updated.");
  if (x != 200)
  {
    Serial.println("Data upload failed, retrying....");
    delay(15000);
    upload();
  }
}

void measure()
{
  delay(100);
  digitalWrite(trigger, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigger, LOW);
  Time = pulseIn(echo, HIGH);
  distanceCM = Time * 0.034;
  resultCM = distanceCM / 2;

  tnk_lvl = map(resultCM, sensr_to_wtr, total_height, 100, 0);
  if (tnk_lvl > 100) tnk_lvl = 100;
  if (tnk_lvl < 0) tnk_lvl = 0;
}

void internet()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    while (WiFi.status() != WL_CONNECTED)
    {
      WiFi.begin(ssid, pass);
      Serial.print(".");
      delay(5000);
    }
    Serial.println("\nConnected.");
  }
}

You need to do the following changes to the code:

  • Insert you Wi-Fi credentials here:

//----------- Enter you Wi-Fi Details---------//
char ssid[] = "XXXXXX"; //SSID
char pass[] = "YYYYYY"; // Password
//-------------------------------------------//
  • You need to enter water tank heights here:

// --------------- Tank details --------------//
const int total_height = 30; // Tank height in CM
const int hold_height = 25;// Water hold height in CM
//-------------------------------------------//

You have to measure your tank’s total height and water holding capacity height and enter it here in centimeter. 

  • You need to enter how frequent your tank level needs to be updated to Thingspeak:

//----- minutes -----//
int minute = 1; // Data update in min.
//------------------//

Note: Minimum is 1 min. If you want to send data every hour enter 60, if you want to send data once every day set 1440 (24hrs = 1440 min) and so on.

  • You need to enter your channel details here:

//----------- Channel Details -------------//
unsigned long Channel_ID = 12345; // Your Channel ID
const int Field_number = 1; // To which field to write data (don't change)
const char * WriteAPIKey = "ACBCDEFGHI"; // Your write API Key
// ----------------------------------------//

How to Upload Code to NodeMCU:

  • Connect your NodeMCU using micro USB cable to your PC.
  • Press and hold flash button and press the reset button once and now you leave the flash button.
  • Select the NodeMCU v1.0 as board.
  • Select 115200 as baud rate and select the correct COM port.
  • Press upload button, it may take 2 min to compile the code and another one minute to upload to NodeMCU.

On successful program uploaded to NodeMCU, you will see this:  

Uploading to ESP8266
Uploading to ESP8266

Or you will see this if you installed ESP32 package to Arduino IDE before:

Code uploaded to ESP8266
Code uploaded to ESP8266

Demonstration:

For demonstration purpose I am going to use a mini water tank that measures 30 cm in (total) height and since it doesn’t have overflow tube, I have marked water holding height as 25 cm as shown below:

Measuring Water Level Using Ultrasonic
Measuring Water Level Using Ultrasonic
IoT based water level monitoring system
IoT based water level monitoring system

After entering the necessary detail in the code I uploaded the code to NodeMCU. I have set the code to update data every 1 minute.

Data on Thingspeak:

Water Level data on Thingspeak
Water Level data on Thingspeak

During the test I drained some water and added some water at times, that’s why water level on graph moves up and down.

On Serial Monitor:

You can also open serial monitor with baud rate of 115200 to see what’s going on with NodeMCU.

Also see: GSM Based Water Level Monitoring System

If you have any question regarding this project feel free to ask us in the comment, you will get a guaranteed reply from us.