Spring Cleaning-Flow Meter

I read yet another book on iOS development and got the creative juices flowing with lots of ideas for some image processing.  That said, I’m starting to feel like a hoarder of electronic parts and opted to put a couple SeedStudio Water Flow Sensors to some use.  Besides someone asked me to describe how to use them in simple terms. So this side trip’s goal is put something together to measure the flow from kitchen faucets. The functional requirements include the following:

  • Hot water line measurement
  • Cold water line measurement
  • Current flow rate in L/sec
  • Running volume for the day in L
  • Max flow Duration for the day in seconds
  • Min flow Duration for the day in seconds
  • Average Duration for the day in seconds
  • Total flow duration for the day in seconds 
  • Integration with my existing M2M Mango instation over Modbus

The Approach

The code itself is not complicated and derived from the product wiki page. I briefly entertained some event based model to abstract the interrupts and looked at the Cosa OO platform for the Arduino as a possible candidate. In the end, the spirit of Arduino is to allow “artists, designers, hobbyists” to innovate and opted for something simple.

From the spec sheet,

f=7.5Q where

f is the frequency in Hz +/- 3% horizontal position
Q  is flow rate in\frac{L}{min}

(1) \therefore Q=\frac{f}{7.5}

To convert Q to \frac{L}{s} , mutiply (1) by \frac{1 min}{60s} leads to

(2) Q=\frac{f}{7.5*60} in \frac{L}{s}

The following oscilloscope screen capture shows a pulse train generated from the flow sensor. The aim is to count the number of rise edges (low to high) during a 1 second interval.

The following figure illustrates a three second view of the flow rate. To calculate a running total of the volume of water consumed, one has to integrate the flow rate over a period of time. In this case we just perform a running sum of the area under the curve. In this example, A1 + A2 + A3.

For A1, v=Q*t where
v is the volume in L
t is the sample period which is 1 sec
Q is the flow rate as calculated as shown in equation 2 earlier

 

In general terms, v=\sum_{k=1}^{\infty}Q_k assuming t = 1 second

Variations in flow rate during the sample period (1 second) from the flow sensor is either an in increase or decrease in the number of pulses. If for example, the flow was 0 for the half a second and X over the other half, the end result the average of the two flow rates.

The Core Components 

Putting things Together

The circuitry for this as well as the code is simple. Not much math and just a couple of resistors. It is well described on the at the product wiki page. What I did was create a host board for the pro mini and wired it up with old wire wrapping wire.

The Code

I opted to create a class for the basic flow meter functions. I may want to reuse the code later if I get a different flow sensor. I opted not to create base flowmeter classes from which to create those that are tied to a specific flow sensor. It keeps it simple for the target audience–the hobbyist.

The source can be found here. FlowMeter.h and FlowMeter.cpp. Create a FlowMeter folder under the libraries folder of your Arduino IDE installation. As for the main code it can be downloaded from here. Create a new Arduino project and paste it the editor.

The main loop is shown below. It is far from complex. The sei/delay/cli is key. I did not get into using the millis() to measure the deltaT. I did a quick test and it was 1001/1000 ms so close enough. Invoking begin()/end() need to be invoked prior and after the sei()/cli(). The rest of the code just checks if the totalizers need to be reset based on time of day and process requests from host. To avoid introducing too many errors, the time spend for that overhead should be kept to a minimum so that we keep Ian eye on the pulses.

void loop ()
{
  gHotWaterFlowMeter.begin();
  gColdWaterFlowMeter.begin();

  sei();                
  delay (SLEEPTIME); 
  cli();    

  gHotWaterFlowMeter.end();
  gColdWaterFlowMeter.end();

  resetTotalizers();

  if( bIsModbus == LOW )
  {
    moveToModbusRegisters();
    gModbusSlave.processMasterRequests();
    readSetpointsFromMaster();
  }
  else 
  {
    printToSerial();

  }

}

Installation and Testing

The following photo shows how the solution was mounted. Note that the flow meters were mounted horizontally.

 

For testing, I took a 1 litre measuring container, filled it, and checked out the value on the HMI host for both hot and cold water lines. The volume incremented by 1.1 L on the host. I repeated this several times for different flow rates. Close enough. I do round to the nearest decimal place.  The HMI polls every 30 seconds so the flow rate is usually zero, unless the tap is running for a long time. I also track the flow time as well though I am more interested in the total volume consumed. The screen shot fragments below show what is seen from the host.