user48700: There is a problem with code related in link Interrupts Problem with Flow sensor. Code is working but when I stop the pumps, flow value on lcd is frozen until I reset the arduino. And when I start the pumps, flowmeter shows firstly 0.54 value, then begin to show real values. But always 0.54 down or up ( if flow is 5 lt/min, lcd show sometimes 5 lt/min, 5+0.54 lt/min or 5-0.54 lt/min ). When there are no oil flow into flow sensor, value of flow have fixed value that last readings. Could you help me ?
 #include <Wire.h> //I2C lib
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int pot_pin = A0;
const int pump_pwm = 3;

const int resetButton = 11;
byte press_pin = A1;

//flowmeter parameters
int flowPin = 2;  // input pin on arduino D2

volatile double flowRate;   // value intented to calculate
volatile double flowR; // flow value in lt
volatile double totalFlow; // total output of flow from system

byte sensorInterrupt = 0; // interrupt 0 on D2 pin Arduino Nano

volatile int count; ////integer needs to be set as volatile to ensure it updates correctly during the interrupt process. 

int pot_init= 0;
int pump_init= 0;
int percentValue =0;


unsigned long previous_read;
void setup() {


  pinMode(resetButton, INPUT);
  digitalWrite(resetButton, HIGH);

  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  Serial.begin(9600); 

  pinMode( flowPin,INPUT); // Set D2 pin as an input

  attachInterrupt(sensorInterrupt,Flow,RISING); // Configures interrupt 0 ( pin D2 on Arduino Nano ) to run function "Flow" 
}
void flow_control(void) {

  // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");        
    Serial.print(totalFlow/1000);
    Serial.println("L");

 if(digitalRead(resetButton) == LOW)
  {
    totalFlow = 0;
    lcd.setCursor(0, 3);
    lcd.print("Resetting....        ");



}

else {
 lcd.setCursor(0,3);
  lcd.print("Total: "); 
  lcd.setCursor(7,3);
  lcd.print(totalFlow/1000);
  lcd.print(" lt");

}
  lcd.setCursor(0,2);
  lcd.print("Flow: ");
    lcd.setCursor(6,2);
  lcd.print(flowRate);
  lcd.print(" lt/min");



}

void Flow(void) 
{
  count++; // every time this function is called, increment  "count" by 1

  if(millis() -  previous_read > 1000){
    noInterrupts(); // disable interrupts on arduino nano
    int local_count = count;
    count=0;
    interrupts(); // enables interrupts on arduino nano
    previous_read += 1000;

  flowR = (local_count*8.93);   // 112 pulse/lt 423.84 pulse /gallon 
  flowRate= flowR*60;     // convert seconds to minutes, new unit is ml/minutes
  flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes

  totalFlow += flowR;
 //process flowrate based on local_count




  //calculation for flowmeter 


  }
}

void loop() {

  pressure_cal(); 
  pump_control();
  flow_control();

}



void pressure_cal(void) {

  float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
  float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V

  // calibration 
  float bar = psi*(0.0689475729);           // Conversion PSI to BAR


  lcd.setCursor (0,1);
  lcd.print (psi);
  lcd.print (" PSI");

  lcd.setCursor ( 10,1);
  lcd.print(bar);
  lcd.print( " BAR");

  //lcd.setCursor(17,1);
  //lcd.print(sensorVoltage);



  Serial.print("\t Sensor Value = ");
  Serial.print(sensorVoltage);
  Serial.print("\t Bar = ");
  Serial.print(bar);
  Serial.print("\t PSI = ");
  Serial.println(psi);

  delay (100);
}

void pump_control(void)

{

  // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 50, 230);  //  duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 50, 230,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);

  lcd.setCursor(2,0);         
  lcd.print("Speed: ");
  lcd.setCursor(8,0);         
  lcd.print("%");         
  lcd.setCursor(9,0);         
  lcd.print(percentValue); 
  lcd.print("     ");         

 //  delay after the last reading:
  delay(10);

}


user7508: 
if (millis() -  previous_read > 1000) { [...] previous_read += 1000; [...] }

The code inside this block is obviously meant to be executed every
second. However, since this belongs to the interrupt handler, it only
has a chance to execute when the flow-meter sends interrupts. If the
flow is zero or very weak, this will not execute often enough.

flowmeter shows firstly 0.54 value

It is no coincidence that 0.54 is what you get when count == 1.
The piece of code above should be moved to the main loop(), or to a
function called from loop(). This way it will execute consistently
irrespective of whether there is some flow or not, which is the only way
to reliably read a zero flow. Note that for better timing consistency
you should avoid doing something like...

delay(100);

Don't do this. Instead, use the same trick as above:
if (millis() -  previous_pressure_print > 100) {
    previous_pressure_print += 100;
    pressure_cal();
}


48700: <p>There is a problem with code related in link <a href="https://arduino.stackexchange.com/questions/55175/interrupts-problem-with-flow-sensor">Interrupts Problem with Flow sensor</a>. Code is working but when I stop the pumps, flow value on lcd is frozen until I reset the arduino. And when I start the pumps, flowmeter shows firstly 0.54 value, then begin to show real values. But always 0.54 down or up ( if flow is 5 lt/min, lcd show sometimes 5 lt/min, 5+0.54 lt/min or 5-0.54 lt/min ). When there are no oil flow into flow sensor, value of flow have fixed value that last readings. Could you help me ?</p>

<pre><code> #include &lt;Wire.h&gt; //I2C lib
#include &lt;LCD.h&gt;
#include &lt;LiquidCrystal_I2C.h&gt;
 // LCD lib
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

const int pot_pin = A0;
const int pump_pwm = 3;

const int resetButton = 11;
byte press_pin = A1;

//flowmeter parameters
int flowPin = 2;  // input pin on arduino D2

volatile double flowRate;   // value intented to calculate
volatile double flowR; // flow value in lt
volatile double totalFlow; // total output of flow from system

byte sensorInterrupt = 0; // interrupt 0 on D2 pin Arduino Nano

volatile int count; ////integer needs to be set as volatile to ensure it updates correctly during the interrupt process. 

int pot_init= 0;
int pump_init= 0;
int percentValue =0;


unsigned long previous_read;
void setup() {


  pinMode(resetButton, INPUT);
  digitalWrite(resetButton, HIGH);

  lcd.begin(20,4);  // A4 - A5 connection SDA - SCL
  lcd.backlight();
  Serial.begin(9600); 

  pinMode( flowPin,INPUT); // Set D2 pin as an input

  attachInterrupt(sensorInterrupt,Flow,RISING); // Configures interrupt 0 ( pin D2 on Arduino Nano ) to run function "Flow" 
}
void flow_control(void) {

  // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print("L/min");
    Serial.print("\t");       // Print tab space

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");        
    Serial.print(totalFlow/1000);
    Serial.println("L");

 if(digitalRead(resetButton) == LOW)
  {
    totalFlow = 0;
    lcd.setCursor(0, 3);
    lcd.print("Resetting....        ");



}

else {
 lcd.setCursor(0,3);
  lcd.print("Total: "); 
  lcd.setCursor(7,3);
  lcd.print(totalFlow/1000);
  lcd.print(" lt");

}
  lcd.setCursor(0,2);
  lcd.print("Flow: ");
    lcd.setCursor(6,2);
  lcd.print(flowRate);
  lcd.print(" lt/min");



}

void Flow(void) 
{
  count++; // every time this function is called, increment  "count" by 1

  if(millis() -  previous_read &gt; 1000){
    noInterrupts(); // disable interrupts on arduino nano
    int local_count = count;
    count=0;
    interrupts(); // enables interrupts on arduino nano
    previous_read += 1000;

  flowR = (local_count*8.93);   // 112 pulse/lt 423.84 pulse /gallon 
  flowRate= flowR*60;     // convert seconds to minutes, new unit is ml/minutes
  flowRate= flowRate/1000; // convert ml to liters, new unit is lt/minutes

  totalFlow += flowR;
 //process flowrate based on local_count




  //calculation for flowmeter 


  }
}

void loop() {

  pressure_cal(); 
  pump_control();
  flow_control();

}



void pressure_cal(void) {

  float sensorVoltage = analogRead(press_pin);   // sensor voltage A0
  float psi = ((sensorVoltage-102)/204)*25;  // Offset    0 PSI= 0.5V=102 unit, 50 PSI= 2.5, 100 PSI= 4.5V, 1 PSI= 0.04V

  // calibration 
  float bar = psi*(0.0689475729);           // Conversion PSI to BAR


  lcd.setCursor (0,1);
  lcd.print (psi);
  lcd.print (" PSI");

  lcd.setCursor ( 10,1);
  lcd.print(bar);
  lcd.print( " BAR");

  //lcd.setCursor(17,1);
  //lcd.print(sensorVoltage);



  Serial.print("\t Sensor Value = ");
  Serial.print(sensorVoltage);
  Serial.print("\t Bar = ");
  Serial.print(bar);
  Serial.print("\t PSI = ");
  Serial.println(psi);

  delay (100);
}

void pump_control(void)

{

  // read the analog in value:
  pot_init = analogRead(pot_pin);
  // map it to the range of the analog out:
  pump_init = map(pot_init, 0, 1023, 50, 230);  //  duty cycle between %20 - %90: speed control , duty cycle between %0 - %20: turned off  , duty cycle between %90 - %100: full speed
  // map pump speed percent of full scale
  percentValue = map (pump_init, 50, 230,0,100);
  // change the analog out value:
  analogWrite(pump_pwm, pump_init);

  // print the results to the Serial Monitor:
  Serial.print("\t Speed Input = ");
  Serial.print(pot_init);
  Serial.print("\t Speed Output = ");
  Serial.print(pump_init);
  Serial.print("\t Pump Speed Percentage = ");
  Serial.println(percentValue);

  lcd.setCursor(2,0);         
  lcd.print("Speed: ");
  lcd.setCursor(8,0);         
  lcd.print("%");         
  lcd.setCursor(9,0);         
  lcd.print(percentValue); 
  lcd.print("     ");         

 //  delay after the last reading:
  delay(10);

}
</code></pre>
 7508: <blockquote>
  <p><code>if (millis() -  previous_read &gt; 1000) { [...] previous_read += 1000; [...] }</code></p>
</blockquote>

<p>The code inside this block is obviously meant to be executed every
second. However, since this belongs to the interrupt handler, it only
has a chance to execute when the flow-meter sends interrupts. If the
flow is zero or very weak, this will not execute often enough.</p>

<blockquote>
  <p>flowmeter shows firstly 0.54 value</p>
</blockquote>

<p>It is no coincidence that 0.54 is what you get when <code>count == 1</code>.</p>

<p>The piece of code above should be moved to the main <code>loop()</code>, or to a
function called from <code>loop()</code>. This way it will execute consistently
irrespective of whether there is some flow or not, which is the only way
to reliably read a zero flow. Note that for better timing consistency
you should avoid doing something like...</p>

<blockquote>
  <p><code>delay(100);</code></p>
</blockquote>

<p>Don't do this. Instead, use the same trick as above:</p>

<pre><code>if (millis() -  previous_pressure_print &gt; 100) {
    previous_pressure_print += 100;
    pressure_cal();
}
</code></pre>
