Automatic inline bottlefiller

Hi. (I will update my program it this top post.)

This is my first sketch on this big scale and I am a newbie, so bear with me
Hope to get some help to get this project running
Descriptsion:
Conveyor belt is always running
bottle barrier is closed so bottels stops at the barrier.
when sensor bottle 1 have count 4 bottels the piston will push the filler tubes down in the bottles
add a time delay befor the valve for co2 open close it after a delay. open filler close when filler sensor have a value,
when all 4 sensors have value activate piston to rice the filler tubes.
when piston sensor have signal open bottle barrier.
when bottle sensor 2 have count to 4 close barrier.
bottle sensor1 need to count also at the same time. so this prosess can be repeated!

sketch of the bottle line:
bottleline.jpg

Tings to fix:

FillerValve1-4 is high after startup!
Run filling only when 4 bottles have entered sensor1

//Automatic bottlefiller line, 

//---------- Display-------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// --------CONSTANTS (won't change)---------------
const int BottleBarrier = 2;	//pin 2 OUTPUT	bottlebarrier = LOW = CLoSED
const int FillerValve1 = 3;		//pin 3-6 OUTPUT	fillervalve 1-4 = LOW = CLOSED
const int FillerValve2 = 4;
const int FillerValve3 = 5;
const int FillerValve4 = 6;
const int Co2Valve = 7;		//pin 7 OUTPUT	co2valve 1-4 = LOW = CLOSED
const int SensorFiller1 = A0;  	//pin A0-A4 INPUT sensor_filler 1-4 = value 
const int SensorFiller2 = A1;  	
const int SensorFiller3 = A2;		
const int SensorFiller4 = A3;		
const int Piston = 11;		//pin 11 OUPUT	piston =  LOW = piston valve for up posision
const int SensorBottle1 = 12;	//pin 12 INPUT	sensor_bottle1 = HIGH = bottle at sensor befor filler
const int SensorBottle2 = 13;	//pin 13 INPUT	sensor_bottle2 = HIGH = bottle at sensor after filler
const int SensorPiston = 8;	//pin A4 INPUT	sensor_piston_up = HIGH = piston UP
//DISPLAY: SDA - ANALOG Pin 4, SCL - ANALOG pin 5

//--------Delays------------------
const int PistonDelay = 2000;  //time between piston start and co2 purge
const int Co2PurgeTime = 2000; //co2 purge time befor filling
const int sensorInterval = 300; // number of millisecs between sensor readings
const int SensorValue = 1000; // Value on filling sensors

//--------VARIABLES (will change)------------------
byte SensorBottle1State = LOW;  // used to record whether the sensors are detecting HIGH = not detecting 
byte SensorBottle2State = LOW;
byte SensorPistonState = LOW;
int SensorValue1 = 0;   // variable to store the value read
int SensorValue2 = 0;   // variable to store the value read
int SensorValue3 = 0;   // variable to store the value read
int SensorValue4 = 0;   // variable to store the value read
int Bottle1Counter = 0;   	// counter for the number of bottles
int Bottle1State = 0;         	// current state of the sensor
int LastBottle1State = 0;     	// previous state of the sensor
int Bottle2Counter = 0;   	// counter for the number of bottles
int Bottle2State = 0;         	// current state of the sensor
int PistonState = 0;
int LastBottle2State = 0;     	// previous state of the sensor
boolean runFilling = false;

unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long Filltime = 0;
unsigned long previousSensorBottle1Millis = 0; // 
unsigned long previousSensorBottle2Millis = 0; // 



void setup()
{
    lcd.begin(20,4);  //change to (16,2) if using a 16x2 display 

// ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i< 3; i++)
  {
        lcd.clear();
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on  
    lcd.setCursor(4,0); //Start at character 4 on line 0
  lcd.print("Starter opp!");
      lcd.setCursor(5,1);
  lcd.print("Automatisk");
        lcd.setCursor(4,2);
  lcd.print("Flaskelinje");
    lcd.setCursor(1,3); 
  lcd.print("AUL Mikrobryggeri!");
  delay(3000);

    

  pinMode(BottleBarrier, OUTPUT);
  pinMode(FillerValve1, OUTPUT);
  pinMode(FillerValve2, OUTPUT);
  pinMode(FillerValve3, OUTPUT);
  pinMode(FillerValve4, OUTPUT);
  pinMode(Co2Valve, OUTPUT);
  pinMode(Piston, OUTPUT);
  pinMode(SensorBottle1, INPUT_PULLUP);
  pinMode(SensorBottle2, INPUT_PULLUP);
  pinMode(SensorPiston, INPUT_PULLUP);
Serial.begin(9600);   

}

void loop() { 
currentMillis = millis();
updateSensorBottle1();
updateSensorBottle2();
updateFillingSensors();
Filling();
  if ((Bottle1Counter == 4) && (Bottle1Counter > 0)){
Bottle1Counter = 0;
runFilling = true;
 }


  if (Bottle2Counter % 4 == 0){
 digitalWrite(BottleBarrier, LOW);
}
else
{
 digitalWrite(BottleBarrier, HIGH);
 }

}
//=============================================================================
void Filling() {
  
    if(currentMillis >= (Filltime + PistonDelay) && (currentMillis <= (Filltime + PistonDelay + Co2PurgeTime))){  
  digitalWrite(Co2Valve, HIGH);  
          lcd.clear();
       lcd.setCursor(6,1); 
  lcd.print("Co2 utrensing!");
  lcd.setCursor(7,2);
  lcd.print(Co2PurgeTime);
    lcd.setCursor(11,2);
  lcd.print("ms");

  }
  else
  {
    digitalWrite(Co2Valve, LOW);  
  }
    if(currentMillis >= (Filltime + PistonDelay + Co2PurgeTime) && (currentMillis <= (Filltime + PistonDelay + Co2PurgeTime + 20000))){  
   digitalWrite(FillerValve1, HIGH);
   digitalWrite(FillerValve2, HIGH);
   digitalWrite(FillerValve3, HIGH);
   digitalWrite(FillerValve4, HIGH);
               lcd.clear();
      lcd.setCursor(6,0); 
  lcd.print("FYLLER!");
  lcd.setCursor(1,1); 
  lcd.print("Fyllesensorverdi:"); 
    lcd.setCursor(1,2); 
  lcd.print("1:   2:   3:   4:"); 
      lcd.setCursor(1,3); 
  lcd.print(SensorValue1); 
        lcd.setCursor(6,3); 
  lcd.print(SensorValue1);
        lcd.setCursor(11,3); 
  lcd.print(SensorValue1);
        lcd.setCursor(16,3); 
  lcd.print(SensorValue1);
  delay(100);
  }
   
  else
  {
  digitalWrite(FillerValve1, LOW);
   digitalWrite(FillerValve2, LOW);
   digitalWrite(FillerValve3, LOW);
   digitalWrite(FillerValve4, LOW);    
 }
 
if   (runFilling == true){
  Filltime = currentMillis;
   lcd.clear();
      lcd.setCursor(6,0); 
  lcd.print("FYLLER!");
        lcd.setCursor(2,1); 
 lcd.print("Fyllestempel ned");
  digitalWrite(Piston, HIGH);  

  }




 runFilling = false;
}
//===============================================================================

  
void updateFillingSensors() {
  SensorValue1 = analogRead(SensorFiller1);    // read the input pin
  SensorValue2 = analogRead(SensorFiller2);    // read the input pin
  SensorValue3 = analogRead(SensorFiller3);    // read the input pin
  SensorValue4 = analogRead(SensorFiller4);    // read the input pin

if (SensorValue1 > SensorValue)
{
digitalWrite(FillerValve1, LOW);  // Filling off
}
  if (SensorValue2 > SensorValue)
{
digitalWrite(FillerValve2, LOW);  // Filling off
}
  if (SensorValue3 > SensorValue)
{
digitalWrite(FillerValve3, LOW);  // Filling off
}
  if (SensorValue4 > SensorValue)
{
digitalWrite(FillerValve4, LOW);  // Filling off
}
if (SensorValue1 > SensorValue) // legg til alle følere
 {
 digitalWrite(Piston, LOW); }
}
//===============================================================================

void updateSensorBottle1() {
  
    if (millis() - previousSensorBottle1Millis >= sensorInterval) {

   if (digitalRead(SensorBottle1) == LOW) {
     SensorBottle1State = ! SensorBottle1State; // this changes it to LOW if it was HIGH 
                                          //   and to HIGH if it was LOW
     previousSensorBottle1Millis += sensorInterval;
   }
 }
  
  
  Bottle1State = digitalRead(SensorBottle1);
if (Bottle1State != LastBottle1State){ 	    
  if (Bottle1State == HIGH){ 
      Bottle1Counter++;
            Serial.print("number of bottls sensor1 :  ");
      Serial.println(Bottle1Counter);
  }
}

  LastBottle1State = Bottle1State;


  }
  //===========================================================================

void updateSensorBottle2() {
  
  if (millis() - previousSensorBottle2Millis >= sensorInterval) {

   if (digitalRead(SensorBottle2) == LOW) {
     SensorBottle2State = ! SensorBottle2State; // this changes it to LOW if it was HIGH 
                                          //   and to HIGH if it was LOW
     previousSensorBottle2Millis += sensorInterval;
   }
 }


  
  Bottle2State = digitalRead(SensorBottle2);
if (Bottle2State != LastBottle2State){ 	    
  if (Bottle2State == HIGH){ 
      Bottle2Counter++;
       Serial.print("number of bottls filled :  ");
      Serial.println(Bottle2Counter);
  }
}
  LastBottle2State = Bottle2State;


  }

I have also made a skech at

Best regards
Pål

so it is several errors that i need help with.

You want us to guess what they are?

Yes please :slightly_frowning_face: The IDE is gessing error: expected unqualified-id before 'if'

?

Check after all your if statements there should be a ;

I have get rid of the error message. so no it compiles :slight_smile:

but it don't work as intended.

first i see that bottles is counting every second. this should only be counted on "sensor_bottle2 = 13" have a input!

Second
when bottle1_Counter have been "pressed" 4 times it should run "piston, HIGH"

Cheers!

The IDE is gessing error: expected unqualified-id before 'if'

It isn't guessing at all. It IS telling you exactly which line number, and where on that line the problem is.

first i see that bottles is counting every second. this should only be counted on "sensor_bottle2 = 13" have a input!

Then there is a 99.9% chance that you switch is wired incorrectly.

it should run "piston, HIGH"

It can't do that. It can set a pin high, using digitalWrite().

What are your Serial.print() statements tell you is happening?

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

WHY???
You have the project in-front of you, we don't.
You know how it is wired, we don't.

Thanks...Tom..... :slight_smile:

tpmill1990:
Check after all your if statements there should be a ;

Categorically not true.

TomGeorge:
Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

WHY???
You have the project in-front of you, we don't.
You know how it is wired, we don't.

Thanks...Tom..... :slight_smile:

I already have, see the first post :slight_smile:
But here it is again:

I have added some more details on the filler line in the first post! :slight_smile:

BeerPal:
when bottle sensor 2 have count to 4 close barrier.
bottle sensor1 need to count also at the same time. so this prosess can be repeated!

As the code is written this can't happen because you have delay(1000) between the reading of the two bottle counters.

You need to stop using delay() and use millis() to manage the timing as illustrated in several things at a time.

I also think you need to organize your code so it does not attempt to work in the linear way you have it designed.

Instead, you need to think of the system being in different states. For example a bottle moving state; a 4-bottles ready state, a filling state, a full state. Then you can have a function for each of these activities and the appropriate function is activated by the state of the system. And you also need a sensorRead() function to gather the necessary data.

The Thread planning and implementing a program may be useful.

...R

Robin2:
As the code is written this can't happen because you have delay(1000) between the reading of the two bottle counters.....................

...R

Thank you so very much this helps me a lot! i have start all over again.

I wonder how the best way to rune a void only one time.

in this case void filling()

It's not a void, it's a function. Void is what it returns.

To run a function only once, call it only once. Set a boolean flag to see if it needs to run.

if (runFilling == true)
{
 filling();
 runFilling = false;
}

The have other parts of the code alter runFilling to true when you need to run it.

Thanks a lot for you replays. it really helps me!

But i struggle with some things

if ((Bottle1Counter % 4 == 0) && (Bottle1Counter > 0)){
runFilling = true;
}

if (runFilling == true)
{ //my code

runFilling = false
}

Here i want it to change the runFilling to true but only run my code one time?

How do i do that.

also i wonder i can run this without delay :

digitalWrite (Co2Valve, HIGH); //delay Co2PurgeTime befor next step
delay(Co2PurgeTime);
digitalWrite (Co2Valve, LOW);

BeerPal:

if   (runFilling == true)

{ //my code

runFilling = false
}




Here i want it to change the runFilling to true but only run my code one time?

How do i do that.

Because runFilling is set to false it won't run a second time unless that variable is set to true somewhere else in the program.

also i wonder i can run this without delay :

digitalWrite (Co2Valve, HIGH); //delay Co2PurgeTime befor next step

delay(Co2PurgeTime);
  digitalWrite (Co2Valve, LOW);

Yes - look at several things at a time. Then have a go at your own code and if it does not work for you post the code so we can help.

...R

i think i need some help!

//Automatic bottlefiller line, 

//---------- Display-------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// --------CONSTANTS (won't change)---------------
const int BottleBarrier = 2;	//pin 2 OUTPUT	bottlebarrier = LOW = CLoSED
const int FillerValve1 = 3;		//pin 3-6 OUTPUT	fillervalve 1-4 = LOW = CLOSED
const int FillerValve2 = 4;
const int FillerValve3 = 5;
const int FillerValve4 = 6;
const int Co2Valve = 7;		//pin 7-10 OUTPUT	co2valve 1-4 = LOW = CLOSED
const int SensorFiller1 = 0;  	//pin A0-A4 INPUT sensor_filler 1-4 = value 
const int SensorFiller2 = 1;  	
const int SensorFiller3 = 2;		
const int SensorFiller4 = 3;		
const int Piston = 11;		//pin 11 OUPUT	piston =  LOW = piston valve for up posision
const int SensorBottle1 = 12;	//pin 12 INPUT	sensor_bottle1 = HIGH = bottle at sensor befor filler
const int SensorBottle2 = 13;	//pin 13 INPUT	sensor_bottle2 = HIGH = bottle at sensor after filler
const int SensorPiston = 4;	//pin A4 INPUT	sensor_piston_up = HIGH = piston UP
//DISPLAY: SDA - ANALOG Pin 4, SCL - ANALOG pin 5

//--------Delays------------------
const int PistonDelay = 1000;  //time between piston start and co2 purge
const int Co2PurgeTime = 1000; //co2 purge time befor filling
const int sensorInterval = 300; // number of millisecs between sensor readings
const int SensorValue = 1; // Value on filling sensors

//--------VARIABLES (will change)------------------
byte SensorBottle1State = LOW;  // used to record whether the sensors are detecting HIGH = not detecting 
byte SensorBottle2State = LOW;
byte SensorPistonState = LOW;
int SensorValue1 = 0;   // variable to store the value read
int SensorValue2 = 0;   // variable to store the value read
int SensorValue3 = 0;   // variable to store the value read
int SensorValue4 = 0;   // variable to store the value read
int Bottle1Counter = 0;   	// counter for the number of bottles
int Bottle1State = 0;         	// current state of the sensor
int LastBottle1State = 0;     	// previous state of the sensor
int Bottle2Counter = 0;   	// counter for the number of bottles
int Bottle2State = 0;         	// current state of the sensor
int LastBottle2State = 0;     	// previous state of the sensor
boolean runFilling = false;


unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()




void setup()
{
    lcd.begin(16,2);  //change to (20,4) if using a 20x4 display 

// ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i< 3; i++)
  {
        lcd.clear();
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on  
    lcd.setCursor(3,0); //Start at character 4 on line 0
  lcd.print("Starter opp!");
    lcd.setCursor(2,2);
  lcd.print("Levert av AUL");
  delay(3000);

    

  pinMode(BottleBarrier, OUTPUT);
  pinMode(FillerValve1, OUTPUT);
  pinMode(FillerValve2, OUTPUT);
  pinMode(FillerValve3, OUTPUT);
  pinMode(FillerValve4, OUTPUT);
  pinMode(Co2Valve, OUTPUT);
  pinMode(Piston, OUTPUT);
  pinMode(SensorBottle1, INPUT);
  pinMode(SensorBottle2, INPUT);
  pinMode(SensorPiston, INPUT);
Serial.begin(9600);   

}

void loop() { 
currentMillis = millis();
updateSensorBottle1();
updateSensorBottle2();
updateFillingSensors();
Filling();
  if ((Bottle1Counter % 4 == 0) && (Bottle1Counter > 0)){
runFilling = true;
 }
 else
 {runFilling = false;
 }

  if (Bottle2Counter % 4 == 0){
 digitalWrite(BottleBarrier, LOW);
}
else
{
 digitalWrite(BottleBarrier, HIGH);
 }

}
//=============================================================================
void Filling() {
if   (runFilling == true){
   lcd.clear();
      lcd.setCursor(3,0); 
  lcd.print("FYLLER!");
        lcd.setCursor(0,1); 
 lcd.print("Senker stempel");
  digitalWrite(Piston, HIGH);  //PistonDelay befor next step
  delay(PistonDelay);
        lcd.setCursor(0,1); 
 lcd.print("Co2Purge      ");  
  digitalWrite (Co2Valve, HIGH); //Co2PurgeTime befor next step
  delay(Co2PurgeTime);
   digitalWrite (Co2Valve, LOW);
   digitalWrite(FillerValve1, HIGH);
   digitalWrite(FillerValve2, HIGH);
   digitalWrite(FillerValve3, HIGH);
   digitalWrite(FillerValve4, HIGH);
 if ((SensorValue1 > SensorValue) && (SensorValue2 > SensorValue) && (SensorValue3 > SensorValue) && (SensorValue4 > SensorValue))
 {
 digitalWrite(Piston, LOW); }
if (SensorPiston == HIGH){
digitalWrite(BottleBarrier, HIGH);
}
  
}
 runFilling = false;
}
//===============================================================================

  
void updateFillingSensors() {
  SensorValue1 = analogRead(SensorFiller1);    // read the input pin
  SensorValue2 = analogRead(SensorFiller2);    // read the input pin
  SensorValue3 = analogRead(SensorFiller3);    // read the input pin
  SensorValue4 = analogRead(SensorFiller4);    // read the input pin

if (SensorValue1 > SensorValue)
{
digitalWrite(FillerValve1, LOW);  // Filling off
}
  if (SensorValue2 > SensorValue)
{
digitalWrite(FillerValve2, LOW);  // Filling off
}
  if (SensorValue3 > SensorValue)
{
digitalWrite(FillerValve3, LOW);  // Filling off
}
  if (SensorValue4 > SensorValue)
{
digitalWrite(FillerValve4, LOW);  // Filling off
}
}
//===============================================================================

void updateSensorBottle1() {
  
  
  Bottle1State = digitalRead(SensorBottle1);
if (Bottle1State != LastBottle1State){ 	    
  if (Bottle1State == HIGH){ 
      Bottle1Counter++;
            Serial.print("number of bottls sensor1 :  ");
      Serial.println(Bottle1Counter);
  }
}

  LastBottle1State = Bottle1State;


  }
  //===========================================================================

void updateSensorBottle2() {
  
  Bottle2State = digitalRead(SensorBottle2);
if (Bottle2State != LastBottle2State){ 	    
  if (Bottle2State == HIGH){ 
      Bottle2Counter++;
       Serial.print("number of bottls filled :  ");
      Serial.println(Bottle2Counter);
  }
}
  LastBottle2State = Bottle2State;




  }
  //===========================================================================

BeerPal:
i think i need some help!

I will try to look at this tomorrow. In the meantime can you give me some pointers as to the areas where you need help so I don't have to study the entire program?

...R

Hi i have update my code in the first post.

the FillerValve1-4 is active under the "if" statement in line 135 after reboot.

why is this and why do it not happen with the Co2Valve" if" statemaent under line 120

Also i don't think the noise filter on input work?

Hi i have update my code in the first post.

That is a very unfriendly thing to do because now some of the replies in the thread don't make sense because they refer to the original program.