I've seen other forum posts on this subject, but I'm still new to programming and the everybody's code is really confusing to me.
So correct me if I'm wrong - In order to read the number of pulses the flow meter gives out when a fluid is running through it, you need a program that counts each time the Hall Effect sensor goes HIGH, right? If that's the case then why do you need to use an 'interrupt function'? This is where I get lost...
I'm trying to read two flow meters with an Arduino Uno, but I think what's messing me up is the interrupt function. Do I need separate interrupt functions for each flow sensor. To my understanding there are 3 interrupt pins on the Arduino Uno. One of these interrupt pins is digital pin 2, which is the one that works with one sensor, but when I try to add another interrupt function I can't read either flow meters. Any help or advice is very appreciated.
The code and flow meters I'm trying to use are from Liquid Flow Meter - Plastic 1/2 NPS Threaded : ID 828 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits
This code works with one flow meter with its signal pin connected to digital pin 2:
/**********************************************************
This is example code for using the Adafruit liquid flow meters.
Tested and works great with the Adafruit plastic and brass meters
------> http://www.adafruit.com/products/828
------> http://www.adafruit.com/products/833
Connect the red wire to +5V,
the black wire to common ground
and the yellow sensor wire to pin #2
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution
**********************************************************/
// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 2
// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
uint8_t x = digitalRead(FLOWSENSORPIN);
if (x == lastflowpinstate) {
lastflowratetimer++;
return; // nothing changed!
}
if (x == HIGH) {
//low to high transition!
pulses++;
}
lastflowpinstate = x;
flowrate = 1000.0;
flowrate /= lastflowratetimer; // in hertz
lastflowratetimer = 0;
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
}
void setup() {
Serial.begin(9600);
Serial.print("Flow sensor test!");
pinMode(FLOWSENSORPIN, INPUT);
digitalWrite(FLOWSENSORPIN, HIGH);
lastflowpinstate = digitalRead(FLOWSENSORPIN);
useInterrupt(true);
}
void loop() // run over and over again
{
float liters = pulses;
liters /= 7.5;
liters /= 60.0;
Serial.print(liters); Serial.println(" Liters");
delay(100);
}
This is the code I tried modifying to get it to work with two flow meters, but only the flow meter using pin 2 works. As you may see, I basically just double everything that the 1st flow meter was using and added '2' to the end:
#define FLOWSENSORPIN 2
#define FLOWSENSORPIN2 3
// count how many pulses!
volatile uint16_t pulses = 0;
volatile uint16_t pulses2 = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
volatile uint8_t lastflowpinstate2;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
volatile uint32_t lastflowratetimer2 = 0;
// and use that to calculate a flow rate
volatile float flowrate;
volatile float flowrate2;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
uint8_t x = digitalRead(FLOWSENSORPIN);
if (x == lastflowpinstate) {
lastflowratetimer++;
return; // nothing changed!
}
if (x == HIGH) {
//low to high transition!
pulses++;
}
lastflowpinstate = x;
flowrate = 1000.0;
flowrate /= lastflowratetimer; // in hertz
lastflowratetimer = 0;
}
SIGNAL(TIMER2_COMPA_vect) {
uint8_t x2 = digitalRead(FLOWSENSORPIN2);
if (x2 == lastflowpinstate2) {
lastflowratetimer2++;
return; // nothing changed!
}
if (x2 == HIGH) {
//low to high transition!
pulses2++;
}
lastflowpinstate2 = x2;
flowrate2 = 1000.0;
flowrate2 /= lastflowratetimer2; // in hertz
lastflowratetimer2 = 0;
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
}
void setup()
{
Serial.begin(9600);
pinMode(FLOWSENSORPIN, INPUT);
digitalWrite(FLOWSENSORPIN, HIGH);
lastflowpinstate = digitalRead(FLOWSENSORPIN);
pinMode(FLOWSENSORPIN2, INPUT);
digitalWrite(FLOWSENSORPIN2, HIGH);
lastflowpinstate2 = digitalRead(FLOWSENSORPIN2);
useInterrupt(true);
}
void loop() {
float liters = pulses;
liters /= 7.5;
liters /= 60.0;
float liters2 = pulses2;
liters2 /= 7.5;
liters2 /= 60.0;
//Serial.println(level);
//Serial.print(liters); Serial.println(" Liters");
Serial.print(liters2); Serial.println(" Liters");
delay(100);
}
I'm guessing the problem has something to do with this block of code?
SIGNAL(TIMER2_COMPA_vect) {
uint8_t x2 = digitalRead(FLOWSENSORPIN2);
if (x2 == lastflowpinstate2) {
lastflowratetimer2++;
return; // nothing changed!
}
if (x2 == HIGH) {
//low to high transition!
pulses2++;
}
lastflowpinstate2 = x2;
flowrate2 = 1000.0;
flowrate2 /= lastflowratetimer2; // in hertz
lastflowratetimer2 = 0;
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
}
If you made it this far through my giant mess of problems then I appreciate the time you took to at least give it a shot to solve. Thanks!