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. :D

-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?