Water Flow Meter

Water Meter

Category: Water
Communication: None, WiFi
Components: Internal
Created By: Gouri Lekshminarayanan
Difficulty Level: Beginner, Expert
Input Sensor: https://www.notion.so/Flow-sensor-a7ec2b2c4dd747809ec04167853adac9
Microcontroller: Arduino UNO
Output Device: https://www.notion.so/Buzzer-b6ba1f7e0632499fbaf9c779ee09ee3d, https://www.notion.so/LCD-screen-a1d6725d214448e08e68217ba38d3236
Prototyped by: Sairam Problem Solver, Gautam Prakash
Status: Complete

This is a water meter that lets you know how much water is being used at a point.

It helps nudge the user to be conscious of their water usage.

Discover

Refer to the first booklet Discover in the Solve Ninja Techno Kit for information on the components available with the Solve Ninja Techno Kit.

Things you will need

Solve Ninja Techno Kit which will contain:

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

Water%20Meter%203b96a53414c647148dc445b5ecb83bf1/WaterMeter.jpg


Investigate

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.

Refer to the second booklet Investigate in the Solve Ninja Techno Kit for information on which Input sensors and Output devices to use.


Solve

Refer to the third booklet Solve in the Solve Ninja Techno Kit for information on making connections and Arduino IDE.

Steps to follow

  1. Take the Solution Box from the Solve Ninja Techno Kit.
  2. Connect the 3 pin wire connector to the PCB in the port named “Flow Sensor”.
  3. Connect the flow sensor to the 3 pin wire connector.
  4. Connect one end of the USB cable to Arduino and other to Computer/laptop.
  5. Plug in one end of the power adapter to the DC jack, and the other end to a power socket.

You will need a 9V 1A power adapter for using this kit. It will not work with the USB cable alone.

  1. Switch on the Solution Box.

  2. Open Arduino IDE on computer/laptop.

  3. Download, Copy, Paste code from here to the Arduino IDE:

  • Click here for code - Without WiFi (Beginner Level)

    /* 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
    CRGB leds[NUM_LEDS];
    #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;
      FastLED.show();
    
      pinMode(buzzer, OUTPUT);
    
      lcd.begin(16, 2);
      // Initialize a serial connection for reporting values to the host
      Serial.begin(115200);
      pinMode(sensorPin, INPUT);
      digitalWrite(sensorPin, HIGH);
    
      pulseCount        = 0;
      flowRate          = 0.0;
      flowMilliLitres   = 0;
      totalMilliLitres  = 0;
      oldTime           = 0;
    
      attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    
      lcd.setBacklight(255);
      lcd.home(); lcd.clear();
      lcd.print("Hi:Water Meter");
      lcd.setCursor(0, 1);
      lcd.print("Conserve Water");
      delay(6000);
    
    }
    
    /**
       Main program loop
    */
    void loop()
    {
    
      if ((millis() - oldTime) > 1000)   // Only process counters once per second
      {
        leds[0] = CRGB::Black;
        FastLED.show();
        digitalWrite(buzzer, LOW);
        detachInterrupt(sensorInterrupt);
        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
        Serial.print("L/min");
        // 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.clear();
        lcd.setCursor(0, 0);
        lcd.print("Curr.Use(mL):");
        lcd.print(flowMilliLitres);
        lcd.setCursor(0, 1);
        lcd.print("Total(mL):");
        lcd.print(totalMilliLitres);
    
        if (flowMilliLitres > 2 && flowMilliLitres <= 49) {
          leds[0] = CRGB::Green;
          FastLED.show();
          delay(1000);
        }
        else if (flowMilliLitres >= 50) {
          digitalWrite(buzzer, HIGH);
    //      delay(2000);
          leds[0] = CRGB::Red;
          FastLED.show();
          delay(1000);
        }
      }
    }
    /*
      Insterrupt Service Routine
    */
    void pulseCounter()
    {
      // Increment the pulse counter
      pulseCount++;
    }
    
  • Click here for code - With WiFi (Expert Level)

    /* Prototype Name : Water Meter (with WiFi)
       Input Sensor   : Flow Sensor,
       Output Device  : Buzzer, WiFi module
       Libraries Used : LiquidCrystalPCF584, FastLED, SoftwareSerial
    */
    
    #include <LiquidCrystal_PCF8574.h>
    LiquidCrystal_PCF8574 lcd(0x3F);
    #include <SoftwareSerial.h>
    #include<FastLED.h>
    #define DATA_PIN 9 // Digital pin number for LED (Multicolor)
    #define NUM_LEDS 3
    CRGB leds[NUM_LEDS];
    #define RX 11
    #define TX 10
    SoftwareSerial esp8266 (RX, TX);
    //Wifi and password
    String AP = "xxxxxxxxx";       // CHANGE ME
    String PASS = "xxxxxxxx"; // CHANGE ME
    // API key and thingspeak link , port, field
    String API = "OE3OTESYER9SO7NF";   // CHANGE ME
    String HOST = "139.59.69.168";
    String PORT = "3000";
    String field = "field1"; // Modify based on the field in the channel
    int count = 0;
    
    int countTrueCommand;
    int countTimeCommand;
    boolean found = false;
    int buzzer = 8; //digital pin 8
    int pulsecount = 0;;
    byte sensorInterrupt = 0;
    byte sensorPin       = 2; //digital pin 2
    float calibrationFactor = 4.5;
    
    volatile byte pulseCount;
    
    float flowRate;
    unsigned int flowMilliLitres;
    unsigned long totalMilliLitres;
    
    unsigned long oldTime;
    
    void setup() {
      Serial.begin(9600);
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      leds[0] = CRGB::Black;
      FastLED.show();
      esp8266.begin(115200);
      sendCommand("AT", 5, "OK");
      sendCommand("AT+CWMODE=1", 5, "OK");
      sendCommand("AT+CWJAP=\"" + AP + "\",\"" + PASS + "\"", 20, "OK");
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
      pinMode(buzzer, OUTPUT);
      pinMode(sensorPin, INPUT);
      digitalWrite(sensorPin, HIGH);
      lcd.begin(16, 2);
      lcd.setBacklight(255);
      lcd.setCursor(0, 0);
      lcd.print("Buzzer Tap");
      lcd.clear();
      pulseCount        = 0;
      flowRate          = 0.0;
      flowMilliLitres   = 0;
      totalMilliLitres  = 0;
      oldTime           = 0;
      attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    }
    
    void loop() {
      flow_sensor();
      flowrate_indicator();
      String Link = "GET /update?api_key=" + API  + "&field1=" ;
      Link = Link +  flowRate;
      Link = Link + " HTTP/1.1\r\n" + "Host: " + HOST + "\r\n" + "Connection: close\r\n\r\n";
      delay(1000);  //Read Web Page every 1 seconds
      sendCommand("AT+CIPMUX=1", 5, "OK");
      sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
      sendCommand("AT+CIPSEND=0," + String(Link.length() + 4), 4, ">");
      esp8266.println(Link); delay(1500); countTrueCommand++;
      sendCommand("AT+CIPCLOSE=0", 5, "OK");
    
    }
    void flow_sensor() {
      if ((millis() - oldTime) > 1000)   // Only process counters once per second
      {
    
        detachInterrupt(sensorInterrupt);
        flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
        oldTime = millis();
        flowMilliLitres = (flowRate / 60) * 1000;
        totalMilliLitres += flowMilliLitres;
        unsigned int frac;
        Serial.print("Flow rate: ");
        Serial.print(int(flowRate));  // Print the integer part of the variabley
        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
        Serial.print("L/min");
        // Print the number of litres flowed in this second
        Serial.print("  Current Liquid Flowing: ");             // Output separator
        Serial.print(flowMilliLitres);
        Serial.print("mL/Sec");
    
        // Print the cumulative total of litres flowed since starting
        Serial.print("  Output Liquid Quantity: ");             // Output separator
        Serial.print(totalMilliLitres);
        Serial.println("mL");
        pulseCount = 0;
        attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
      }
    }
    void flowrate_indicator() {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Flow Rate:");
      lcd.print(int(flowRate));
      if (flowRate > 0 && flowRate <= 2) {
        tone(buzzer, 1000, 500) ;//beeps at frequency of 1000Hz
      }
      else if (flowRate > 2 && flowRate < 5) {
        tone(buzzer, 10000, 500) ;//beeps at frequency of 10000Hz
      }
      else if (totalMilliLitres >= 5) {
        tone(buzzer, 45000, 500) ;//beeps at frequency of 45000Hz
      }
    
    }
    void pulseCounter()
    {
      // Increment the pulse counter
      pulseCount++;
    }
    void sendCommand(String command, int maxTime, char readReplay[]) {
      Serial.print(countTrueCommand);
      Serial.print(". at command => ");
      Serial.print(command);
      Serial.print(" ");
      while (countTimeCommand < (maxTime * 1))
      {
        esp8266.println(command);//at+cipsend
        if (esp8266.find(readReplay)) //ok
        {
          found = true;
          break;
        }
    
        countTimeCommand++;
      }
    
      if (found == true)
      {
        Serial.println("OK");
        countTrueCommand++;
        countTimeCommand = 0;
      }
    
      if (found == false)
      {
        Serial.println("Fail");
        countTrueCommand = 0;
        countTimeCommand = 0;
      }
    
      found = false;
    }
    
  1. Then Check for Tools→ Board→ Port in the IDE.

  2. Compile and Upload the code.

  3. Disconnect USB cable.

  4. Switch off the Solution Box.

  5. Switch on the Solution Box.

  6. Test by blowing air into the flow sensor in the direction of the arrow. Test if value increases in the serial monitor/ LCD screen.

  7. Disconnect the flow sensor from the Solution Box.

  8. 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.

  9. Re-Connect the 3 pin wire connector to the PCB in the port named “Flow Sensor”. Extend if needed. You can use Jumper cables for this.

  10. Connect the flow sensor to the 3 pin wire connector.

  11. Hang the Solution Box 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 Solution Box.

  2. Power up the Solution Box.


Share

Refer to the fourth booklet Share inside the Solve Ninja Techno Kit to know how you can share your solution.

  • 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: Share your solution on the Solve Ninja App, 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!