Water Meter with an Arduino

This is a step-by-step guide to build a water meter.
A water meter lets you know how much water is being used at a point. It helps nudge the user to be conscious of their water usage.



Things you will need

Additional materials:

  • 2 x FTA (Female threaded adapter) - to attach flow sensor to pipe
  • PVC pipe of 1/2 inch diameter
  • Spanner - to tighten parts
  • Teflon tape - to prevent leakage through pipe joints
  • Electrical wire and sockets for extension


Questions you need to ask

Get data. Examples:

  • What is the difference between water usage and water wastage ?
  • What are the relevant units of measurement?
  • What is the maximum flow rate of the tap? At what point of opening the tap does this happen?
  • What is the ideal flow rate of the tap to perform simple actions like washing hands, utensils, groceries, etc.?

What are the things you need to learn about the user? Examples:

  • Who is the user?
  • How much water is being used?
  • How often is it being used?
  • How much is being wasted? How?
  • Is there any time when the user opens the tap gradually/not fully?
  • Does the user think they are wasting water?
  • Does the user recognize this as a problem?
  • What is stopping the user from recognizing the problem and taking action?

What are the things you need to think about to convince the user that wasting water is a problem? Examples:

  • Why is it a problem?
  • What would influence the user’s behaviour? How do they want the problem to be solved/notified?
  • Can there be a punishment mechanism whenever there is excessive water flow or a reward mechanism whenever there is optimum water flow?

This will help you decide what output device to use, for example-

  • Buzzer with an annoying beeeep or a gentle music (like a water filter), or ,
  • Multicolour LED that blinks red when there’s a lot of water flow/usage, yellow when there’s very little, and green when it’s optimal, or,
  • LCD screen that displays how much water is being/has been used, or,
  • RFID/ biometric system to tag users and capture data of how much water is being used by each individual user, etc. The list is endless.


Steps to follow

  1. Take the Arduino UNO, disconnect it from power source and from your computer.
  2. Connect the 3 male-to-male jumper wires to the Arduino UNO and to the flow sensor following this schematic:
    Data (yellow wire) → D2
    Positive (red wire) → 5V
    Negative/Ground (black wire) → GND
  3. Double check connections before proceeding.
  4. Connect one end of the USB cable to Arduino and other to Computer/laptop.
  5. Open Arduino IDE on computer/laptop.
  6. Download, Copy, Paste code from here to the Arduino IDE:
/* Prototype Name : Water Meter
   Input Sensor   : Water Flow Sensor
   Output Device  : LCD, Multicolor LED, Buzzer
   Libraries Used : LiquidCrystalPCF584, FastLED

#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27); // change to 0X3F if necessary
#include <FastLED.h> //
#define DATA_PIN 9// Digital pin number for LED (NeoPixel)
#define NUM_LEDS 3
#define buzzer 8
byte sensorInterrupt = 0;  // 0 = interrupt for digital pin 2
byte sensorPin       = 2;  //Digital Pin 2

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;

volatile byte pulseCount;

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

unsigned long oldTime;

void setup()
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  leds[0] = CRGB::Black;

  pinMode(buzzer, OUTPUT);

  lcd.begin(16, 2);
  // Initialize a serial connection for reporting values to the host
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);

  lcd.home(); lcd.clear();
  lcd.print("Hi:Water Meter");
  lcd.setCursor(0, 1);
  lcd.print("Conserve Water");


   Main program loop
void loop()

  if ((millis() - oldTime) > 1000)   // Only process counters once per second
    leds[0] = CRGB::Black;
    digitalWrite(buzzer, LOW);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;

    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;

    unsigned int frac;

    // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print(".");             // Print the decimal point
    // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    frac = (flowRate - int(flowRate)) * 10;
    Serial.print(frac, DEC) ;      // Print the fractional part of the variable
    // Print the number of litres flowed in this second
    Serial.print("  Current Liquid Flowing: ");             // Output separator

    // Print the cumulative total of litres flowed since starting
    Serial.print("  Output Liquid Quantity: ");             // Output separator
    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;

    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    // LCD , LED and buzzer
    lcd.setCursor(0, 0);
    lcd.setCursor(0, 1);

    if (flowMilliLitres > 2 && flowMilliLitres <= 49) {
      leds[0] = CRGB::Green;
    else if (flowMilliLitres >= 50) {
      digitalWrite(buzzer, HIGH);
//      delay(2000);
      leds[0] = CRGB::Red;
  Insterrupt Service Routine
void pulseCounter()
  // Increment the pulse counter
  1. Then Check for Tools→ Board→ Port in the IDE.
  2. Compile and Upload the code.
  3. Test by blowing air into the flow sensor in the direction of the arrow. Test if value increases in the serial monitor/ LCD screen.
  4. Disconnect the flow sensor from the Solution Box.
  5. Connect the flow sensor to the tap as shown. Use FTA/Threaded Collars to fix the sensor to the pipes. Tighten the FTA using a spanner and use the teflon tape to prevent any leakages that might happen.
  6. Re-Connect the 3 jumper wires to the Arduino UNO. Extend if needed.
  7. Connect the flow sensor to the 3 pin wire connector.
  8. Construct a simple enclosure for your solution. You could use an old plastic container, or some cardboard material.
  9. Hang the enclosure on the wall at a suitable distance from the tap and flow sensor. To check if the distance is suitable,
  • make sure that water doesn’t splash till that distance
  • the flow sensor wire/power adapter wire should not be too taut.
  1. Connect the flow sensor to the enclosure.
  2. Power it up!


  • Locally: Once you install the solution near a tap, observe how the user interacts with the tap and the water meter. Talk to them about the solution and learn what they think of it.
    • Has their perspective on water consumption changed? Are they consciously reducing their water consumption?
    • Is there any way to collect data to prove that their water consumption has reduced, as a result of reinforcing the behaviour of reducing water flow rate?
  • Globally: Upvote this solution if you have tried this out, and inspire 5 of your friends to take similar action. Continue collecting data; real victory is when your family, school mates, community members realise that in addition to saving water as a resource, they are also saving money in their water bills!