I am sure a lot of you are also working on ways to keep an eye on water flow, So I thought I would make a blog covering my implementation.
I opted for a hall effect flow meter because I salvaged it a while ago and had it handy. It has been up and running in the greenhouse for a while now as part of a larger code, Ive pulled the meter portion out and it is below, I've got no spare arduino to test it works but it is pretty simple [Point out any problems you see].
How It works:
I dont like the approach of measuring the frequency to calculate flow rate and then integrating to get water flow, So It works the opposite way.
>ISR to log number of pulses
>Convert the Pulses/second for a flow rate
>Logs Total Pulses for total water usage
>Checks there isnt a major leak [flow rate is reduced because I use drip irrigation]
Things to keep in mind, the serial will reset every time you reconnect so it isnt goof for final implementation, the clock will roll-over every 50 days and could output one bad reading every 50 days. This code is commented to allow anyone to implement it and you guys at Element14 will find them a little obvious,sorry.
Code - ISR Based FLow Meter |
---|
/* This script is used to make sense of the output from a hall effect water flow meter and make a note of any problems
Michael Ratcliffe Mike@MichaelRatcliffe.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Components: See main folder for sensor data sheets, required liabaries and extra information: [can be downloaded via www.michaelratcliffe.com]
All power systems should be powerd of DC voltage of below 48v for safter [water is around] 12v is prefferable and cheapest. As always this is a DIY project and done at your own risk.
>Arduino Mega 2560 [1280 is not sutiable, ram problems and sensor conflict] compiled using Arduino 1:1.0.5 >Hall Effect Water Flow Meter 5v
*/ //******************************** User Defined Variables *******************************************************// #define Meter_power 5 #define Meter_ground 4 #define Water_pin 3
float Click_Per_L = 300; // this depends on your flow meter
const float Max_ExpectedFlow =2; //Max flow expected flowrate in L/s, if it is more than this we have a problem
//************************** Just Some basic Definitions used for the Up Time LOgger ************// long Day=0; int Hour =0; int Minute=0; int Second=0; int HighMillis=0; int Rollover=0;
//***************************** End Of User Defined Variables **************************************************//
unsigned long PulseCount=0; //counter for water meter pulses unsigned long Current_PulseCount=0; int Last_Reading=0; int Readings=0; float Water_Used=0; float Flow_Rate= 0; unsigned long Last_Count =0;
//**************************** Setup Routine , Runs Once and Sets used pins to correct value *******************// void setup() {
//Making it easy to power the Flowmeter pinMode(Meter_ground, OUTPUT); digitalWrite(Meter_ground, LOW); pinMode( Meter_power, OUTPUT); digitalWrite(Meter_power, HIGH);
//Stoping noise from being a problem, pin is high untill hall sensor pulls it low pinMode(Water_pin, INPUT); digitalWrite(Water_pin, HIGH);// saves having an external pullup
//External Interrupts: This is what the watr meter pulse count is collected from attachInterrupt(1, WaterCounter, FALLING); //watermeter pulse output connected to pin3 };
//************************************** Main Loop that will continualy run ******************************************// void loop(){
//calls uptime function below main loop uptime();
//************** If Statment that will run every second ******************// if (Last_Reading!=Second) { Last_Reading=Second; //Makes note of the last second Readings=1; //Tell serial there is data to transmit
//Turn off interupt while we take a quick note of it and then turn it back on detachInterrupt(1); // Current_PulseCount=PulseCount; // making note of pulse count attachInterrupt(1, WaterCounter, FALLING); //watermeter pulse output connected to pin3
Flow_Rate=((Current_PulseCount-Last_Count)/Click_Per_L); Water_Used=(1/(Click_Per_L/Current_PulseCount)); //cant recall why I did it this way, maybe to retain float capabilities
Last_Count=Current_PulseCount; // Makes a note of the last reading
};
//**** Checks If there is Data To send over Serial- Recomended to be LCD instead ******// if (Readings==1){ print_Serial();
}
delay(10); }; //*************************************************END OF LOOP ******************************************************//
//******************* Uptime Counter **************************************************// //WE need an uptime counter to verify our total flow readout is valid
void uptime(){ //** Making Note of an expected rollover *****// if(millis()>=3000000000){ HighMillis=1;
} //** Making note of actual rollover **// if(millis()<=100000&&HighMillis==1){ Rollover++; HighMillis=0; } long secsUp = millis()/1000; Second = secsUp%60; Minute = (secsUp/60)%60; Hour = (secsUp/(60*60))%24; Day = (Rollover*50)+(secsUp/(60*60*24)); //First portion takes care of a rollover [around 50 days] };
//******************** Prints To Serial Console **********************************************************//
void print_Serial(){
//Printing Some Uptime Values Serial.print(F("Uptime: ")); // The "F" Portion saves your SRam Space Serial.print(Day); Serial.print(F(" Days ")); Serial.print(Hour); Serial.print(F(" Hours ")); Serial.print(Minute); Serial.print(F(" Minutes ")); Serial.print(Second); Serial.println(F(" Seconds"));
//Printing Some Water Flow info Serial.print(F("Total Water Used")); Serial.print(Water_Used); Serial.println(F(" L")); Serial.print(F("Current Flow Rate: ")); Serial.print(Flow_Rate); Serial.println(F(" L/s"));
};
//************8*Interupt routine for water meter readings - Runs everytime sensor has a pulse *************//
void WaterCounter() {
// Increment the pulse counter PulseCount++;
}; |
Recommendations: Add a LCD/ IOT solution to remove the serial resetting problem, add a uptime counter.
It looks like other contestants are moving a long quickly now, keep the content coming it makes a great read.
Mike
Top Comments