Arduino skips code on liquid filler

Good day, i'm writing this to see if someone can help me with a routine I made for an automatic liquid filler.
It uses a YF-S201 flow sensor, the sensor outputs pulses at a certain frequency, and from that frequency you can get the
flow, and naturally, the volume, for getting the frequency I made a IRS routine that polls the sensor for 500ms.

The program is intended to activate a water pump connected to the flow sensor, and then constantly poll the flow and volume.
When the volume reaches about 1 Liter, the pump is turned off, the LCD display tells the user filling has been completed, waits a second,
then polls for the press of the activation button again.

Problem is, once the liter is filled, it completely skips the lcd message, however, the pump is turned off and the volume value
is correctly reset, yet the messages and the delay never happen. I have done plenty of tests using flags, but not even those trigger.
Only the volume reset and pump deactivation.

I really cant figure out why almost anything after my do-while routine is skipped, help would be gretly appreciated. Sorry for the spanish code, I put english comments to help it be understandable.

const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
volatile int NumPulsos; //Variable for counting flowmeter pulses
int PinSensor = 2;    //Pin for flow sensor
float factor_conversion=7.31; // Conversion factor from sensor datasheet
float volumen=0;//
long dt=0; //time difference between each loop
long t0=0; //miliseconds after previous loop
int PinBoton = 7; //This pin is connected to a push button to trigger the pump
int PinBomba = 8;//Pin connected to a relay to trigger the water pump
void ContarPulsos ()  //Interrupt routine function
{ 
  NumPulsos++;  //Increments the number of pulses by 1
} 


int ObtenerFrecuecia() //Function for obtaining the frequency of the flow sensor
{
   int frecuencia;
  NumPulsos = 0;   //Pulse numer is reset
  interrupts();    //Enable interrupts
  delay(500);   //Sensor is polled for half a second
  noInterrupts(); //Interrupts are disabled
  frecuencia=NumPulsos; // We get the half frequency
  return frecuencia;
}

void setup() //
{ 
  pinMode(PinBomba,OUTPUT); 
  pinMode(PinBoton,INPUT); 
  pinMode(PinSensor, INPUT);
  attachInterrupt(0,ContarPulsos,RISING);//Interrupt is given to pin 2 (indicated as 0 here)
  t0=millis();//T0 starts counting
  digitalWrite(PinBomba,LOW);
  lcd.begin(16,2);
  lcd.print("Welcome");
delay(1000);
} 

void loop ()    
{
  if(digitalRead(PinBoton) == LOW){ //Poll if the pushbutton is pressed
  delay(500);
   lcd.setCursor(0, 0);
   lcd.print("Waiting...");
  }else{ //When the button is pressed
    do{ //A loop is created for filling the bottle
  digitalWrite(PinBomba,HIGH);//Pump is activated
  float frecuencia=ObtenerFrecuecia(); //We get the frequency in Hz
  float caudal_L_m=frecuencia/(factor_conversion*2); //Flow is calculated in L/m
  dt=millis()-t0; //Time difference is calculated
  t0=millis();//t0 is reset
  volumen=volumen+(caudal_L_m/60)*(dt/500); // volume(L)=flow(L/s)*time(s)

   //Information regarding current flow and volume is written on an LCD display
   lcd.setCursor(0, 0);
   lcd.print("Caudal:");
   lcd.print(caudal_L_m,3);
   lcd.setCursor(0, 1);
   lcd.print("Volumen: ");
   lcd.print(volumen,3);
    }while(volumen < .95); //When the filling reached .95 liters, the pump will stop.
    digitalWrite(PinBomba,LOW); //Pump is turned off
   volumen = 0;//Volume is reset
  lcd.clear();//A message showing the user the filling is complete is shown
   lcd.setCursor(0, 0);
   lcd.print("Dispensacion");
   lcd.setCursor(0, 1);
   lcd.print("Completa");
   delay(1000); //We wait 1 second until the button can be pressed again
    
  }
  }

Hi
please don't understand which messages never occur?
RV mineirin

Your measurement routine disables interrupts after it is done and leaves them disabled - not good.
You need to turn them off to reset your pulse counter, turn them on to get your measurements, turn the off again to copy the results and then turn them back on

int ObtenerFrecuecia() //Function for obtaining the frequency of the flow sensor
{
  int frecuencia;
  noInterrupts();
  NumPulsos = 0;   //Pulse numer is reset
  interrupts();    //Enable interrupts
  delay(500);   //Sensor is polled for half a second
  noInterrupts(); //Interrupts are disabled
  frecuencia = NumPulsos; // We get the half frequency
  interrupts();
  return frecuencia;
}

and depending on how many pulses you get, you should change NumPulsos from 'int' to 'unsigned int' or 'unsigned long' since there really is no concept of a negative pulse count.

Also, your time variables should be unsigned long as well since that is what millis() returns.

Hi @duckbuster

in the tests I did here with your code, the problem is in disabling the interrupts in the ObtenerFrecuecia() routine.
Study another alternative to this routine.

RV mineirin

1 Like

That's a good breakdown of my mistakes, thanks, i'll try to incorporate your suggestions later and see if it makes a difference.

Yup, I was suspicious the interrupts were the root cause and this almost confirms it, gonna try thinking of something else, maybe replacing interrupts and nointerrupts with just turning on and off the sensor.

Late response but I incorporated the changes you suggested and it works flawlessly now, thank you very much!
For the curious this is the main change I made:

int ObtenerFrecuecia()  //Function for obtaining the frequency of the flow sensor
{
 noInterrupts(); //Reset pulse count
 int frecuencia;
 NumPulsos = 0;   //Pulse number is reset
 interrupts();    //Re-enable interrupts for polling
 delay(500);   //500 ms sample
 noInterrupts(); //Re-disable interrupts to get the frequency
 frecuencia=NumPulsos; //frequency is saved
interrupts(); //Re-enable interrupts to avoid sabotage of other functions.
 return frecuencia;
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.