Page 1 of 1
Flow meter Testing
Posted: Thu Jan 05, 2012 10:32 pm
by rimai
I've been doing some tests with a flow meter and this is the code I used on the I/O Expansion module:
Code: Select all
int hallsensor0 = 11; //The pin location of the sensor
int hallsensor1 = 3; //The pin location of the sensor
int hallsensor2 = 5; //The pin location of the sensor
volatile int ButtonPress0 = 0;
volatile int ButtonPress1 = 0;
volatile int ButtonPress2 = 0;
void rpm()
{
ButtonPress1++;
}
SIGNAL(PCINT0_vect) {
ButtonPress0++;
}
SIGNAL(PCINT2_vect) {
ButtonPress2++;
}
void setup() //
{
pinMode(hallsensor0, INPUT); //initializes digital pin 2 as an input
digitalWrite(hallsensor0,HIGH);
pinMode(hallsensor1, INPUT); //initializes digital pin 2 as an input
digitalWrite(hallsensor1,HIGH);
pinMode(hallsensor2, INPUT); //initializes digital pin 2 as an input
digitalWrite(hallsensor2,HIGH);
Serial.begin(57600); //This is the setup function where the serial port is initialised,
PCMSK0 |= (1<<PCINT3); // Pin 11
PCICR |= (1<<PCIE0); // Interrupt 0
PCMSK2 |= (1<<PCINT21); // Pin 5
PCICR |= (1<<PCIE2); // Interrupt 2
MCUCR = (1<<ISC01) | (1<<ISC01); //Rising edge
attachInterrupt(1, rpm, RISING); // Interrupt 1
}
void loop ()
{
Serial.print (ButtonPress0, DEC); //Prints the number calculated above
Serial.print (" - "); //Prints the number calculated above
Serial.print (ButtonPress1, DEC); //Prints the number calculated above
Serial.print (" - "); //Prints the number calculated above
Serial.println (ButtonPress2, DEC); //Prints the number calculated above
}
This allowed me to see how many pulses it can capture.
Using the Arduino attachInterrupt() function, it seems that I get half the number of pulses.
The channel 0 is the one that uses attachInterrupt() function.
The channel 1 uses Interrupt 2 and channel 5 uses Interrupt 0.
So, technically 3 flow meter sensors could be connected to a single I/O module.
I'll create a new code that can be used to pull the flow data from RA.
I'll post when I have it completed.
Re: Flow meter Testing
Posted: Fri Jan 06, 2012 8:03 pm
by binder
That looks very interesting. I'm curious to see what the end result will be from this.
Re: Flow meter Testing
Posted: Fri Jan 06, 2012 8:16 pm
by Deckoz2302
im curious of its use...
Re: Flow meter Testing
Posted: Fri Jan 06, 2012 9:21 pm
by rimai
Well, in my case, it would be good to show me when to go clean up my reactor pump.
I have it inside the sump and it gets clogged with chaeto every now and then, reducing the flow considerably.
By monitoring the flow, it could alert me to go clean up
Re: Flow meter Testing
Posted: Fri Jan 06, 2012 10:04 pm
by Deckoz2302
I could use that on my return and my reactor pumps where/what flow meter are you using?
Re: Flow meter Testing
Posted: Fri Jan 06, 2012 10:08 pm
by rimai
I don't think it can handle return.
It's for a pretty small pipe size.
http://www.seeedstudio.com/depot/water- ... b67aed4f44
Re: Flow meter Testing
Posted: Sat Jan 07, 2012 6:10 am
by Deckoz2302
both my reactors and return use 3/8thsID tubing and reactor pump powers 2 reactors @ 185gph, and return is 350gph. any way you can tell what size it is? the site doesnt say
Re: Flow meter Testing
Posted: Sat Jan 07, 2012 11:07 am
by jsclownfish
The flow path is about 3/8" and it says it maxes out at about 475gph (30L/min). I'm using them on smaller flow lines to the skimmer and reactor. I've been thinking about splitting off the main line to measure a fraction of the main flow and then rejoining to the main, hopefully that will give a reasonable approximation of the main flow.
-Jon
Re: Flow meter Testing
Posted: Sat Jan 07, 2012 12:59 pm
by Deckoz2302
Interesting. Thanks for the info
Re: Flow meter Testing
Posted: Wed Jan 11, 2012 1:53 pm
by rimai
Here is the updated I/O PDE:
Code: Select all
#include <Wire.h>
#include <avr/wdt.h>
byte IOports[] ={
3,5,6,9,10,11};
byte IOOut[7];
volatile int Flow0 = 0;
volatile int Flow1 = 0;
volatile int Flow2 = 0;
unsigned long lastmillis=millis();
void FlowMeter1()
{
Flow1++;
}
SIGNAL(PCINT0_vect) {
Flow0++;
}
SIGNAL(PCINT2_vect) {
Flow2++;
}
void setup()
{
// Serial.begin(57600);
Wire.begin(9);
Wire.onRequest(requestEvent);
for (int a=0;a<6;a++)
{
pinMode(IOports[a],INPUT);
digitalWrite(IOports[a],HIGH); //pull up resistor
}
PCMSK0 |= (1<<PCINT3); // Pin 11
PCICR |= (1<<PCIE0); // Interrupt 0
PCMSK2 |= (1<<PCINT21); // Pin 5
PCICR |= (1<<PCIE2); // Interrupt 2
MCUCR = (1<<ISC01) | (1<<ISC01); //Rising edge
attachInterrupt(1, FlowMeter1, RISING); // Interrupt 1
wdt_enable(WDTO_1S);
}
void loop()
{
wdt_reset();
if (millis()-lastmillis>1000)
{
lastmillis=millis();
IOOut[1]=Flow0>>8;
IOOut[2]=Flow0;
IOOut[3]=Flow1>>8;
IOOut[4]=Flow1;
IOOut[5]=Flow2>>8;
IOOut[6]=Flow2;
Flow0=0;
Flow1=0;
Flow2=0;
}
}
void requestEvent() {
IOOut[0]=0;
for (int a=0;a<6;a++)
{
IOOut[0]+=digitalRead(IOports[a])<<a; //pull up resistor
}
Wire.send(IOOut,sizeof(IOOut));
}
And here is a RA PDE to test the module:
Code: Select all
#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel_Salinity.h>
#include <ReefAngel_RF.h>
#include <ReefAngel.h>
byte IOIn[7];
int Flow0;
int Flow1;
int Flow2;
char text[12];
void setup()
{
ReefAngel.Init();
}
void loop()
{
ReefAngel.Refresh();
GetFlow();
ConvertNumToString(text, Flow0, 1);
strcat(text," ");
ReefAngel.LCD.DrawText(0, 255, 10, 10, text);
ConvertNumToString(text, Flow1, 1);
strcat(text," ");
ReefAngel.LCD.DrawText(0, 255, 10, 20, text);
ConvertNumToString(text, Flow2, 1);
strcat(text," ");
ReefAngel.LCD.DrawText(0, 255, 10, 30, text);
}
void GetFlow()
{
Wire.requestFrom(9,7);
if(Wire.available())
{
for (int a=0;a<8;a++)
IOIn[a]=Wire.receive();
}
Flow0=(IOIn[1]<<8)+IOIn[2];
Flow1=(IOIn[3]<<8)+IOIn[4];
Flow2=(IOIn[5]<<8)+IOIn[6];
}
Re: Flow meter Testing
Posted: Thu Jan 12, 2012 1:58 pm
by jsclownfish
I tried this a bit today, but I couldn't get a response variable to the flow. I could see a 'fixed' reading on the screen for each one. I'm guessing I just had the lines incorrectly connected. Can you explain the wiring connections you are using with the IO?
Thanks,
-Jon
Re: Flow meter Testing
Posted: Thu Jan 12, 2012 2:24 pm
by rimai
Sorry, forgot to mention that
I was using Channel 0,1 and 5
Re: Flow meter Testing
Posted: Thu Jan 12, 2012 2:27 pm
by jsclownfish
So was the 5V line from an external source? I'm assuming the ground was wired to the unit directly.
-Jon
Re: Flow meter Testing
Posted: Thu Jan 12, 2012 2:35 pm
by rimai
Humm, I hacked my board and used a piece of wire to get 5V out.
I can post a photo later when I get home.
But, you can use external 5V just as well, with all the GNDs wired to the module, so they all have the same common ground.
Re: Flow meter Testing
Posted: Wed Jan 25, 2012 2:35 pm
by jsclownfish
I finally got around to playing with this some more last night and it worked well. I am testing it out now with the min/max function (
http://forum.reefangel.com/viewtopic.ph ... 6&start=10) on a phosban reactor to see how it works and how variable the flow is through the day. I am using this pde on the I/O because I only need one sensor to test and I don't fully understand the PCINT functions yet. A really quick assessment of the flow (gal/hr) was reasonably close but still needs some tweaking.
-Jon
Code: Select all
#include <Wire.h>; //IC2 communication
volatile int NbTopsFan; //measuring the rising edges of the signal
int calc;
int hallsensor = 3; //The pin location of the sensor
void rpm () //This is the function that the interupt calls
{
NbTopsFan++; //This function measures the rising and falling edge of the hall effect sensors signal
}
void setup() {
Wire.begin(9); // join i2c bus with address #9
Wire.onRequest(requestEvent); // register event
//flow setup
pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
attachInterrupt(1, rpm, RISING); //and the interrupt is attached
}
void loop() {
//flow calculations
NbTopsFan = 0; //Set NbTops to 0 ready for calculations
sei(); //Enables interrupts
delay (1000); //Wait 1 second
cli(); //Disable interrupts
calc = (NbTopsFan * 60 / 7.5)*.264; //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour
}
void requestEvent()
{
Wire.send(calc); //send info on flow
}
Re: Flow meter Testing
Posted: Sun Mar 18, 2012 8:48 am
by jsclownfish
I've been trying to get my IO expansion loaded up with both inputs and outputs, but I am struggling trying to modify the flow meter code originally posted. I'd like to add a couple ATOs as level warning sensors (one in the overflow and one in the water reservoir). These would be additional INPUTs from the IO (along with the 3 flow sensors). I also would like to move the buzzer alarm as an OUTPUT to the IO. I am trying to just send a number to trigger the alarm or ato state. Maybe there is a better way to do this, but I'm still pretty green at this coding and I really don't understand the interrupts, so I'm kind of tripping over myself.
Here is the test master code I am trying to test the IO...
Code: Select all
#include <ReefAngel_Features.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <ReefAngel.h>
byte IOIn[10];
int Flow0;
int Flow1;
int Flow2;
byte buzz = 0;
byte Overflow;
byte Reservoir;
void setup()
{
ReefAngel.Init();
}
void loop()
{
ReefAngel.Refresh();
GetFlow();
ReefAngel.LCD.DrawSingleMonitor(Flow0, COLOR_BLACK, 5, 10, 1);
ReefAngel.LCD.DrawSingleMonitor(Flow1, COLOR_BLACK, 5, 20, 1);
ReefAngel.LCD.DrawSingleMonitor(Flow2, COLOR_BLACK, 5, 30, 1);
ReefAngel.LCD.DrawSingleMonitor(Overflow, COLOR_BLACK, 5, 40, 1);
ReefAngel.LCD.DrawSingleMonitor(Reservoir, COLOR_BLACK, 5, 50, 1);
ReefAngel.LCD.DrawSingleMonitor(buzz, COLOR_BLACK, 5, 60, 1);
if (Overflow == 1)
{
buzz == 1;
}
else
{
buzz == 0;
}
//send data parameter package to the auxillary monitor
Wire.beginTransmission(9); // transmit to device #9
Wire.write('$'); // send the $$$
Wire.write('$');
Wire.write('$');
Wire.write(buzz);
Wire.endTransmission(); // stop transmitting
}
void GetFlow()
{
Wire.requestFrom(9,9);
if(Wire.available())
{
for (int a=0;a<10;a++)
IOIn[a]=Wire.read();
}
Flow0=(IOIn[1]<<8)+IOIn[2];
Flow1=(IOIn[3]<<8)+IOIn[4];
Flow2=(IOIn[5]<<8)+IOIn[6];
Overflow=IOIn[7];
Reservoir=IOIn[8];
}
and the test IO slave code...
Code: Select all
#include <Wire.h>
#include <avr/wdt.h>
//wire.write variable number
byte param[2];
byte IOports3;
byte IOports5;
byte IOports6;
byte IOports9;
byte IOports10;
byte IOports11;
byte Overflow=0;
byte Reservoir=0;
byte Buzzer=0;
byte IOOut[7];
volatile int Flow0 = 0;
volatile int Flow1 = 0;
volatile int Flow2 = 0;
unsigned long lastmillis=millis();
void FlowMeter1()
{
Flow1++;
}
SIGNAL(PCINT0_vect) {
Flow0++;
}
SIGNAL(PCINT2_vect) {
Flow2++;
}
void paramsend(int a)
{
param[0]=(byte)(a>>8);
param[1]=(byte)(a);
Wire.write(param,2);
}
void setup()
{
// Serial.begin(57600);
Wire.begin(9);
Wire.onRequest(requestEvent);
pinMode(IOports3,INPUT);
digitalWrite(IOports3,HIGH); //pull up resistor
pinMode(IOports5,INPUT);
digitalWrite(IOports5,HIGH); //pull up resistor
pinMode(IOports6,INPUT);
digitalWrite(IOports6,LOW); //pull up resistor
pinMode(IOports9,INPUT);
digitalWrite(IOports9,LOW); //pull up resistor
pinMode(IOports10,OUTPUT);
digitalWrite(IOports10,LOW); //pull up resistor
pinMode(IOports11,INPUT);
digitalWrite(IOports11,HIGH); //pull up resistor
PCMSK0 |= (1<<PCINT3); // Pin 11
PCICR |= (1<<PCIE0); // Interrupt 0
PCMSK2 |= (1<<PCINT21); // Pin 5
PCICR |= (1<<PCIE2); // Interrupt 2
MCUCR = (1<<ISC01) | (1<<ISC01); //Rising edge
attachInterrupt(1, FlowMeter1, RISING); // Interrupt 1
wdt_enable(WDTO_1S);
}
void loop()
{
wdt_reset();
if (millis()-lastmillis>1000)
{
lastmillis=millis();
IOOut[1]=Flow0>>8;
IOOut[2]=Flow0;
IOOut[3]=Flow1>>8;
IOOut[4]=Flow1;
IOOut[5]=Flow2>>8;
IOOut[6]=Flow2;
Flow0=0;
Flow1=0;
Flow2=0;
Overflow=0;
Reservoir=0;
}
//overflow sensor
if (digitalRead(IOports6) == HIGH)
{
Overflow == 1;
}
else
{
Overflow == 0;
}
//reservoir sensor
if (digitalRead(IOports9) == HIGH)
{
Reservoir == 1;
}
else
{
Reservoir == 0;
}
//overtemp alarm
if (Buzzer = 1)
{
digitalWrite(IOports10,HIGH);
}
else
{
digitalWrite(IOports10,LOW);
}
}
void requestEvent() {
paramsend(Flow0);
paramsend(Flow1);
paramsend(Flow2);
Wire.write(Overflow);
Wire.write(Reservoir);
}
void receiveEvent(int howMany)
{
if (howMany==4) // Our custom protocol is 4 bytes
{
byte cmd1,cmd2,cmd3,cmd4;
cmd1=Wire.read();
cmd2=Wire.read();
cmd3=Wire.read();
cmd4=Wire.read();
if (cmd1=='$' && cmd2=='$' && cmd3=='$') // the first 3 bytes of the custom protocol are $$$ to ensure it's coming from RA
{
Buzzer=cmd4;
}
}
else
for (int a=0;a<howMany;a++)
Wire.read(); // if the number of bytes is not 4, discard everything
}
right now I get a screen like this:
0
0
0
255
255
0
and no response. Since it isn't hooked up to any sensors the buzzer is just triggered by a the ato singal in the master (kind of a circular aresponse, but it's jsut a test) I've had success sending info before, but I'm getting confused with this one. Anyhelp would be greatly appreciated.
-Jon
Re: Flow meter Testing
Posted: Sun Mar 18, 2012 11:55 am
by rimai
Try this:
Code: Select all
#include <Wire.h>
#include <avr/wdt.h>
byte Overflow=0;
byte Reservoir=0;
byte Buzzer=0;
byte IOOut[9];
volatile int Flow0 = 0;
volatile int Flow1 = 0;
volatile int Flow2 = 0;
unsigned long lastmillis=millis();
void FlowMeter1()
{
Flow1++;
}
SIGNAL(PCINT0_vect) {
Flow0++;
}
SIGNAL(PCINT2_vect) {
Flow2++;
}
void setup()
{
// Serial.begin(57600);
Wire.begin(9);
Wire.onRequest(requestEvent);
pinMode(3,INPUT);
digitalWrite(3,HIGH); //pull up resistor
pinMode(5,INPUT);
digitalWrite(5,HIGH); //pull up resistor
pinMode(6,INPUT);
digitalWrite(6,HIGH); //pull up resistor
pinMode(9,INPUT);
digitalWrite(9,HIGH); //pull up resistor
pinMode(10,OUTPUT);
digitalWrite(10,LOW); //pull up resistor
pinMode(11,INPUT);
digitalWrite(11,HIGH); //pull up resistor
PCMSK0 |= (1<<PCINT3); // Pin 11
PCICR |= (1<<PCIE0); // Interrupt 0
PCMSK2 |= (1<<PCINT21); // Pin 5
PCICR |= (1<<PCIE2); // Interrupt 2
MCUCR = (1<<ISC01) | (1<<ISC01); //Rising edge
attachInterrupt(1, FlowMeter1, RISING); // Interrupt 1
wdt_enable(WDTO_1S);
}
void loop()
{
wdt_reset();
if (millis()-lastmillis>1000)
{
lastmillis=millis();
IOOut[0]=0;
IOOut[1]=Flow0>>8;
IOOut[2]=Flow0;
IOOut[3]=Flow1>>8;
IOOut[4]=Flow1;
IOOut[5]=Flow2>>8;
IOOut[6]=Flow2;
Flow0=0;
Flow1=0;
Flow2=0;
}
//overflow sensor
Overflow = digitalRead(6);
//reservoir sensor
Reservoir = digitalRead(9);
IOOut[7]=Overflow;
IOOut[8]=Reservoir;
//overtemp alarm
digitalWrite(10,Buzzer);
}
void requestEvent() {
Wire.write(IOOut,sizeof(IOOut));
}
void receiveEvent(int howMany)
{
if (howMany==4) // Our custom protocol is 4 bytes
{
byte cmd1,cmd2,cmd3,cmd4;
cmd1=Wire.read();
cmd2=Wire.read();
cmd3=Wire.read();
cmd4=Wire.read();
if (cmd1=='$' && cmd2=='$' && cmd3=='$') // the first 3 bytes of the custom protocol are $$$ to ensure it's coming from RA
{
Buzzer=cmd4;
}
}
else
for (int a=0;a<howMany;a++)
Wire.read(); // if the number of bytes is not 4, discard everything
}
Re: Flow meter Testing
Posted: Fri Mar 29, 2013 4:00 pm
by jsclownfish
FYI, I noticed you can buy these at
http://www.adafruit.com/products/828 now. I really like being able to see the 'plumbing' is working properly on my various lines. The more powerful lines now just have a PVC T connector in place to let most of the water bypass, but keep the meter moving off the feed. It's not really accurate for flow rates, but I can definitely see the pumps are working and if they start to slow down.
-Jon
Re: Flow meter Testing
Posted: Wed Nov 20, 2013 9:48 am
by jsclownfish
I would like to add a few more of the newer large flow meters that are out there, but I don't really understand the pin change interrupts and registers. Can the I/O handle more flow meters (5 total) or do I need another I/O module? How would I modify the code above?
Thanks,
Jon
Re: Flow meter Testing
Posted: Wed Nov 20, 2013 10:33 am
by rimai
I think the module only handles 3 interrupts at the most
Re: Flow meter Testing
Posted: Sun Nov 24, 2013 9:15 am
by Mike S
Very interesting. I'd love to have one for the inlet of my calcium reactor.
Re: Flow meter Testing
Posted: Mon Feb 10, 2014 2:01 pm
by jsclownfish
Hi all,
A quick FYI...
I use small G1/2 flow sensors on an IO expansion module on my system to monitor flow from the various pumps. They work well to provide some data that water is flowing properly and there are no clogs are major flow issues. The downside of these is they are kind of small and in my experience they can stop working after about a year. On the positive, they are relatively cheap and I just use a T on the return lines to let any extra flow bypass the sensor. It also provides some back-up in case the flow meter got clogged (although that has never happened).
Anyway, I went to order a couple new flow sensors
http://www.seeedstudio.com and was happy to see there are much larger versions available now. They can handle larger flow rates (up to 120L/min for a G1-1/4) and may be useful for larger flow lines. Here is a pic of some of the new ones I just got in...
Re: Flow meter Testing
Posted: Sat Nov 01, 2014 2:13 pm
by Damion
Has any one tried something like this?
puratekdotcom/products/insight-monitor-controller/accessories/flow-sensors
They seem more reliable and less likely to stop flow upon failure.
Granted, they don't tell you flow rate, but tell you if there is flow. This is more suited for a return pump or higher flow pump.
They work with a little "paddle" sticking in the flow stream and that paddle is connected to a micro switch.
Somewhere on his site I saw a non-intrusive level sensor, which seemed cool as well.
Re: Flow meter Testing
Posted: Mon Nov 10, 2014 1:17 pm
by jsclownfish
Those look interesting. I haven't had any problems with flow stopping upon failure. When they wear out or get stuck the water moves around the little paddlewheel pretty freely.
-Jon
Re: Flow meter Testing
Posted: Fri Mar 06, 2015 10:25 am
by ewaldsreef
If the readings are acurate this could be a very helpful add on. If you had a sensor on your return pump you could monitor for efficiency. I do aquarium maintenance for a living. There are so many return pumps out there working at lower capacity because of debris on the impeller. Also so many tanks with UVs and chillers that are running way to much or to little flow to be effective.
The big question is reliability and accuracy.
Re: Flow meter Testing
Posted: Thu Mar 19, 2015 5:23 pm
by jsclownfish
I use a number of them to monitor flow, but I don't really count on accuracy to determine efficiency of the pumps, just that the flow is working and in the general range I expect.
Jon
Re: Flow meter Testing
Posted: Mon Mar 23, 2015 8:54 am
by ewaldsreef
Jon
I was going to add one to my RO to monitor water usage to let me know when to replace filters. Do you think it would be accurate enough to accomplish this?