IoT Project: Flow Rate Monitoring Device for Water Systems in Developing Communities

Fort Lewis College Department of Physics & Engineering

Mac Greene

FLC Seal
To explore the concept of a cellular connected device for monitoring that status of improved water systems, a system has been configured in which flow measurements are taken by a Particle Electron microcontroller, and routinely published to ThingSpeak as a platform for viewing the data. This tutorial details the construction and configuration of a prototype water system monitoring device.


The Sustainable Development Goals (SDGs), declared by the United Nations, include a goal that all humans will have access to safely managed water services by 2030. Safely managed water services are defined as access to an improved water source (e.g. piped water, a covered well, or protected spring) that is on-premises, available when needed, and free of microbiological and priority chemical contaminants. As of 2016, an estimated 2.1 billion people do not have access to safely managed water services. Eliminating water scarcity is an incredibly ambitious goal; the task of monitoring the current situation alone is labor intensive and expensive. Utilizing the increasing connectedness of the world, and the decreasing price of collecting and sending data over cellular networks could prove beneficial in monitoring and improving the access to water across the world. By leveraging inexpensive microcontrollers with cellular connectivity, municipalities in developing countries can be provided with a platform of monitoring and documenting the current status of water systems in nearby villages. These data can also be used to understand the state of a country's water needs, and how they are being met. This device, equipped with sensors and cellular connectivity capabilities, could enhance the feedback loop between the water provider and the supporting municipality. When a water system is functioning, the device will send back useful water quality data, including flow rates, turbidity readings, and chlorination levels. These data can be stored and viewed by municipalities through an IoT platform, such as ThingSpeak. When abnormal system behaviour is detected, such as a continuous stop of water flow, the municipality will be alerted. This device will be powered by solar energy, but could also utilize fluid flow to generate power. These data could prove valuable over time in validating water system sustainability practices. It will also save time and money by eliminating the need to visit a community to determine the current functionality of a system.

sdg goalssdg

Required Materials:

  1. Electron microcontroller:
  2. Flow Meter:                
  3. Jumper Wires              
  4. 10K Resistor
  5. Solar Panel:                 
In addition to these materials, accounts will need to be created for Particle and for ThingSpeak. Particle subscription fees are $2.99/month at minimum, with additional fees occuring when data limits are exceeded. The first three months of use are free, and the data usage feese are reasonably priced. ThingSpeak is a free service.

Connecting the Flow Sensor
The flow sensor has a wire harness with three connections; power, ground, and an output terminal. The red and black wires correspond to the power-in and ground connections, respectively. The yellow wire is an output that will produce a pulse when water if flowing through the sensor. From the specifications listed on the adafruit page, it is known that the meter will produce 450 pulses per liter of water that flows through the sensor. We can use this information to determine the amount of water that flows through the sensor, and the flow rate!

To connect the flow sensor to the Electron, connect the red wire from the sensor to the VBAT terminal on the Electron. Then, connect the black wire to the ground terminal. Now, we will add in a 10K pull-up resistor into the circuit to prevent the output from the sensor from floating. It is possible for the output from the sensor to be somewhere between LOW and HIGH, which is problematic when trying to count the total number of pulses. By introducing a pull-up resistor, the output from the sensor will remain HIGH until a pulse from the sensor arrives. Place the resistor between the VBAT terminal, and a new strip on the breadboard. Now, connect the other end of the resistor to the yellow wire terminal on the flow sensor wire harness, and the D1 input on the Particle Electron.

wiring diagram
Flow Sensor wired to the Electron, with a pull-up resistor to prevent a floating signal.

Writing the Flow Sensor Code
To correctly register all pulses delivered by the flow sensor, an interrupt is attached to the "flowPin" variable. This allows the function "Flow" to be triggered every time a pulse is registered, resulting in the variable "count" to increase. Not every input pin is capable of acting as an interrupt. The digitial input D0, for example, will not function correctly as an interrupt.

As specified by the manufacturer, the flow sensor will deliver 450 pulses for every 1 liter of water that flows through it. Dividing the number of pulses by 450 results in the number of liters recorded by the sensor, and again dividing by the interval results in the flow rate. Copy and paste the code below into the IDE portal on your Particle account, then "flash" the code unto the Particle Electron. Flashing can be peformed through cellular, but will use a siginificant amount of data to do so. Another option is to flash the code onto the microcontroller using a USB cable. Refer to the Particle CLI documentation for instructions on how to flash a code through a USB from the command prompt.

//Configure the variables
int flowPin = D1;   //This is the input pin for the flow sensor

double flowRate;    //This is the flow rate value to be calculated

double numLiters;   //This is the number of liters that has passed the sensor, calculated from the flow rate

double interval;    //This value allows us to set the data collection period

volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process 

//Put your setup code here, to run once:

void setup() {

  pinMode(flowPin, INPUT);           //Sets the pin as an input

  attachInterrupt(D1, Flow, RISING);  //Configures interrupt to run the function "Flow"  and attaches to flowPin

  interval = 10000 ; //Declare the interval for data collection, in milliseconds


//Put your main code here, to run repeatedly:

void loop() {

  count = 0;          //Reset the counter so we start counting from 0 again

  interrupts();       //Enables interrupts on the Arduino

  delay (interval);   //Wait for 10 seconds

  noInterrupts();     //Disable the interrupts on the Arduino

  numLiters = count / 450;     //Calculate number of liters registered by Count. Note: The flow sensor signals 450 pulses per 1 liter

  flowRate = numLiters / (interval / 60000);      //Calculate the flow rate in LPM

  Particle.publish("FlowRate",String(flowRate)); //Publish the flowRate value, as a string type, through the event "FlowRate"


//Create function Flow
void Flow()


   count++; //Every time this function is called, increment "count" by 1


Configuring the Webhook
In order to visualize the flow measurement data, the Particle server will be connected to ThingSpeak through an internet linking protocal called a webhook. ThingSpeak is an IoT platform that can recieve incoming data from a server via a webhook, and create dynamically-updated graphs from the incoming data. There are numerous IoT platforms available, but ThingSpeak was chosen for its capablity to routinely execute MATLAB scripts that can be used to analyze the data. This feature, however, will not be required in this project, as the incoming data does not need to be altered.

First, create a ThingSpeak account, and create a new channel. You do not need to worry about altering the channel details at this point, but feel free to add a channel name, description, and field 1 title. Now that the channel has been created, a webhook will be created to automatically send the flow measurements from the Particle server to the ThingSpeak channel. To configure the webhook, navigate to the "Integrations" tab on the Particle Console, and select "New Integration", then "Webhook". The event name corresponds to the Particle publish function's first input, which is "FlowRate" in this case (note: the event name is case sensitive). The URL for the webhook will be Leave the "Request Type" as POST, the "Request Format" as Web Form. Choose whether you'd like any microcontroller listed on the Particle account to be able to trigger the webhook, or a specifc device using the "Device" input. Now, click on the Advanced Settings tab, click Custom, and mimic the two form field inputs as shown below. Fill in API key location with the API Write Key located on the API Keys tab of the ThingSpeak channel. Turn on the Electron, the data that is being published to the Particle server should now automatically be added to the field 1 graph on your ThingSpeak channel!

webhook details
Particle Webhook Settings. Replace the "INSERT API WRITE KEY HERE" with the API Write Key from the ThingSpeak channel.

An example of how the value will be displayed on a ThingSpeak plot is shown in the following figure. The settings can be adjusted to alter the number of points displayed, the amount of previous days displayed, and other details.

ThingSpeak Graph
ThinkSpeak Plot demonstrating test flow measurements.
Attaching the Solar Panel
The solar panel can be connected directly to the VIN and GROUND terminals on the Electron. The power management integrated circuit (PMIC) will prevent excessive voltage/current from damaging the microcontroller. To optimize the system, code can be added to put the electron into a sleep mode when certain parameters are met.

Publishing Multiple Variables to ThingSpeak
In this tutorial, we send a single value representing the flow rate to the Particle and ThingSpeak servers as string types. It is possible to concatenate additional variables as a string, such as flow amoung and battery percentage, and publish the entire string to ThingSpeak. In this scenario, an additional channel will need to be configured. One channel serves to store the entire data string, where a MATLAB script can be routinely executed to import the string, split the string into individual variables, and then reupload the variables to individual graphs on a new channel. A diagram demonstrating this flow of data is shown in the following figure. The TimeControl application on thingspeak is used to execute the MATLAB scripts at set intervals. MATLAB scripts are stored under the MATLAB Analysis application on ThingSpeak.

Diagram of data flow through ThingSpeak, starting with the webhook data string.


The code for this project was modelled after the code written for a similiar arduino project tutorial, created by BC Robotics: