Project Description

All About Water Systems: Ultrasonic/WaterFlow/Rain Sensor

About This Project:

Sometimes when I take a bath, the water stops. I checked that the water tank is empty and I have to call the water engineer to fix the water. I wish I could’ve known the water problem earlier. So now, with Cayenne, I have an idea to make My Water System connected to my mobile device.

My current water system has 2 water tanks. The water from the underground flows into blue tanks using Grundfos pump, it’s filtered with sand and then goes through the orange tanks. Orange tanks distribute the water using a small pump to home.

Sometimes the water from the ground is not flowing into the blue tank, so I need the water flow sensor in order to know whether the Grundfos Pump is flowing the water or not. If the water flow sensors detects slower than usual flow, it means either I need to tweak the ‘pipe button’ or fix the underground pipe.

For the orange tank, sometimes I have to know if water is flowing into orange tanks or not. If the water flows slower than usual (or even stops), it means it’s time to clean up the water filter.

Hardware Components:

What’s Connected:

  • Arduino Uno WIFI Developer Editions
  • 2 Pcs Ultrasonic HC-SR04
  • 2 Pcs Water Flow Sensors
  • 2 Pcs Arduino Relay
  • 1 Contactor Schneider LC1D09M7 220V for Grundfos Pump
  • 1 MY2 AC 220V/240V – 5A DPDT Electromagnetic Power Control Relay OMRON
  • 1 Rain Sensors (This is Bonus because in the Future I want to develop the system if Rain comes I want to all windows closed automatically)

Arduino Pin

  • D2 water flow sensor blue tank
  • D3 water flow sensor orange tank
  • D4 ultrasonic blue tank – echo
  • D5 ultrasonic blue tank – trigger
  • D6 ultrasonic orange tank – echo
  • D7 ultrasonic orange tank – trigger
  • D8 relay blue tank
  • D9 relay orange tank
  • A0 rain sensor


Note: WARNING! You have to put the water flow sensor to pin D1 and D2 ONLY, because the water flow sensor needs to use interrupts and for Arduino UNO it’s only available on pin D1 and D2. (


Triggers & Alerts:

  • If orange tank’s below 75%, turn on blue switch (Grundfos Pump)
  • If orange tank’s above 95%, turn off blue switch
  • If blue tank’s above 95%, turn off blue switch
  • If orange tank’s below 50%, send email alert (there is some problem present in the water systems)


  • Turn on blue switch (Grundfos Pump) at 5 am – 6 am (the lowest electrical use in my home)

Dashboard Screenshots:

Mobile Dashboard:





Water Flow for Blue Tanks in L/minute:

Rain Sensor in %:

  • 0% means not raining at all
  • 100% means full flood, please prepare your boat because the flood has already reach the top of the roof T_T

Photos of the Project:

(Take some pictures of your project living in the wild!)


  • Water Systems Hardware

  • Arduino

Ultrasonic Placement:

  • For blue tank

  • For orange tank

Whole System with Tanks:

  • Water Systems


//Remove This Someday when UnoWifiDev can connect to Cayenne (Can’t Wait That Time Comes ^^)
//#include <UnoWiFiDevEd.h>
//#define CAYENNE_DEBUG // Uncomment to show debug messages
//#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include <CayenneEthernetW5500.h>
// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = “XXXXXXXX”;
// Water Flow –> Only Works ON Pin 2 and Pin 3 for Uno, check
int flowPin = 2; //This is the input pin on the Arduino, Only Can be setup in Port 2 and 3
int flowPin2 = 3;
double flowRate; //This is the value we intend to calculate.
double flowRate2;
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
volatile int count2;
unsigned int getcount; //Getcount from count for flowRate
unsigned int getcount2;
// Rain Sensor
float rain_level;
int rain_percentage;
int rain_bottom = 1022;
int rain_top = 2;
int rain_distance = rain_bottom – rain_top;
const int rainPin=A0;
#define VIRTUAL_RAIN V10
// Ultrasonic
const int echoPin = 4; // Echo Pin
const int trigPin = 5; // Trigger Pin
float water_level;
float water_percentage;
int water_bottom = 42;
int water_top = 32;
int water_distance = water_bottom – water_top;
const int echoPin2 = 6; // Echo Pin
const int trigPin2 = 7; // Trigger Pin
float water_level2;
float water_percentage2;
int water_bottom2 = 75;
int water_top2 = 19;
int water_distance2 = water_bottom2- water_top2;
void setup()
// Water Flow
pinMode(flowPin, INPUT);
attachInterrupt(digitalPinToInterrupt(flowPin), Flow, RISING);
pinMode(flowPin2, INPUT);
attachInterrupt(digitalPinToInterrupt(flowPin2), Flow2, RISING);
// Ultrasonic
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
// Rain
pinMode(rainPin, INPUT);
void loop()
// Water Flow

// Ultrasonic
// Rain
rain_level = analogRead(rainPin);
rain_percentage = 100 * ((rain_distance – rain_level)/rain_distance);
// Water Flow
void Flow()
count++; //Every time this function is called, increment “count” by 1
void Flow2()
count2++; //Every time this function is called, increment “count” by 1
static unsigned long lastSecond;
void getWaterFlow()
if (micros() – lastSecond >= 1000000L)
lastSecond += 1000000;
noInterrupts(); //Disable the interrupts on the Arduino
getcount = count;
getcount2 = count2;
count = 0; // Reset the counter so we start counting from 0 again
count2 = 0;
interrupts(); //Enables interrupts on the Arduino
//Start the math for Blue Tank
flowRate = (getcount * 2.25); //Take counted pulses in the last second and multiply by 2.25mL
flowRate = flowRate * 60; //Convert seconds to minutes, giving you mL / Minute
flowRate = flowRate / 1000; //Convert mL to Liters, giving you Liters / Minute

//Start the math for Orange Tank
flowRate2 = (getcount2 * 2.25); //Take counted pulses in the last second and multiply by 2.25mL
flowRate2 = flowRate2 * 60; //Convert seconds to minutes, giving you mL / Minute
flowRate2 = flowRate2 / 1000; //Convert mL to Liters, giving you Liters / Minute

//Serial.println(flowRate); //Print the variable flowRate to Serial
Cayenne.virtualWrite(VIRTUAL_PIN_WATERFLOW_1, flowRate);

//Serial.println(flowRate); //Print the variable flowRate to Serial
Cayenne.virtualWrite(VIRTUAL_PIN_WATERFLOW_2, flowRate2);
// Ultrasonic
float duration;
long HR_dist = 0; // Calculated Distance
unsigned long previousMillisUltraSonic = 0;
void getDistance(){
unsigned long currentMillisUltraSonic = millis();

// Check sensor data every 250 milliseconds
if (currentMillisUltraSonic – previousMillisUltraSonic >= 5000) {

digitalWrite(trigPin, LOW);
digitalWrite(trigPin, HIGH);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
duration = duration/58.2;
Cayenne.virtualWrite(VIRTUAL_PIN_ULTRASONIC_1, duration);

water_percentage = (100 * (water_top + water_distance – duration)) / water_distance;
Cayenne.virtualWrite(VIRTUAL_PIN_ULTRASONIC_PERCENT_1, water_percentage);

digitalWrite(trigPin2, LOW);
digitalWrite(trigPin2, HIGH);
digitalWrite(trigPin2, LOW);
duration = pulseIn(echoPin2, HIGH);
duration = duration/58.2;
Cayenne.virtualWrite(VIRTUAL_PIN_ULTRASONIC_2, duration);
water_percentage2 = (100 * (water_top2 + water_distance2 – duration)) / water_distance2;
Cayenne.virtualWrite(VIRTUAL_PIN_ULTRASONIC_PERCENT_2, water_percentage2);

previousMillisUltraSonic = currentMillisUltraSonic;
// Rain
Cayenne.virtualWrite(VIRTUAL_RAIN, rain_percentage);


Author: Benny Estes


For more information:


Tags:  201801, Cayenne, Ethernet, LC1D09M7 220V, Relay, Ultrasonic sensor, water