Flow Sensor

Hello everyone, I'm building a pulsitle pump and I want to check the flow on each pulse in ml/s.
Im exporting the readings to excel, because i found easy to check the data.

YF-S210 sensor:
Hall Efect
5V~18V
Current cons: 15mA
Flow: 1~30L/min
1/2"

My problem is that the curves are so flat, it's suppose to look like a sine wave, but I'm having more a triangle shape. Tried to change the delay, but didnt work

const int flowPin = 2; //This is the input pin on the Arduino
double flowRate = 0; //This is the value we intend to calculate.
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.
const int IntSensor = 0; //interrupt = 0
const float CalFactor = 7.5;
double t = 0;
int line = 0;
unsigned long tbefore = 0;

void setup() {

pinMode(flowPin, INPUT_PULLUP); //Sets the pin as an input
attachInterrupt(0, Flow, RISING); //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"
Serial.begin(9600); //Start Serial
Serial.println("CLEARDATA");
Serial.println("LABEL,Time,Tempo,FlowRate");

}
void loop()
{
if((millis()-tbefore)>50)
{
line++;
detachInterrupt(IntSensor); // desabilita interrupcao
flowRate = ((50.0 / (millis()-tbefore))*count)/CalFactor;
flowRate = (flowRate/60)*1000; //ml/s
Serial.print("DATA,TIME,");
Serial.print(t);
Serial.print(",");
Serial.println(flowRate);
count = 0;
t=millis();
tbefore = millis();
attachInterrupt(IntSensor,Flow,FALLING);
}

if (line > 25)
{
line = 0;
Serial.println("ROW,SET,2");
}
}

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

I guess your flow is simply to low. Did you realize that the sensor doesn't work in it's accuracy (which is quite low anyway) if the flow is below 1l/min (~ 16ml/s)?

Looks like 50 msec is too low for flow calculation. Could you output just a pure count values?
And its better to use noInterrupts()/interrupts() in a loop instead of attach/detach

Attaching and detaching interrupts on the fly will mis-count interrupts - don't do
things this way, just attach in setup and that's it. All access to volatile variables in the
main program should use noInterrupts()/interrupts() to bracket the access into a
critical-section like this:

 if (millis() - tbefore > 50)
 {
   line++;
  
   noInterrupts() ;  // critical section (atomic), as short as possible, no Serial or delay calls are allowed here.
   int my_count = count ;  // sample count into a local variable
   count = 0 ;  // update count
   interrupts () ;

   // handle sampling time in one place and consistently:
   unsigned long now = millis() ;   // sample time once only per loop, otherwise you mis-account it.
   unsigned long duration = now - tbefore ;
   tbefore = now;  // setup tbefore for next time, 

   flowRate = ((50.0 / duration) * my_count) / CalFactor;  // use the local variable only here.
   flowRate = (flowRate / 60) * 1000 ; // ml/s
   Serial.print("DATA,TIME,");
   Serial.print(t);
   Serial.print(",");
   Serial.println(flowRate);
  }

Note the separation into sections with distinct purposes, and the correct accounting of time.
If you call millis(), do some stuff, then call millis() again you will not include all the elapsed
time in your calculations.

Hey, thanks for ur feedback.

const int flowPin = 2;    //This is the input pin on the Arduino
double flowRate = 0;    //This is the value we intend to calculate. 
volatile int count; //This integer needs to be set as volatile to ensure it updates correctly during the interrupt process.  
unsigned long tbefore = 0;
double t = 0;
int line = 0;

void setup() {
  
  pinMode(flowPin, INPUT_PULLUP);           //Sets the pin as an input
  attachInterrupt(0, Flow, CHANGE);  //Configures interrupt 0 (pin 2 on the Arduino Uno) to run the function "Flow"  
  Serial.begin(115200);                //Start Serial
  Serial.println("CLEARDATA");        //Communication with PLX DAQ Excel
  Serial.println("LABEL,Time,Tempo,FlowRate"); //Col names in Excel
  
}
void loop()
{
  if (millis() - tbefore > 200
  )
   {
    
    line++;
    noInterrupts(); //Disable the interrupts on the Arduino
    t = millis();
    int my_count = count ;      // Reset the counter so we start counting from 0 again
    count = 0; // update count
    interrupts();   //Enables interrupts on the Arduino
  
    // handle sampling time in one place and consistently:
     unsigned long now = millis() ;   // sample time once only per loop, otherwise you mis-account it.
     unsigned long duration = now - tbefore ;
     tbefore = now;  // setup tbefore for next time, 
  
     flowRate = ((1000 / duration) * my_count) / 5.5;  // use the local variable only here.
     //flowRate = (flowRate / 60) * 1000 ; // ml/s
     
    Serial.print("DATA,TIME,");  //Printing in the Excel file
    Serial.print(t);
    Serial.print(",");
    Serial.println(flowRate);

   }
   
  if (line > 50)
  {
    line = 0;
    //Serial.println("ROW,SET,2"); //Jump to row 2 in the PLX DAQ excel file
  }
  
}
 
void Flow()
{
   count++; //Every time this function is called, increment "count" by 1
}

The thing is that the variation is fast, because its a pulsatile flow. I dont know if this sensor is ideal…

PD

Im still having this square waves, do you think it may be the resolution of the arduino or maybe the is the sensor that is not capable of capturing in a short period of time?

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