#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;

int press_pin =A1;

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

double flowRate;   // value intented to calculate
double flowR; // flow value in lt
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;



void setup() {



  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) {

  count = 0; // reset counter so it could start counting from 0

  interrupts(); // enables interrupts on arduino nano
  delay(1000); // wait 1000 msec
  noInterrupts(); // disable interrupts on arduino nano


  //calculation for flowmeter 

  flowR = (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;

  // 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");

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

  lcd.setCursor(0,3);
  lcd.print("Total: "); 
  lcd.setCursor(8,2);
  lcd.print(totalFlow/1000);
  lcd.print("lt");




}

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

void loop() {

  pressure_cal(); 
  pump_control();
  flow_control();
  lcd_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.println (sensorVoltage);
  Serial.println(bar);
  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(2);


}

I try to write code including flow sensor, pressure sensor and pump. I wrote the code. But When I use interrupt , code stop. I used functions in " void loop()" . I moved the interrupt code ( flow_control) between void setup and void loop. But I can see outputs in serial monitor but I cannot see on lcd. Could you help me fix the problem ?

  • What happens in lcd_control()? You forgot to include that function. – Majenko Aug 10 at 8:50
  • I thought that I can code all lcd command in a function. But the code I added , the function is not active. I forgot to delete it. – sapphire Aug 10 at 10:58

A lot of peripheral libraries requires interrupts to be enabled, especially when they use timing or the I2C/SPI pins. Instead of disabling interrupts for the majority of the sketch, what you want to do is isolate disabling the interrupts to just reading and resetting the count variable:

noInterrupts(); // disable interrupts on arduino nano
local_count = count;
count=0;
interrupts(); // enables interrupts on arduino nano

Also all that processing takes some time which will skew the timing so it's better to use timestamp and millis:

unsigned long previous_read;

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;

    //process flowrate based on local_count

}
  • Should I replacey count*8.93 by local_count*8.93 ? When I do, Arduino says local_count was not declared in this scope? What should I do ? flowR = (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 – sapphire Aug 12 at 10:03
  • that calculation should be inside the if (where the comment is), you only need to run it when processing the new count. – ratchet freak Aug 12 at 12:51
  • Thank you so much ratchet. I want to add a button to reset only total flow on lcd void flow_control(void) { if(digitalRead(resetButtonA) == LOW) { totalMilliLitresA = 0; lcd.setCursor(0, 1); lcd.print("0L"); } – sapphire Aug 13 at 7:30
  • Thank you so much. I want to add a reset button to reset only total flow on lcd. Is this code true inside void flow(void) ? void flow_control(void) { if(digitalRead(resetButton) == LOW) { totalFlow = 0; lcd.setCursor(0, 3); lcd.print("0L"); } – sapphire Aug 13 at 7:32

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.