flow sensor data collection

I have a hall effect flow sensor. My goal is to monitor beer poured from a keg. Below is my code so far, I found it on the web and have been tweaking it to my needs so far. As is it tracks how much beer has been poured. I would like it to loop looking for the flow to start, monitor the pour volume, then after the flow has stopped subtract the poured volume from the volume of the full keg.

How can I start monitoring the flow when it first starts? would this be an inturrupt?

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;

// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 18.7;

volatile byte pulseCount;  

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
float kegOZ = 661;
float ozPOURED = 24.07;
float BeerLeft=647.9;

float ounces = 0.0;

unsigned long oldTotalML;
unsigned long oldTime;

void setup()
{
  
  // Initialize a serial connection for reporting values to the host
  Serial.begin(9600);
   
  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;
  oldTotalML =0;
  

  // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
  // Configured to trigger on a FALLING state change (transition from HIGH
  // state to LOW state)
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

/**
 * Main program loop
 */
void loop()
{
  
   
   if((millis() - oldTime) > 1000)    // Only process counters once per second
  { 
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
    detachInterrupt(sensorInterrupt);
        
    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    
    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    oldTime = millis();
    
    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres = (flowRate / 60) * 1000;
    
    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;

    //Divide total millilitres by 29.57353 to convert to ounces
      ounces=totalMilliLitres/29.57353;
      
    unsigned int frac;

    

    // 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
    Serial.println();

    // Print the cumulative total of litres flowed since starting
    Serial.print("Output Liquid Quantity: ");        
    Serial.print(totalMilliLitres);
    Serial.println("mL"); 
    Serial.print("\t");       // Print tab space
  Serial.print(totalMilliLitres/1000);
  Serial.print("L");
  Serial.println();

  // Print the cumulative total of ounces flowed since starting
    Serial.print("Output ounces: ");        
    Serial.print(ounces);
    Serial.println("OZ"); 
    Serial.print("\t");       // Print tab space
  Serial.print(totalMilliLitres/1000);
  Serial.print("L");
      

    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;
    
    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}

/*
Insterrupt Service Routine
 */
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

What are the specific conditions that tell YOU, personally, that a flow has started? They will be the same logic you use to make the program know the flow has started.

Paul

Paul_KD7HB:
What are the specific conditions that tell YOU, personally, that a flow has started? They will be the same logic you use to make the program know the flow has started.

Paul

That would be pulling back the tap handle.

botdad1013:
That would be pulling back the tap handle.

That obviously has nothing to do with you determining exactly WHEN the flow begins.
Paul

Flow programmes usually have code to measure rate. You can start counting when the rate exceeds 200l/min secure in the knowledge that, if it should be flowing, it will be faster than that. This is to get rid of false starts.

Every pulse is a volume of fluid. In your case: “approximately 4.5 pulses per second per liter/minute of flow.” That’s 270 pulses (4.5 * 60) per minute per liter/minute = 270 pulses per liter (3.704 ml per pulse).

Calculate the volume of the keg in pulses. Each time you detect a pulse, subtract a pulse from the keg and note the time.

If the time since the last pulse reaches some number of milliseconds (100? 500?) that indicates that the flow has ‘stopped’, note the contents of the keg for next time. The amount that was dispensed was the keg contents the previous time pouring stopped minus the current contents.

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