Internet Connected Smart Water Meter

In this article by Pradeeka Seneviratne, author of the book Internet of Things with Arduino Blueprints, goes on to say that for many years and even now, water meter readings are collected manually. To do this, a person has to visit the location where the water meter is installed. In this article, we learn how to make a smart water meter with an LCD screen that has the ability to connect to the Internet wirelessly and serve meter readings to the utility company as well as the consumer.

(For more resources related to this topic, see here.)

In this article, we will:

  • Learn about water flow meters and its basic operation
  • Learn how to mount and plumb a water flow meter to the pipeline
  • Read and count water flow sensor pulses
  • Calculate water flow rate and volume
  • Learn about LCD displays and connecting with Arduino
  • Convert a water flow meter to a simple web server and serve meter readings over the Internet

Prerequisites

The following are the prerequisites:

  • One Arduino UNO board (The latest version is REV 3)
  • One Arduino Wi-Fi Shield (The latest version is REV 3)
  • One Adafruit Liquid flow meter or a similar one
  • One Hitachi HD44780 DRIVER compatible LCD Screen (16x2)
  • One 10K ohm resistor
  • One 10K ohm potentiometer
  • Few Jumper wires with male and female headers (https://www.sparkfun.com/products/9140)

Water Flow Meters

The heart of a water flow meter consists of a Hall Effect sensor that outputs pulses for magnetic field changes. Inside the housing, there is a small pinwheel with a permanent magnet attached. When the water flows through the housing, the pinwheel begins to spin and the magnet attached to it passes very close to the Hall Effect sensor in every cycle. The Hall Effect sensor is covered with a separate plastic housing to protect it from the water. The result generates an electric pulse that transitions from low voltage to high voltage, or high voltage to low voltage, depending on the attached permanent magnet's polarity. The resulting pulse can be read and counted using Arduino.

For this project, we will be using Adafruit Liquid Flow Meter. You can visit the product page at http://www.adafruit.com/products/828. The following image shows Adafruit Liquid Flow Meter:

Internet of Things with Arduino Blueprints

This image is taken from http://www.adafruit.com/products/828

Internet of Things with Arduino Blueprints

Pinwheel attached inside the water flow meter

A little bit about Plumbing

Typically, the direction of the water flow is indicated by an arrow mark on top of the water flow meter's enclosure. Also, you can mount the water flow meter either horizontally or vertically according to its specifications. Some water flow meters can mount both horizontally and vertically.

You can install your water flow meter to a half-inch pipeline using normal BSP pipe connectors. The outer diameter of the connector is 0.78" and the inner thread size is half an inch.

The water flow meter has threaded ends on both sides. Connect the threaded side of the PVC connectors to both ends of the water flow meter. Use the thread seal tape to seal the connection, and then connect the other ends to an existing half-inch pipe line using PVC pipe glue or solvent cement.

Make sure to connect the water flow meter with the pipeline in the correct direction. See the arrow mark on top of the water flow meter for flow direction.

Internet of Things with Arduino Blueprints

BNC Pipeline Connector made by PVC

Internet of Things with Arduino Blueprints

Securing the connection between Water Flow Meter and BNC Pipe Connector using Thread seal

Internet of Things with Arduino Blueprints

PVC Solvent cement used to secure the connection between pipeline and BNC pipe connector.

Wiring the water flow meter with Arduino

The water flow meter that we are using with this project has three wires, which are as follows:

  • The red wire indicates the positive terminal
  • The black wire indicates the Negative terminal
  • The yellow wire indicates the DATA terminal

All three wire ends are connected to a JST connector. Always refer to the datasheet before connecting them with the microcontroller and the power source.

Use jumper wires with male and female headers as follows:

  1. Connect the positive terminal of the water flow meter to Arduino 5V.
  2. Connect the negative terminal of the water flow meter to Arduino GND.
  3. Connect the DATA terminal of the water flow meter to Arduino digital pin 2 through a 10K ohm resistor.

Internet of Things with Arduino Blueprints

You can directly power the water flow sensor using Arduino since most of the residential type water flow sensors operate under 5V and consume a very low amount of current. You can read the product manual for more information about the supply voltage and supply current range to save your Arduino from high current consumption by the water flow sensor. If your water flow sensor requires a supply current of more than 200mA or a supply voltage of more than 5V to function correctly, use a separate power source with it.

The following image illustrates jumper wires with male and female headers:

Internet of Things with Arduino Blueprints

Reading pulses

Water flow meter produces and outputs digital pulses according to the amount of water flowing through it that can be detected and counted using Arduino.

According to the data sheet, the water flow meter that we are using for this project will generate approximately 450 pulses per liter. So 1 pulse approximately equals to [1000 ml/450 pulses] 2.22 ml. These values can be different depending on the speed of the water flow and the mounting polarity.

Arduino can read digital pulses by generating the water flow meter through the DATA line.

Rising edge and falling edge

There are two type of pulses, which are as follows:

  • Positive-going pulse: In an idle state, the logic level is normally LOW. It goes to HIGH state, stays at HIGH state for time t, and comes back to LOW state.
  • Negative-going pulse: In an idle state, the logic level is normally HIGH. It goes LOW state, stays at LOW state for time t, and comes back to HIGH state.

The rising edge and falling edge of a pulse are vertical. The transition from LOW state to HIGH state is called RISING EDGE and the transition from HIGH state to LOW state is called falling EDGE.

You can capture digital pulses using rising edge or falling edge, and in this project, we will be using the rising edge.

Reading and counting pulses with Arduino

In the previous section, you have attached the water flow meter to Arduino. The pulse can be read by digital pin 2 and the interrupt 0 is attached to digital pin 2. The following sketch counts pulses per second and displays on the Arduino Serial Monitor.

Using Arduino IDE, upload the following sketch into your Arduino board:

int pin = 2;

volatile int pulse;

const int pulses_per_litre=450;

 

void setup()

{

Serial.begin(9600);

 

pinMode(pin, INPUT);

attachInterrupt(0, count_pulse, RISING);

}

 

void loop()

{

pulse=0;

interrupts();

delay(1000);

noInterrupts();

 

Serial.print("Pulses per second: ");

Serial.println(pulse);

 

}

 

void count_pulse()

{

pulse++;

}

Calculating the water flow rate

The water flow rate is the amount of water flowing at a given time and can be expressed in gallons per second or liters per second. The number of pulses generated per liter of water flowing through the sensor can be found in the water flow sensor's specification sheet. Let's say m. So, you can count the number of pulses generated by the sensor per second, Let's say n.

Thus, the water flow rate R can be expressed as follows:

Internet of Things with Arduino Blueprints

The water flow rate is measured in liters per second.

Also, you can calculate the water flow rate in liters per minute as follows:

Internet of Things with Arduino Blueprints

For example, if your water flow sensor generates 450 pulses for one liter of water flowing through it and you get 10 pulses for the first second, then the elapsed water flow rate is 10/450 = 0.022 liters per second or 0.022 * 1000 = 22 milliliters per second.

Using your Arduino IDE, upload the following sketch into your Arduino board. It will output water flow rate in liters per second on the Arduino Serial Monitor.

int pin = 2;

volatile int pulse;

const int pulses_per_litre=450;

 

void setup()

{

Serial.begin(9600);

pinMode(pin, INPUT);

attachInterrupt(0, count_pulse, RISING);

}

 

void loop()

{

pulse=0;

interrupts();

delay(1000);

noInterrupts();

 

Serial.print("Pulses per second: ");

Serial.println(pulse);

 

Serial.print("Water flow rate: ");

Serial.print(pulse/pulses_per_litre);

Serial.println("litres per second");

}

 

void count_pulse()

{

pulse++;

}

Calculating water flow volume

Water flow volume can be calculated by adding all the flow rates per second of a minute and can be expressed as follows:

Volume = ∑ Flow Rates

The following Arduino sketch will calculate and output the total water volume since startup. Upload the sketch into your Arduino board using Arduino IDE.

int pin = 2;

volatile int pulse;

float volume = 0;

float flow_rate =0;

const int pulses_per_litre=450;

 

void setup()

{

Serial.begin(9600);

pinMode(pin, INPUT);

attachInterrupt(0, count_pulse, RISING);

}

 

void loop()

{

pulse=0;

volume=0;

interrupts();

delay(1000);

noInterrupts();

 

Serial.print("Pulses per second: ");

Serial.println(pulse);

 

flow_rate = pulse/pulses_per_litre;

 

Serial.print("Water flow rate: ");

Serial.print(flow_rate);

Serial.println("litres per second");

 

volume = volume + flow_rate;

 

Serial.print("Volume: ");

Serial.print(volume);

Serial.println(" litres");

 

}

 

void count_pulse()

{

pulse++;

}

To measure the accurate water flow rate and volume, the water flow meter will need careful calibration. The sensor inside the water flow meter is not a precision sensor, and the pulse rate does vary a bit depending on the flow rate, fluid pressure, and sensor orientation.

Adding an LCD screen to the water meter

You can add an LCD screen to your water meter to display readings rather than displaying them on the Arduino serial monitor. You can then disconnect your water meter from the computer after uploading the sketch onto your Arduino.

Using a Hitachi HD44780 driver compatible LCD screen and Arduino LiquidCrystal library, you can easily integrate it with your water meter. Typically, this type of LCD screen has 16 interface connectors. The display has 2 rows and 16 columns, so each row can display up to 16 characters.

Internet of Things with Arduino Blueprints

Wire your LCD screen with Arduino as shown in the preceding diagram. Use the 10K potentiometer to control the contrast of the LCD screen. Perform the following steps to connect your LCD screen with your Arduino:

  • LCD RS pin to digital pin 8
  • LCD Enable pin to digital pin 7
  • LCD D4 pin to digital pin 6
  • LCD D5 pin to digital pin 5
  • LCD D6 pin to digital pin 4
  • LCD D7 pin to digital pin 3

Wire a 10K pot to +5V and GND, with its wiper (output) to LCD screens VO pin (pin3).

Internet of Things with Arduino Blueprints

Now, upload the following sketch into your Arduino board using Arduino IDE, and then remove the USB cable from your computer. Make sure the water is flowing through the water meter and press the Arduino reset button. You can see number of pulses per second, water flow rate per second, and the total water volume from the beginning of the time displayed on the LCD screen.

#include <LiquidCrystal.h>

 

int pin = 2;

volatile int pulse;

float volume = 0;

float flow_rate =0;

const int pulses_per_litre=450;

 

// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(8, 7, 6, 5, 4, 3);

 

void setup()

{

Serial.begin(9600);

pinMode(pin, INPUT);

attachInterrupt(0, count_pulse, RISING);

 

// set up the LCD's number of columns and rows:

lcd.begin(16, 2);

// Print a message to the LCD.

lcd.print("Welcome");

}

 

void loop()

{

pulse=0;

volume=0;

interrupts();

delay(1000);

noInterrupts();

 

lcd.setCursor(0, 0);

 

lcd.print("Pulses/s: ");

lcd.print(pulse);

 

flow_rate = pulse/pulses_per_litre;

 

lcd.setCursor(0, 1);

lcd.print(flow_rate,DEC);

lcd.print(" l/s");

 

volume = volume + flow_rate;

 

lcd.setCursor(0, 8);

lcd.print(volume, DEC);

lcd.println(" l");

}

 

void count_pulse()

{

pulse++;

}

Converting your water meter to a web server

In the previous steps, you have learned how to display your water flow sensor's readings, and calculate water flow rate and total volume on the Arduino serial monitor. In this step, we learn about integrating a simple web server to your water flow sensor and remotely read your water flow sensor's readings.

You can make a wireless web server with Arduino Wi-Fi shield or Ethernet connected web server with the Arduino Ethernet shield.

  1. Remove all the wires you have connected to your Arduino in the previous sections in this article.
  2. Stack the Arduino Wi-Fi shield on the Arduino board using wire-wrap headers. Make sure the Wi-Fi shield is properly seated on the Arduino board.
  3. Now reconnect the wires from water flow sensor to the Wi-Fi shield. Use the same pin numbers as in previous step.
  4. Connect 9V DC power supply to the Arduino board.
  5. Connect your Arduino to your PC using the USB cable and upload the following sketch. Once the upload is complete, remove your USB cable from the water flow meter. Upload the following Arduino sketch into your Arduino board using Arduino IDE:
    #include <SPI.h>
    
    #include <WiFi.h>
    
     
    
    char ssid[] = "yourNetwork";
    
    char pass[] = "secretPassword";
    
    int keyIndex = 0;
    
     
    
    int pin = 2;
    
    volatile int pulse;
    
    float volume = 0;
    
    float flow_rate =0;
    
    const int pulses_per_litre=450;
    
     
    
    int status = WL_IDLE_STATUS;
    
     
    
    WiFiServer server(80);
    
     
    
    void setup()
    
    {
    
     
    
    Serial.begin(9600);
    
    while (!Serial)
    
    {
    
    ;
    
    }
    
     
    
     
    
    if (WiFi.status() == WL_NO_SHIELD)
    
    {
    
    Serial.println("WiFi shield not present");
    
    while(true);
    
    }
    
     
    
    // attempt to connect to Wifi network:
    
    while ( status != WL_CONNECTED) {
    
    Serial.print("Attempting to connect to SSID: ");
    
    Serial.println(ssid);
    
     
    
    status = WiFi.begin(ssid, pass);
    
     
    
    delay(10000);
    
    }
    
    server.begin();
    
    }
    
     
    
     
    
    void loop()
    
    {
    
     
    
    WiFiClient client = server.available();
    
    if (client) {
    
    Serial.println("new client");
    
     
    
    boolean currentLineIsBlank = true;
    
    while (client.connected()) {
    
    if (client.available()) {
    
    char c = client.read();
    
    Serial.write(c);
    
     
    
    if (c == '\n' &&currentLineIsBlank) {
    
     
    
    client.println("HTTP/1.1 200 OK");
    
    client.println("Content-Type: text/html");
    
    client.println("Connection: close");
    
    client.println("Refresh: 5");
    
    client.println();
    
    client.println("<!DOCTYPE HTML>");
    
    client.println("<html>");
    
     
    
    if (WiFi.status() != WL_CONNECTED) {
    
    client.println("Couldn't get a wifi connection");
    
    while(true);
    
    }
    
     
    
    else {
    
     
    
    //print meter readings on web page
    
    pulse=0;
    
    volume=0;
    
    interrupts();
    
    delay(1000);
    
    noInterrupts();
    
     
    
    client.print("Pulses per second: ");
    
    client.println(pulse);
    
     
    
    flow_rate = pulse/pulses_per_litre;
    
     
    
    client.print("Water flow rate: ");
    
    client.print(flow_rate);
    
    client.println("litres per second");
    
     
    
    volume = volume + flow_rate;
    
     
    
    client.print("Volume: ");
    
    client.print(volume);
    
    client.println(" litres");
    
    //end
    
     
    
    }    
    
     
    
    client.println("</html>");
    
    break;
    
       }
    
    if (c == '\n') {
    
     
    
    currentLineIsBlank = true;
    
       }
    
    else if (c != '\r') {
    
     
    
    currentLineIsBlank = false;
    
       }
    
       }
    
    }
    
     
    
    delay(1);
    
     
    
    client.stop();
    
    Serial.println("client disconnected");
    
    }
    
    }
    
     
    
    void count_pulse()
    
    {
    
    pulse++;
    
    }
  6. Open the water valve and make sure the water flows through the meter.
  7. Click on the RESET button on the WiFi shield.
  8. In your web browser, type your WiFi shield's IP address and press Enter. You can see your water flow sensor's flow rate and total volume on the web page. The page refreshes every 5 seconds to display the updated information.

Summary

In this article, you gained hands-on experience and knowledge about water flow sensors and counting pulses while calculating and displaying them. Finally, you made a simple web server to allow users to read the water meter through the Internet. You can apply this to any type of liquid, but make sure to select the correct flow sensor because some liquids react chemically with the material the sensor is made of. You can search on Google and find which flow sensors support your preferred liquid type.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Internet of Things with Arduino Blueprints

Explore Title