LCD 16x2 refresh and flow meter

Hello everybody,

First, I’m French and I’m a beginner with arduino (Since this morning !!)

Last week I’ve received my starterkit and a flow meter (hall effect sensor, https://fr.rs-online.com/web/p/indicateurs-interrupteurs-et-capteurs-de-debit/4468315/?searchTerm=446-8315&relevancy-data=636F3D3126696E3D4931384E525353746F636B4E756D6265724D504E266C753D656E266D6D3D6D61746368616C6C26706D3D5E5C647B337D5B5C732D2F255C2E2C5D5C647B332C347D2426706F3D313426736E3D592673743D52535F53544F434B5F4E554D4245522677633D4E4F4E45267573743D3434362D3833313526 )

Today I’ve tried to connect my flow meter and a 16x2 LCD to the arduino UNO. It’s a success and working but I’ve encountered some problems.

Digit on the LCD (value of the flow) are not refresh aright.

Below my code, for you, where is the problem ?

if I’ve understood Arduino’s programming, for me the problem is located in the “void loop” but I don’t see where…

And finally, what do you think about my code ?

/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
#include <LiquidCrystal.h>


// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(7, 6, 8, 9, 10, 11);

volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_min; // Calculated litres/min
unsigned char flowsensor = 2; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
   flow_frequency++;
}
void setup()
{
  lcd.begin(16, 2); // Print a message to the LCD.
   lcd.print("Débitmètre LM");
   lcd.setCursor(9,1);
   lcd.print("l/min");
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;
}
void loop ()
{
   currentTime = millis();
   // Every second, calculate and print litres/min
   if(currentTime >= (cloopTime + 1000))
   {
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_min = flow_frequency; // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/min
      flow_frequency = 0; // Reset Counter
      Serial.print(l_min, DEC); // Print L/min
      Serial.println(" L/min");
      lcd.setCursor(0,1);
      lcd.print(l_min);
   }
}

Thx for you response and sorry if my english it’s not the best :wink:

  if(currentTime >= (cloopTime + 1000))will cause a glitch when millis() rolls over back to zero. If you use
if (currentTime - cloopTime >= 1000)the problem will not occur.

What do you mean by not refreshing correctly?

Generally speaking you have to clear whatever is on the display before printing new information, otherwise it gets overlapped. Could this be the issue you're having?

after the "if" add

lcd.clear();
lcd.setCursor(0, 0);

gpop1:
after the "if" add

lcd.clear();
lcd.setCursor(0, 0);

A clear command takes a long time and the screen 'blinks' visibly. Better to fill with spaces

lcd.setCursor(0, 0);
lcd.print("                    ");
lcd.print(l_min);

Or even better, the sprintf function. I'm not 100% sure about the syntax but it should be along the lines of:

char buffer[20]
sprintf(buffer, "Flow rate: %3", l_min);

  lcd.setCursor (0,0);
  lcd.print (buffer);

May God be with you all.

Hello Guys !!

Thanks your quick replies !!

I used

lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(l_min);

And it’s working good but the complete line is blanking and “l/min” disappear but it’s not a problem.

I have an another question, if I want to connect a second flow meter. Do you think I can use the following code ?

/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
#include <LiquidCrystal.h>


// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(7, 6, 8, 9, 10, 11);

volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_min; // Calculated litres/min
unsigned int l_min2; // Calculated litres/min
unsigned char flowsensor = 2; // Sensor 1 Input
unsigned char flowsensor = 4; // Sensor 2 Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
   flow_frequency++;
}
void setup()
{
  lcd.begin(16, 2); // Print a message to the LCD.
   lcd.print("CW Flow"); // CW for Cold water
   lcd.setCursor(0,1);
   lcd.print("HW Flow"); // HW for Hot water
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;
}
void loop ()
{
   currentTime = millis();
   // Every second, calculate and print litres/min
   if (currentTime >= (cloopTime + 1000))
   {
     
      lcd.setCursor(8,0);
      lcd.print("             ");
      lcd.print(l_min);
      lcd.setCursor(8,1);
      lcd.print("             ");
      lcd.print(l_min2);
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_min = flow_frequency; // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/min
      l_min2 = flow_frequency2
      flow_frequency = 0; // Reset Counter
      flow_frequency2 = 0;
      Serial.print(l_min, DEC); // Print L/min
      Serial.print(l_min2, DEC);
      lcd.setCursor(8,0);
      lcd.print(l_min);
      lcd.setCursor(8,1)
      lcd.print(l_min2)
   }
}

If you think that my code is too complicated, say it and I will try to make it more simple.

It's my first code and I've not good automation. Have you some books to advise me in order to learn arduino ?

I know there is some tutorials but I prefer to work with books.

Thanks you guys !!

I have an another question, if I want to connect a second flow meter. Do you think I can use the following code ?

No. You will need two interrupts on two different pins.

//pulse counts changed within count_ISR's
volatile unsigned int count1;
volatile unsigned int count2;

//variables for protected copies of counts
unsigned int copyCount1;
unsigned int copyCount2;

void count1_ISR()
{
  count1++;
}

void count2_ISR()
{
  count2++;
}
void setup() {

  Serial.begin(115200);

  /*
  //send test signal to interrupt pins
  analogWrite(5,127);//980 hz timer 0 jumper pin 5 to pin 2
  analogWrite(9,127);//490 hz timer 2 jumper pin 9 to pin 3
  */
  attachInterrupt(0, count1_ISR, RISING); //pin2 (Atmega328)
  attachInterrupt(1, count2_ISR, RISING); //pin3 (Atmega328)
  
}

void loop() {
  static unsigned long lastSecond;
  if (micros() - lastSecond >= 1000000L)
  {
    lastSecond += 1000000;
    getCount();
    Serial.println(copyCount1);
    Serial.println(copyCount2);
    Serial.println();
  }

}
unsigned int getCount()
{
  noInterrupts();
  copyCount1 = count1;
  count1 = 0;
  copyCount2 = count2;
  count2 = 0;
  interrupts();
}

ivan59200:
Hello Guys !!

Thanks your quick replies !!

I used

lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(l_min);

And it’s working good but the complete line is blanking and “l/min” disappear but it’s not a problem.

I have an another question, if I want to connect a second flow meter. Do you think I can use the following code ?

/*

YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins

LiquidCrystal lcd(7, 6, 8, 9, 10, 11);

volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_min; // Calculated litres/min
unsigned int l_min2; // Calculated litres/min
unsigned char flowsensor = 2; // Sensor 1 Input
unsigned char flowsensor = 4; // Sensor 2 Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
  flow_frequency++;
}
void setup()
{
  lcd.begin(16, 2); // Print a message to the LCD.
  lcd.print(“CW Flow”); // CW for Cold water
  lcd.setCursor(0,1);
  lcd.print(“HW Flow”); // HW for Hot water
  pinMode(flowsensor, INPUT);
  digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
  Serial.begin(9600);
  attachInterrupt(0, flow, RISING); // Setup Interrupt
  sei(); // Enable interrupts
  currentTime = millis();
  cloopTime = currentTime;
}
void loop ()
{
  currentTime = millis();
  // Every second, calculate and print litres/min
  if (currentTime >= (cloopTime + 1000))
  {
   
      lcd.setCursor(8,0);
      lcd.print("            “);
      lcd.print(l_min);
      lcd.setCursor(8,1);
      lcd.print(”            ");
      lcd.print(l_min2);
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_min = flow_frequency; // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/min
      l_min2 = flow_frequency2
      flow_frequency = 0; // Reset Counter
      flow_frequency2 = 0;
      Serial.print(l_min, DEC); // Print L/min
      Serial.print(l_min2, DEC);
      lcd.setCursor(8,0);
      lcd.print(l_min);
      lcd.setCursor(8,1)
      lcd.print(l_min2)
  }
}

Regarding the screen this should fix your issue:

lcd.setCursor(0, 0);
lcd.print("L/min:          ")
lcd.setCursor(8, 0);
lcd.print(l_min);

How it works:

lcd.setCursor(0, 0);
lcd.print("L/min:          ")

Your basically cleaning the screen by writing the full 16 characters with text on line 0.

lcd.setCursor(8, 0);
lcd.print(l_min);

Now you write the value from the flowmeter, but you command the lcd to start writting on line 0, character 8. So the text "L/min: " stays on screen.

Regarding the flow-meter, depends how fast your pulses are.

If they are slow and you have no delay functions on your code you can poll them.
If they are fast or you have delays in your code, you should use an interrupt. There are 3 available from the UNO. Int 0 (D2), Int 1 (D3) and ICP1 (D8).
If they are very fast (>1Khz), only the ICP1 should be used, in conjunction with timer 1. This is useful for frequency or RPM measurement (in general flowmeters are not that fast)

The code/tips from cattledog should be a good start