Flow Meter

Ive made the flow meter for a work project and I'm going to use the LCD to give me a read out of L/MIN.

Spent a few hours today getting a read out.

I have a read out from the flow meter using this code but this code doesn't have the LCD read out added

volatile int NbTopsFan;            //measuring the rising edges of the signal
int Calc; 
int hallsensor = 2;                //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 signal
}                                  //The setup() method runs once, when the sketch starts

void setup() 

{
 pinMode(hallsensor, INPUT);       //initializes digital pin 2 as an input
 Serial.begin(9600);               //This is the setup function where the serial port is initialised
 attachInterrupt(0, rpm, RISING);  //and the interrupt is attached
}
                                   // the loop() method runs over and over again
                                   // as long as the Arduino has power
void loop () 
{
 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);    //(Pulse frequency x 60) / 7.5Q = flow rate in L/hour
 Serial.print (Calc, DEC);         //Prints the number calculated above
 Serial.print (" L/hour\r\n");     //Prints "L/hour" and returns a new line
}

I want to add some of this LCD read out to the code above

/*
This tutorial Demonstrates the use of Flow Sensor
 Web: blog.circuits4you.com
  The circuit:
Flow Sensor Connections
Yellow --- Pin 6
Red    --- +5V
Black  --- GND     
      
LCD Connections      
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 1K resistor:
 * One end to ground
 * Another end to LCD VO pin (pin 3)
 
 This example code is in the public domain.
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

volatile int FlowPulse; //measuring the rising edges of the signal
int Calc;                               
int flowsensor = 6;    //The pin location of the sensor


void setup() {
     
   pinMode(flowsensor, INPUT); //initializes digital pin 2 as an input
   Serial.begin(9600);         //This is the setup function where the serial port is initialised,
   attachInterrupt(0, rpm, RISING); //and the interrupt is attached
   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(0, 1);
  lcd.print("Flow Meter");
}

void loop() {
     
 FlowPulse = 0;      //Set NbTops to 0 ready for calculations
 sei();            //Enables interrupts
 delay (1000);      //Wait 1 second
 cli();            //Disable interrupts
 Calc = (FlowPulse * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
 Serial.print (Calc, DEC); //Prints the number calculated above
 Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line
  
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 2);
  lcd.print(Calc,DEC);   // print the Flow Rate
  lcd.print(" L/hour");
}

void rpm ()     //This is the function that the interupt calls 
{ 
  FlowPulse++;  //This function measures the rising and falling edge of the hall effect sensors signal
}

It says that the PIN read out is pin 6 but I cant a read out from pin 6 at all - I can only get a read out from pin 2.

The LCD also uses Pin 2 can I put two connections to pin 2 of the Arduino?

Can I connect the LCD display to a different pin and not use PIN 2?

I had a conflict with the LCD and the readout of the Meter as both was set to PIN 2.

You can move the LCD wire called on pin 2 to another pin, say 6, so long as you declare it in the setup command, e.g.

LiquidCrystal lcd(12, 11, 5, 4, 3, 6);

I would be very suss about the second bit of code as I believe putting the hall sensor on pin 6 is a bad idea.

I have set the LCD to 6.

I can get a read out on the serial monitor of the flow rate but on the LCD it just gets stuck on "Flow Meter"

It should change to L/Hour

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 6);

volatile int FlowPulse; //measuring the rising edges of the signal
int Calc;                               
int flowsensor = 2;    //The pin location of the sensor


void setup() {
     
   pinMode(flowsensor, INPUT); //initializes digital pin 2 as an input
   Serial.begin(9600);         //This is the setup function where the serial port is initialised,
   attachInterrupt(0, rpm, RISING); //and the interrupt is attached
   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 6);
  // Print a message to the LCD.
  lcd.setCursor(0, 1);
  lcd.print("Flow Meter");
}

void loop() {
     
 FlowPulse = 0;      //Set NbTops to 0 ready for calculations
 sei();            //Enables interrupts
 delay (1000);      //Wait 1 second
 cli();            //Disable interrupts
 Calc = (FlowPulse * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
 Serial.print (Calc, DEC); //Prints the number calculated above
 Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line
  
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 2);
  lcd.print(Calc,DEC);   // print the Flow Rate
  lcd.print(" L/hour");
}

void rpm ()     //This is the function that the interupt calls 
{ 
  FlowPulse++;  //This function measures the rising and falling edge of the hall effect sensors signal
} ]

Ive got it working now :-).

Just need to work out how to calculate the flow rate, I want a minimum of 4L per second

Working code

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 6);

volatile int FlowPulse; //measuring the rising edges of the signal
int Calc;                               
int flowsensor = 2;    //The pin location of the sensor


void setup() {
     
   pinMode(flowsensor, INPUT); //initializes digital pin 2 as an input
   Serial.begin(9600);         //This is the setup function where the serial port is initialised,
   attachInterrupt(0, rpm, RISING); //and the interrupt is attached
   
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 6);
  // Print a message to the LCD.
  lcd.setCursor(1,0);
  lcd.print("Flow Rate Meter");
  
  delay(1000);// wait 500ms                                      // Delay to read text
 lcd.clear(); // clear LCD display

}

void loop() {
     
 FlowPulse = 0;      //Set NbTops to 0 ready for calculations
 sei();            //Enables interrupts
 delay (1000);      //Wait 1 second
 cli();            //Disable interrupts
 Calc = (FlowPulse * 6/ 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
 Serial.print (Calc, DEC); //Prints the number calculated above
 Serial.print (" L/Minn"); //Prints "L/hour" and returns a  new line
  
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.begin(16,6);
  lcd.setCursor(1, 0);
  lcd.print(Calc, DEC);   // print the Flow Rate
  lcd.print("    L/Min");
}

void rpm ()     //This is the function that the interupt calls 
{ 
  FlowPulse++;  //This function measures the rising and falling edge of the hall effect sensors signal
}
 sei();            //Enables interrupts
 delay (1000);      //Wait 1 second
 cli();            //Disable interrupts

That is the crappiest way possible to read interrupts. If you are going to do nothing except wait for some other code to count state changes, you might as well forget interrupts and just use a while loop here watching for state changes.

 cli();            //Disable interrupts
 Calc = (FlowPulse * 6/ 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
 Serial.print (Calc, DEC); //Prints the number calculated above
 Serial.print (" L/Minn"); //Prints "L/hour" and returns a  new line

There is a word that describes people that do Serial ouput with interrupts disabled. 6 letters, starts with s, rhymes with stupid.

I didn't write the code :-(.

Are you saying to delete one of those lines?

Are you saying to delete one of those lines?

I'm saying that you should not do Serial.print() after disabling interrupts.

I didn't write the code

Well, whoever did should be ashamed of themselves.

How can I correct this then?

englewood:
How can I correct this then?

What is it you want to change?

Since the Arduino is doing nothing during the delay(), except dealing with interrupts, using interrupts is pointless. During that one second, using a while statement and millis() to loop for one second, read the pin over and over. Count the number of times the pin is HIGH when it was LOW last time. Look at the state change detection example.

Then get rid of all the crap dealing with interrupts.

I took the Interrupts out and it went crazy :-0

I took the Interrupts out and it went crazy

So did I when you didn't post your code.

How can I correct this then?

Here is how to read and printout interrupt counts every second without delays. The reading of volatile variables from within an ISR is protected and the Serial printing does not occur when interrupts are disabled.

volatile unsigned long count = 0;
unsigned long copyCount = 0;
unsigned long lastRead = 0;
unsigned long interval = 1000;

void setup()
{
  Serial.begin(115200);
  Serial.println("start...");

  attachInterrupt(0, isrCount, RISING); //interrupt signal to pin2
}

void loop()
{
  if (millis() - lastRead >= interval) //read interrupt count every second
  {
    lastRead  += interval;
    noInterrupts(); //cli()
    copyCount = count;
    count = 0;
    interrupts(); //sei()

    Serial.println(copyCount);
  }
}

void isrCount()
{
  count++;
}

Here is how to read and printout interrupt counts every second without delays.

That's much better. On the other hand, the Arduino is still doing nothing for most of the time, so interrupts really are not necessary.

Strip out what you don't need, rather than re-invent the wheel. An hour is usually a long time, and you might want to re-think how you present the data.

If you want the rate, you need to (digitally) low-pass filter the number of counts per second (although
second may not be the best granularity depending on the pulse rates involved).

Well I have my flow meter working and works very well :slight_smile:

Can I incorporate a 9V battery monitor to print the battery level on the LCD.

Is it possible to run 2 inputs to PIN 2 on the Arduino?

I have the out put of the flow meter going to PIN 2 but I've also seen that the battery monitor also goes to PIN 2

Can I incorporate a 9V battery monitor to print the battery level on the LCD.

With a voltage divider, yes. You can't supply 9V to an analog pin without damaging the Arduino.

Is it possible to run 2 inputs to PIN 2 on the Arduino?

As long as you don't care which device you are reading from.

I have the out put of the flow meter going to PIN 2 but I've also seen that the battery monitor also goes to PIN 2

It may not need to.

Hello Paul,

Im running a 9v battery through a 5V regulator to power the arduino.

I have the flow switch reading from PIN 2

englewood:
Hello Paul,

Im running a 9v battery through a 5V regulator to power the arduino.

I have the flow switch reading from PIN 2

So, what's the problem?

How do you expect to read the voltage of the battery? The Arduino is downstream of the regulator. All it will see is the regulated voltage.