HomeTutorials › Using A Flow Sensor With Arduino

Using A Flow Sensor With Arduino

In this tutorial we will be hooking up a Flow Sensor to an Arduino Uno to measure liquid flow. This type of flow sensor is designed to measure the volume of liquid traveling past a given point, a great way to keep tabs on how much water your drip irrigation system is using, or any other project were the flow of liquid needs to be tracked. We like this basic flow sensors because of its relatively low cost and ease of use.

A Few Considerations:
Before we jump into getting this sensor hooked up there are a few points to consider when using it in a project.

• These are not able to monitor a flow of less than 1 liter per minute or in excess of 30 liters per minute.
• The sensor is rated to a Maximum of 2.0MPa (290 PSI)

How It Works:
The sensor itself is very simple inside; there is a small flapper wheel that spins as water flows past. A magnet on the flapper wheel triggers a hall effect sensor which sends a momentary pulse down the output wire with each revolution. Knowing that there are 450 pulses per liter, we can then determine the flow rate over time or the total volume that has passed… or both!

The Parts Needed:

flow-2

This tutorial will be requiring a few common parts:

We have also used one of our full sized Arduino Mounting Plates in this tutorial. The mounting plate keeps your Arduino and breadboard neatly fixed next to one another, allowing for much more organized prototyping!

The Schematic

This handy little diagram shows how we will be connecting everything. Don’t worry if it looks a little overwhelming, we will be going through this step by step!

sketch1

Step 1 – Power To The Breadboard

flow-4

We are going to jump right in and set up the Arduino Uno and the breadboard right next to one another. The sensor works with anywhere between 5-18VDC but since we are working with 5VDC logic on the Arduino, we will just use the Arduino’s own 5V power by way of the USB port at this time.

Start by connecting one of the jumper wires from the 5V pin on the Arduino and running it over to the positive rail on the side of the solderless breadboard. Next, run a wire from the Ground pin on the Arduino over to the negative rail on the solderless breadboard.

We now have power on the breadboard!

Step 2 – The Sensor’s Wire Harness

flow-5

This particular sensor has a nice long wire harness complete with a connector. We do not happen to have the connector laying around but luckily we can use our Male/Male Prototyping Wires to connect this sensor to the breadboard. Alternatively, any long 0.100″ pitch breadboard compatible header pins could also be used. We chose this method as it is much easier to visually follow the wires.

The harness itself has a Red, Yellow, and Black wire. We know from the product page that the red wire is a power wire, the yellow wire is the output wire for the sensor, and the black wire is a ground.

Step 3 – The Pull Up Resistor

flow-6

Next we are going to use a 10K Ohm resistor (Brown, Black, Orange) as a pull up resistor. The pull up resistor prevents a situation where the Arduino digital input pin ends up floating (think of this as the input not definitively being on or off). When an input is floating it may hold the last value, it may flip between off and on, quite random – generally not a good thing when we are trying to tell if it is on or off!

Bend the legs of the resistor and placed it between the positive 5V rail on the breadboard and a row of pins. We are also going to go ahead and extend the sensor’s wire harness by plugging jumper wires into the connector.

Step 4 – Connecting The Sensor To The Breadboard

flow-7

In the last step we extended the sensor’s wire harness – we can now plug these jumper wires into the breadboard. The Black wire is the sensor ground and should be connected to the negative (ground) rail on the breadboard. The Red wire should be connected to the positive 5V rail to give the sensor power. The yellow wire should be plugged into the same row as the pull up resistor we added last step – this is the output from the sensor.

We are just about there!

Step 5 – The Final Connection

flow-8

We have one last wire to add – this connects the pull up resistor and the sensor output to the Arduino’s digital input. In this example we will be using an interrupt pin so we will need to use pin 2 on the Arduino Uno. If you are using a different Arduino please consult this table to see what pins are available!

Step 6 – Double Check And Plug It In!

flow-2

Before we give the Arduino power it is always a good idea to go over all of the connections to make sure there are no wires in the wrong spot – sometimes that can make for a very expensive mistake!

One way to avoid this problem is good wire color discipline. In other words, decide on a purpose for each color of wire and stick to them! In this example all 5V power are red wires, all grounds are black wires, and yellow are signal wires. This way, if you ever see a red wire going to a black wire you will know right away that something isn’t quite right!

Step 7 – Starting The Code


void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}

Now that we have finished with the hookup we need to start writing some code. We will be using the Arduino IDE, this is available from https://www.arduino.cc/en/Main/Software

We will start with the “BareMinimum” sketch found by clicking “File” and selecting Examples / Basic / BareMinimum. This sketch is a great starting point as it includes the Setup and Loop functions – we will write the rest!

Step 8 – Understanding How To Read The Sensor

We know that this sensor will output a pulse to Arduino pin 2 every time the flapper rotates and every and that every rotation means 2.25mL of fluid has passed the sensor so calculating the flow rate is really just a matter of counting the revolutions per minute and multiplying by 2.25mL .

So, what is the best way to count RPM with an Arduino? In this case the interrupt pin is going to be very useful. Interrupts have a very appropriate name – they allow you to perform a task (run a segment of code) the moment a signal is received, meaning they are great when you are trying to count pulses from a sensor.

Using interrupts is easy – lets get to it!

Step 9 – Writing The Code

We are starting with the BareMinimum Sketch found in the IDE, it should look something like this:

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:  
}
 

So first we will need some variables to hold values:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:  
}
 

The volatile integer “count” is important as it will be where we store the number of pulses during each second we test. The volatile part may be new to many of you, and it is there to ensure the variable updates correctly during the Interrupt Service Routine. Aside from that, it acts just like any other integer. We will want it to increment every single time there is a pulse received which means we need to create a new function that the interrupt will run when a pulse is received:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:  
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

 

The “++” following the variable means every time the program runs this line it will add 1 to that variable – great for counting!

The interrupt function will be calling the “Flow” function so lets go ahead and add the interrupt to the setup section of code:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  

}
void loop() {
  // put your main code here, to run repeatedly:  
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

 

So that last little bit may require a little more explanation: The first thing we should be clear about is on the Arduino Uno pin 2 is Interrupt 0, so both lines of code we have added are referring to the same physical pin on the Arduino. Basically the pin needs to be set as an input before setting up the interrupt.

On the next line we are configuring the interrupt by using “attachInterrupt”. To better illustrate how this line works, think of it as this:

attachInterrupt(interrupt number, the function you would like to run when triggered, what you would like to set as the trigger).

So we are using interrupt 0 to trigger “Flow” when the pin changes from low to high (when a pulse from the sensor arrives). The complete list of triggers are available on the Arduino Learning Center

Time to start writing the main code that will run continuously in the loop:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  

}
void loop() {
  // put your main code here, to run repeatedly:  
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

 

OK, half way there. Since the loop runs over and over again we need reset our variable “count” to 0 at the beginning, we do not want the number of pulses from the last loop carrying forward. The next line enables the interrupts, meaning we now start counting how many pulses the sensor sends out. On the following line we delay the code for 1000ms (1 Second) to give us time to count pulses and on the last line we disable the interrupts to stop counting. Any pulses from the sensor are ignored before the interrupt is enabled and after it is disabled so with this code we will take a very accurate count of pulses over a period of 1 second.

Let’s do some math to turn the number of pulses per second to a more useful unit of measure:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  

}
void loop() {
  // put your main code here, to run repeatedly:  
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
  
  //Start the math
  flowRate = (count * 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
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

 

Those last 3 lines were just a unit conversion.

Pulses per second * 2.25 milliliters per Pulse = milliliters/Second
mL/Second * 60 Seconds = mL/Minute
mL/Minute / 1000 = Liters/Minute

So flowRate = Liters/Minute … Perfect! Now we just need to write it to Serial so we can actually see the data:

int flowPin = 2;    //This is the input pin on the Arduino
double flowRate;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  

void setup() {
  // put your setup code here, to run once:
  pinMode(flowPin, INPUT);           //Sets the pin as an input
  attachInterrupt(0, Flow, RISING);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(9600);  //Start Serial
}
void loop() {
  // put your main code here, to run repeatedly:  
  count = 0;      // Reset the counter so we start counting from 0 again
  interrupts();   //Enables interrupts on the Arduino
  delay (1000);   //Wait 1 second 
  noInterrupts(); //Disable the interrupts on the Arduino
  
  //Start the math
  flowRate = (count * 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

  Serial.println(flowRate);         //Print the variable flowRate to Serial
}

void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

 

In the Setup we are starting the Serial connection at a rate of 9600 Baud – the default speed. At the bottom of the loop we are printing a line on the Serial connection containing the result of our math. All Done!

Step 10 – Upload The Code And Test

finalcode1

Now that all of the code has been written it can be uploaded to your Arduino! Click “Upload” button in the top left corner of the Arduino IDE and it should upload without any issues. Next, click the “Serial Monitor” button in the top right corner (it looks like a magnifying glass). After a few seconds you should start to see a stream of data appear in the window – that is your flow in Liters/Minute.

Have A Question?
If you have any questions, or need further clarification please post in the comments section below; this way future users of this tutorial can see the questions and answers!

Parts Used In This Tutorial:

57 comments

  1. Bagus
  2. daniel
  3. Jason
  4. Stefan
  5. Vasekdvor
  6. rishii
  7. José Lobo
    • Theo S.
  8. Mehdi
    • Theo S.
  9. Erik
  10. KaisarGreat
  11. Jaeson
  12. quangckd0703
  13. kuldeep singh
  14. Matías
  15. AJAY
  16. R.Arun
    • Theo S.
  17. sangeetha
  18. her0
    • Theo S.
  19. Sanjukta Bagchi
  20. Mattie Mckenzie
  21. john
  22. Kathryn
    • Theo S.
  23. Saman
    • Theo S.
  24. WEXLER
    • Theo S.
  25. Elpiniki Marouli
  26. liv_nicole01
    • Theo S.
  27. Shashi Kiran
  28. Shashi Kiran
  29. Alim Huseynov
    • Front Desk @ BCR

Leave a Reply