2
 #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 ?

asked Aug 10, 2018 at 7:36
2
  • What happens in lcd_control()? You forgot to include that function. Commented Aug 10, 2018 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. Commented Aug 10, 2018 at 10:58

1 Answer 1

3

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
}
answered Aug 10, 2018 at 12:14
4
  • 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 Commented Aug 12, 2018 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. Commented Aug 12, 2018 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"); } Commented Aug 13, 2018 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"); } Commented Aug 13, 2018 at 7:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.