Water bottle filling machine

Hi,

I am making a simple gravity-fed water bottle filling machine using a solenoid and hall-effect flow sensor. It works perfectly, but I would like to upscale it to 4 nozzles i.e. 4 independent sensors and 4 independent solenoids to fill 4 bottle simultaneously.

I am not familiar with interrupts, but I wonder how this could work given my attached code.

I would appreciate any advice. I assume I need 1 interrupt per sensor and the UNO only has 2?

Many thanks,
Ben

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin = 2;
byte solenoid = 9;
byte buzzer = 10;

float calibrationFactor = 4.5;

volatile byte pulseCount;  
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;

void setup()
{
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(sensorPin, INPUT);
  pinMode(solenoid, OUTPUT);
  digitalWrite(sensorPin, HIGH);
  digitalWrite(solenoid, LOW);
  digitalWrite(buzzer, LOW);

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

  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

void loop()
{ 
  digitalWrite(solenoid, HIGH);
  if((millis() - oldTime) > 1000)
  { 
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
      
    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

    // 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");
    
   if (totalMilliLitres > 250)
   {
    digitalWrite(solenoid, LOW);
    }

    // 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++;
}

ben_788:
Hi,

I am making a simple gravity-fed water bottle filling machine using a solenoid and hall-effect flow sensor. It works perfectly, but I would like to upscale it to 4 nozzles i.e. 4 independent sensors and 4 independent solenoids to fill 4 bottle simultaneously.

I am not familiar with interrupts, but I wonder how this could work given my attached code.

I would appreciate any advice. I assume I need 1 interrupt per sensor and the UNO only has 2?

Many thanks,
Ben

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

byte sensorPin = 2;
byte solenoid = 9;
byte buzzer = 10;

float calibrationFactor = 4.5;

volatile byte pulseCount; 
float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;

void setup()
{
  Serial.begin(9600);
  pinMode(buzzer, OUTPUT);
  pinMode(sensorPin, INPUT);
  pinMode(solenoid, OUTPUT);
  digitalWrite(sensorPin, HIGH);
  digitalWrite(solenoid, LOW);
  digitalWrite(buzzer, LOW);

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

attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

void loop()
{
  digitalWrite(solenoid, HIGH);
  if((millis() - oldTime) > 1000)
  {
    detachInterrupt(sensorInterrupt);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
     
    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

// 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");
   
  if (totalMilliLitres > 250)
  {
    digitalWrite(solenoid, LOW);
    }

// 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++;
}

Your write up confuses me a bit. If you want to fill 4 bottles simultaneously, you only need to duplicate the solenoid valves. Anything else just confuses the picture unless you do not wish to fill the 4 simultaneously.

Paul

I you wish to continue using interrupts, you will need a different board that supports at least 4 pins. You can also change your code to not use interrupts and just poll the sensor pin to detect a falling edge. Look at the State Change Detection example in the IDE (File->Examples->02.Digital->StateChangeDetection)

ben_788:
I would appreciate any advice. I assume I need 1 interrupt per sensor and the UNO only has 2?

You need to tell us what sensor your using (post a link to its datasheet) and tell us how many pulses per second it produces.

And, to provide context, what is the amount of water going into each bottle and the acceptable error in the quantity?

...R

You could “diode or” your connections from the fill stations together to one interrupt pin, and also make individual connections to separate digital inputs ; then when it triggers an interrupt look at the digital pins to see which fill station generated that interrupt and deal with it appropriately .

Or use 4 pin change interrupts and adjust the flow of each nozzle to be slightly different so that 2 or more don’t reach full at exactly the same time.

Thanks for all your replies.

I require 4 solenoids and 4 sensors as I assume the bottles will all fill at a slightly different rate. I'm filling 250ml, 500ml and 1 litre bottles and my tolerance is ~20/30ml

These are the sensors I am using: https://www.ebay.co.uk/itm/1Pc-1-2-water-flow-sensor-control-effect-flowmeter-halls-1-30L-min-for-Ardu-vi/274057313935?hash=item3fcf16be8f:g:3G0AAOSw5D1cz8gj.

If I go down the route of a larger board, would the Mega have 4 interrupts? Is it simply a case of numbering the "channels" i.e. declare sensorInterrupt = 0, sensorInterrupt = 1.

Thank you

Has your local health department approved the use of the unknown plastic sensors you are using? Exactly what plastic material are you using in providing drinking water to people? Does it contain known cancer causing chemicals

Paul

Hi Paul, We fill bottles with distilled water for industy, not drinking water.