Arduino Projects

GSM based Water Level Monitoring and Control using Arduino, Sim900A, and Ultrasonic Sensor

GSM Based Water Level Monitoring:

GSM based Water Level Monitoring and Control using Arduino, Sim900A, and Ultrasonic Sensor- In today’s article, you will learn how to make GSM based Water Level Monitoring and control system using Arduino Nano, GSM SIM900A module, and HC-SR04 Ultrasonic Sensor.

By the way, I have written many articles related to the water level monitoring and control system, in which I have used different technologies to monitor water levels and control water pumps. For example,




Wireless Water level monitoring using Long-range LoRa transceiver modules, with the help of this project water level inside a tank can be monitored within a range of 5 Kilometers.

IoT based water level monitoring and control system using ESP32 WiFi + Bluetooth module, Waterproof ultrasonic Sensor, and the new Blynk V2.0. With the help of this water level monitoring system, you can monitor the water level inside a tank from anywhere in the world.

I also made a water level monitoring system using a Pressure Sensor and displayed the water level information on LEDs.

If you’re interested in exploring technologies beyond GSM, such as LoRa and IoT platforms, I highly recommend read my previous articles on the Water Level Monitoring and Control Systems.



Amazon Links:

Arduino Nano

HC-SR04 Ultrasonic Sensor

GSM SIM900A

GSM GPRS SIM800l

Other Tools and Components:

Top Arduino Sensors:

Super Starter kit for Beginners

Digital Oscilloscopes

Variable Supply

Digital Multimeter

Soldering iron kits

PCB small portable drill machines

*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!



Anyway, let’s get back to our project.

GSM based Water Level Monitoring

For the demonstration purposes, I am going to monitor the water level inside a bucket which you can think of as the water tank and you can think of this 110/220Vac Bulb as the water Pump.

GSM based Water Level Monitoring

The Ultrasonic sensor is right on top of the water tank. Everything is in place and it looks good; so let’s go ahead and power up the entire system.

As usual, I am using my designed Arduino and LoRa based development board, because I specially designed it for projects like these. I am not using a separate power supply for the GSM SIM900A module, because my board has a 5V and 3A power supply which is more than enough to power up the Arduino, GSM, and relays.



If you don’t want to make such a development board then you can make a dedicated 5V and 3A power supply.

When the 110/220Vac supply is connected never touch the relay contacts as it can be dangerous. So, as far as possible, wear protective gloves and perform such high voltage experiments in the presence of a companion or someone having basic knowledge of the electrical systems.

When the water level in the water tank drops below a certain level, the Arduino starts sending alert messages with the help of GSM module.

GSM based Water Level Monitoring

In the programming, I’ve utilized a timer to ensure that alert messages are generated every 2 minutes. Having an alert message every 2 minutes could indeed be quite annoying. However, it’s important to note that this time duration is adjustable, and I will explain how to modify it later in this article.




We have two options, we can turn ON the water pump automatically or we can do it manually. In my case, I don’t want the water pump to turn ON automatically. Anyway, let’s write a message to turn ON the water pump.

GSM based Water Level Monitoring

abc123 is a password to add a little bit of security so that nobody else can control the water pump, you can use any combination of letters, characters, and numbers. Then the word relay, and command on. The % signs are used to separate these parameters. I have already explained this in my GSM based Home automation project. Anyway, the message is ready and let’s send it to control the water pump.

GSM based Water Level Monitoring

You can see the bulb just turned ON which represents a water pump. Now, it will stay ON until the water tank is filled. I filled the Bucket and then the Light “Water Pump” automatically turned OFF.

I have also added another feature that is; you can check the water level inside a water tank at anytime, all you need is to write a message which consists of a password and the word level.

GSM based Water Level Monitoring

Anyway, before I send this message, first let’s remove some water. Now, let’s send the message and check the level.

GSM based Water Level Monitoring

This is pretty amazing; with this feature you will never run out of water because you can check the water level at anytime and you can turn ON the water pump whenever you want, you don’t need to wait for the water tank to get completely empty.



GSM based Water Level Monitoring, Circuit:

GSM based Water Level Monitoring

Connect the 5V TXD and RXD pins of the GSM SIM900A module to the Arduino digital pins D9 and D10. Connect the 5V and GND pins of the GSM module to the 5V and 3A power supply Vin and GND. The power supply 5V and GND are connected to the Arduino Vin and GND pins.

Connect the VCC and GND pins of the HC-SR04 Ultrasonic Sensor to the Arduino Vin and GND pins. Connect the Trigger and Echo pins of the Ultrasonic Sensor to the Arduino D2 and D3 pins respectively.

Connect the VCC and GND wires of the relay module to the 5V and GND. Connect the relay input pin to the Arduino digital pin D4. The Vin and Gnd wires should be connected to a 5V and 3A power supply.

GSM based Water Level Monitoring

You can follow this circuit diagram if you want to make your own 5V and 3A power supply. Now, let’s go ahead and take a look at the programming.



GSM based Water Level Monitoring, Programming:

#include <SoftwareSerial.h>
SoftwareSerial SIM900(9, 10); // TXpin=9 RXpin=10

#define trigPin 2
#define echoPin 3
#define relay 4

int distance;
String passcode="abc123"; 
String incoming = "";
String textForSMS;

// for the timer
int minutes = 0; 
int seconds = 0; 
long int total_seconds = 0; 
int secflag = 0; 
int timer_started_flag = 0; 
 
 
// Tracks the time since last event fired
unsigned long previousMillis=0;
unsigned long int previoussecs = 0; 
unsigned long int currentsecs = 0; 
 unsigned long currentMillis = 0;
  int interval= 1 ; // updated every 1 second
int tsecs = 0; 

// flags

boolean Zero_Level_Flag = false;

void setup() {
  //initialize Serial Monitor
  Serial.begin(9600);
 pinMode(trigPin, OUTPUT);
 pinMode(relay, OUTPUT);
 pinMode(echoPin, INPUT);
SIM900.begin(9600); // original 19200
 randomSeed(analogRead(0));

  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(1000);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); 
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(1000);
     SIM900.println("AT+CMGD=1,4"); // delete all SMS
   delay(5000);
  Serial.println("Ready...");
}

void loop() {

       currentMillis = millis();
   currentsecs = currentMillis / 1000; 
    if ((unsigned long)(currentsecs - previoussecs) >= interval) {
      total_seconds = total_seconds + 1;
      previoussecs = currentsecs;

      if ( total_seconds >= 59 )
      {
        minutes = minutes + 1;
        total_seconds = 0;
        
      }
      if ( minutes >= 2 )
      {
        total_seconds = 0;
        minutes =0;
        Zero_Level_Flag = false;
      }
      
//      Serial.print("Minutes:");
//      Serial.println(minutes);
//      Serial.println();
//      Serial.print("Seconds:");
//      Serial.println(total_seconds);     
     
    }

  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
 // Trigger the sensor by setting the trigPin high for 10 microseconds:
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Read the echoPin. pulseIn() returns the duration (length of the pulse) in microseconds:
int  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance:
//  distance = duration*0.034/2;
  
distance = (duration/2) / 29.1;
Serial.print("Distance: ");
Serial.println(distance);
  // Print the distance on the Serial Monitor (Ctrl+Shift+M):

  /*
   * 44 is the distance of the water level from the ultrasonic sensor
   * when the tank is full.
   * 64 is the low limit of the water level from the ultrasonic sensor
   */
int waterLevelPer = map(distance,44,64, 100, 0);

if(waterLevelPer <= 0)
{
  waterLevelPer=0;
  
  }
  
if (waterLevelPer >= 100)
{
  waterLevelPer = 100;
   }
    
if (waterLevelPer >= 90)
{
  digitalWrite(relay,LOW);
   }
    
Serial.print("Percentage: ");
Serial.println(waterLevelPer);
 
  if ((waterLevelPer <= 20) && (Zero_Level_Flag == false))
{
  Zero_Level_Flag = true;
textForSMS =  "level: "; 
textForSMS = textForSMS + waterLevelPer; 
textForSMS = textForSMS + "%";
textForSMS = textForSMS + "\n"; 
sendSMS(textForSMS);
//Serial.println(textForSMS);
//Serial.println("message sent."); 
textForSMS = ""; 
delay(200);
  }
  
  
if(SIM900.available() >0)
  {

  incoming=SIM900.readString(); 
  //Serial.println(incoming);


String fulldata = getValue(incoming, '%', 0); 
String password = getValue(incoming, '%', 1); //contains password
String level= getValue(incoming, '%', 2); //contains motor type dc motor or servo motor
String relaystate= getValue(incoming, '%', 3); //contains motor type dc motor or servo motor

//Serial.print("value 1: ");
//Serial.println(password);
//Serial.print("value 2: ");
//Serial.println(level);
//Serial.print("value 3: ");
//Serial.println(relaystate);

if((password==passcode)&&(level=="level"))
{
  textForSMS =  "level: "; 
textForSMS = textForSMS + waterLevelPer; 
textForSMS = textForSMS + "%";
textForSMS = textForSMS + "\n"; 
 
sendSMS(textForSMS);
//Serial.println(textForSMS);
//Serial.println("message sent."); 
textForSMS = ""; 
delay(200);
}
else if((password==passcode)&&(level=="relay")&&(relaystate=="on"))
{
 digitalWrite(relay,HIGH);
 delay(100);
}
else if((password==passcode)&&(level=="relay")&&(relaystate=="off"))
{
 digitalWrite(relay,LOW);
 delay(100);
}
}  
}

void sendSMS(String message)
{
  SIM900.print("AT+CMGF=1\r");                     // AT command to send SMS message
  delay(1000);
 SIM900.println("AT + CMGS = \"+923348912230\"");  // recipient's mobile number, in international format
 
  delay(1000);
  SIM900.println(message);                         // message to send
  delay(1000);
  SIM900.println((char)26);                        // End AT command with a ^Z, ASCII code 26
  delay(1000); 
  SIM900.println();
  delay(100);                                     // give module time to send SMS
 
}

String getValue(String data, char separator, int index)
{
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data.length() - 1;
 
    for (int i = 0; i <= maxIndex && found <= index; i++) {
        if (data.charAt(i) == separator || i == maxIndex) {
            found++;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }
    }
    return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}



About the code:

I started off by adding the SoftwareSerial.h header file. Using the SoftwareSerial we can define multiple serial ports. You know, in Arduino Uno and Arduino Nano we have only one serial port that is available on pins 0 and 1. As I want to use the Arduino’s default serial port for the debugging purposes; so that’s why I defined another serial port for the GSM SIM900A module.

SoftwareSerial SIM900(9, 10);

Next, I defined pins for the Trigger, Echo, and Relay.

#define trigPin 2

#define echoPin 3

#define relay 4

I also defined some variables for storing the water level value, password, incoming message, and alert message.

int distance;

String passcode="abc123";

String incoming = "";

String textForSMS;

I also defined some variables for the timer.

int distance;

String passcode="abc123";

String incoming = "";

String textForSMS;

Code inside the setup() function is exactly the same as explained in my previous GSM based home automation project. So, let’s go to the loop() function.

Using the millis() function, we calculate the seconds and minutes.

currentMillis = millis();

   currentsecs = currentMillis / 1000;

    if ((unsigned long)(currentsecs - previoussecs) >= interval) {

      total_seconds = total_seconds + 1;

      previoussecs = currentsecs;

      if ( total_seconds >= 59 )

      {

        minutes = minutes + 1;

        total_seconds = 0;

      }

      if ( minutes >= 2 )

      {

        total_seconds = 0;

        minutes =0;

        Zero_Level_Flag = false;

      }

So, when the minutes are greater than or equal to 2,  we set the Zero_Level_Flag to false which signals the Arduino to send an alert message. When the alert message is sent the Zero_Level_flag is again set to true, and this whole process starts again.

All the other instructions are from my GSM based home automation project, all these instructions are used to split the string message and store the corresponding values in variables. Then we use these different parameters for requesting the water level and for controlling the water pump. I highly recommend you guys should watch my video on the GSM based home automation project. Anyway, that’s all for now.




Watch Video Tutorial:

Engr Fahad

My name is Shahzada Fahad and I am an Electrical Engineer. I have been doing Job in UAE as a site engineer in an Electrical Construction Company. Currently, I am running my own YouTube channel "Electronic Clinic", and managing this Website. My Hobbies are * Watching Movies * Music * Martial Arts * Photography * Travelling * Make Sketches and so on...

Leave a Reply

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

Back to top button