0

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

}
  • It is about the variable flowRate? Where is that variable calculated? Spoiler: in the interrupt. When there are no interrupts, that value is not calculated. I don't see a simple solution. The interrupt counts and the flowR should use that count (even if it is zero). That means you have to calculate flowR in the Arduino loop, you can use millis to calculate the actual elapsed time to allow that it is sometimes longer than 1 second. – Jot Aug 27 '18 at 6:28
  • But I add the interrupt code in void loop and function called by main loop. Code dont work. The code I added works , but there is stability problem. When ı begin arduino, Flow sensor shows 0.54 lt/min on LCD. And when flow begin, flowrate changes with +- 0.54 error ( like 4.00 lt/min then 4.54lt/min then 3.46 lt/min and ) How can I solve this problem in void loop ? – sapphire Aug 28 '18 at 6:40
2

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();
}
  • But I add the interrupt code in void loop and function called by main loop. Code dont work. The code I added works , but there is stability problem. When ı begin arduino, Flow sensor shows 0.54 lt/min on LCD. And when flow begin, flowrate changes with +- 0.54 error ( like 4.00 lt/min then 4.54lt/min then 3.46 lt/min and ) How can I solve this problem in void loop ? – sapphire Aug 28 '18 at 6:36
  • @sapphire: Do not describe the code, show it! Edit your question and add the version of the code you are talking about. – Edgar Bonet Aug 28 '18 at 7:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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