Abfüllanlage, problem mit if verschachtelung

Hallo

Als Schulprojekt baue ich eine Abfüllanlage, jetzt habe ich das Problem dass meine Pumpe nicht mehr abgeschaltet wird wenn der Füllvorgang beendet ist (Durchflusssensor, counter). Wie kann ich das verschachteln dass meine Pumpe abgeschaltet wird obwohl sie durch die Lichtschranke ja wieder angeschaltet wird?
Habe versucht den Bereich kenntlich zu machen !
vielen Dank im Voraus !

[/#include <Servo.h>

Servo motorlinks;
Servo motorrechts;

const int durchfluss = 48;
int counter;
int durchflussstatus;
int pumpe = 45;
int ventil = 44;
int Notaus = 51;
int notausstatus;
int tasterrechts = 53;
int tasterstatus;
int tasterlinks = 52;
int tasterstatus2;
int lichschrankeoben = 43;
int lichobenstatus;

void setup() { 
Serial.begin(9600);
pinMode(durchfluss, INPUT);
pinMode(Notaus,INPUT);  
pinMode(tasterrechts,INPUT);
pinMode(lichschrankeoben,INPUT);
pinMode(pumpe,OUTPUT);
pinMode(ventil,OUTPUT);
motorlinks.attach(50);
motorrechts.attach(49);
motorlinks.write(90);
motorrechts.write(90);
digitalWrite(pumpe, LOW);
digitalWrite(ventil, LOW);
}

void loop() {
durchflussstatus = digitalRead(durchfluss);
notausstatus = digitalRead(Notaus);
tasterstatus = digitalRead(tasterrechts);
tasterstatus2 = digitalRead(tasterlinks);
lichobenstatus = digitalRead(lichschrankeoben);

if(notausstatus == HIGH) //Wenn Notaus nicht betätigt
{

  if(tasterstatus == HIGH) //Anlage EIN
  {
  motorrechts.write(140); //Motor rechts starten
  motorlinks.write(140); //Motor links starten
  }

  if(tasterstatus2 == HIGH) //Förderbandstopp
  {
  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  }
 
////////////////////////////////////////////////////////////////////////////////////

  if(lichobenstatus == LOW) //Förderbandstopp
  {
  digitalWrite(pumpe, HIGH);
  digitalWrite(ventil, HIGH);
  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  if (durchflussstatus == HIGH) 
  {  
  counter++;
  }
  if (counter == 200)
  {
  digitalWrite(pumpe, LOW);
  digitalWrite(ventil, LOW);
  }
  
////////////////////////////////////////////////////////////////////


  Serial.println(counter);
}
  if(lichobenstatus == HIGH) //Förderbandstopp
  {
  digitalWrite(pumpe, LOW);
  digitalWrite(ventil, LOW);
  }
}

if(notausstatus == LOW) //Wenn Notaus betätigt
{

  {
  motorlinks.write(90);
  motorrechts.write(90);
  digitalWrite(pumpe, LOW);
  digitalWrite(ventil, LOW);
  }

}
}]

versuch mal statt counter ==200 counter>=199

Eine Füllanlage ...
Also eine Ablaufsteuerung!

Das Zauberwort ist in solchen Fällen IMMER: "Endlicher Automat"
(In der SPS Welt auch manchmal Schrittkette genannt.)

Hier im Forum wurde schon einiges (quasi täglich) zu endlichen Automaten geschrieben.

Vielen Dank !
An so Kleinigkeiten hängt man dann fest :slight_smile:
Nächstes Problem: wie kann ich etwas nur einmalig ausführen ?

Das Problem lautet wie folgt, Ich schreibe etwas auf das LCD und in der nächsten if schleife will ich etwas anderes darauf schreiben, Problem ist nur, dass der das aus der vorherigen if schleife auch wieder überschreibt. Will hoffen dass man verstehen kann was ich meine. Funktioniert aber ansonsten mit Füllstands anzeige tip top ! Hab versucht den Bereich (////) so kenntlich zu machen.

#include <Servo.h>
#include <LiquidCrystal.h>

Servo motorlinks;
Servo motorrechts;

LiquidCrystal lcd(40, 39, 38, 37, 36, 35);
const int durchfluss = 48;
int counter;
int durchflussstatus;
int durchflussan;
int pumpe = 45;
int ventil = 44;
int Notaus = 51;
int notausstatus;
int tasterrechts = 53;
int tasterstatus;
int tasterlinks = 52;
int tasterstatus2;
int lichschrankeoben = 42;
int lichobenstatus;
int lichschrankeunten = 43;
int lichuntenstatus;
int trigPin = 46;
int echoPin = 47;
int ledfuellstand = 41;

void setup() { 
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(durchfluss, INPUT);
pinMode(Notaus,INPUT);  
pinMode(tasterrechts,INPUT);
pinMode(lichschrankeoben,INPUT);
pinMode(pumpe,OUTPUT);
pinMode(ventil,OUTPUT);
motorlinks.attach(50);
motorrechts.attach(49);
motorlinks.write(90);
motorrechts.write(90);
digitalWrite(pumpe, LOW);
digitalWrite(ventil, LOW);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(ledfuellstand, OUTPUT);
}

void loop() {
durchflussstatus = digitalRead(durchfluss);
notausstatus = digitalRead(Notaus);
tasterstatus = digitalRead(tasterrechts);
tasterstatus2 = digitalRead(tasterlinks);
lichobenstatus = digitalRead(lichschrankeoben);
lichuntenstatus = digitalRead(lichschrankeunten);
long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  
if (distance < 15) {  // This is where the LED On/Off happens
    digitalWrite(ledfuellstand,LOW); // When the Red condition is met, the Green LED should turn off
}
if (distance > 15) {
    digitalWrite(ledfuellstand,HIGH);
  }
  
////////////////////////////////////////////////////////////////////////////////////////////////////////

if(notausstatus == HIGH) //Wenn Notaus nicht betätigt
{
  {
  lcd.clear();
  lcd.setCursor(0, 0);
  
  lcd.print("Anlage bereit");
  }
  if(tasterstatus == HIGH) //Anlage EIN
  {
  {
    lcd.clear();
  lcd.setCursor(0, 0);
  
  lcd.print("Anlage laeuft");
  }
  motorrechts.write(140); //Motor rechts starten
  motorlinks.write(140); //Motor links starten
  }

///////////////////////////////////////////////////////////////////////////////////////////////////////

  if(tasterstatus2 == HIGH) //Förderbandstopp
  {
  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  }
  
  if(lichobenstatus == LOW && lichuntenstatus == LOW) //Wenn Lichtschranke oben und unten unterbrochen, grosses glas füllen
  {
  digitalWrite(pumpe, HIGH); //Pumpe anschalten
  digitalWrite(ventil, HIGH); //Ventil öffnen
  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  
  if (durchflussstatus == HIGH) //Wenn durchflusssensor anspricht
  {  
  durchflussan = 1; //Hilfszeile
  }
  if (durchflussstatus == LOW && durchflussan == 1) //Wenn Hilfszeile und Durchflusssensor = 1
 {
   counter++; //Impulse Zählen
   durchflussan = 0; //Hilfszeile nullen
 }
  if (counter > 100) //Wenn der counter 100 Impulse gezählt hat
  {
  digitalWrite(pumpe, LOW); //Pumpe abschalten
  digitalWrite(ventil, LOW); //Ventil schliessen
  motorrechts.write(140); //Motor rechts starten
  motorlinks.write(140); //Motor links starten
  }
  
  Serial.println(counter); //Im serial monitor die Impulse ausgeben
}

  if(lichobenstatus == HIGH && lichuntenstatus == LOW) //Wenn Lichtschranke unten unterbrochen, kleines glas füllen
  {
  digitalWrite(pumpe, HIGH); //Pumpe anschalten
  digitalWrite(ventil, HIGH); //Ventil öffnen
  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  
  if (durchflussstatus == HIGH) //Wenn durchflusssensor anspricht
  {  
  durchflussan = 1; //Hilfszeile
  }        
  if (durchflussstatus == LOW && durchflussan == 1) //Wenn Hilfszeile und Durchflusssensor = 1
   counter++; //Impulse Zählen
   durchflussan = 0; //Hilfszeile nullen
 }
  if (counter > 50) //Wenn der counter 50 Impulse gezählt hat
  {
  digitalWrite(pumpe, LOW); //Pumpe abschalten
  digitalWrite(ventil, LOW); //Ventil schliessen
  motorrechts.write(140); //Motor rechts starten
  motorlinks.write(140); //Motor links starten
  }
  
  Serial.println(counter); //Im serial monitor die Impulse ausgeben
}
  if(lichobenstatus == HIGH && lichuntenstatus == HIGH) //Wenn beide Lichtschranken nicht unterbrochen sind
  {
  digitalWrite(pumpe, LOW); //Pumpe ausschalten
  digitalWrite(ventil, LOW); //Ventil schliessen
  }


if(notausstatus == LOW) //Wenn Notaus betätigt
{

  {
    lcd.setCursor(0, 0);
lcd.clear();
lcd.print("Notaus");

lcd.setCursor(0, 1);

lcd.print("betaetigt!");

  motorlinks.write(90); //Motor links stop
  motorrechts.write(90); //Motor rechts stop
  digitalWrite(pumpe, LOW); //Pumpe abschalten
  digitalWrite(ventil, LOW); //Ventil schliessen
  }

}
}

Zwei Dinge...

(Auch wenn ich dann pingelig erscheine)
Es gibt keine IF Schleifen.

Wenn Dinge nur ein mal erledigt werden sollen, sollte man ein Flag setzen und dann natürlich auch mal zwischendurch auswerten, bevor man das doppelt macht, was nicht doppelt gemacht werden soll.

Noch ein Tip:
Wenns zu viele IF-Verschachtelungen werden:

Nimm eine State machine (Zustandsautomat) das macht es oft einfacher.

Du beschreibst die Zustände, die deine Maschine haben kann, und mit welcher Bedingung sie in einen anderen Zustand kommen kann.
das kannst du dann mit Switch case umsetzen.

Zum Beispiel:
eine Zustandsmaschine für einen einfachen Getränkeautomat:
Zwischenablage02.jpg
den kann man so in Code umsetzen:

const byte START = 0;
const byte FUELLSTART = 1;
const byte FUELLEN = 2;
const byte VOLL = 3;

const boolean AN = true;
const boolean AUS = false;

int state = STATE_START;

switch (state){
  case START: 
    if (digitalread(STARTBUTTON)) {
      state = FUELLSTART;
      // lcd schreiben
    }
  break;
  
  case FUELLSTART:
    if (!Becher) {   
      // lcd schreiben "kein Becher"
    } else {
      state = FUELLEN;      
      // lcd schreiben "Füllen"
    }
    if (digitalread(NOTAUSBUTTON){
      ResetAll();
      state = START;  
    }
  break;
  
  case FUELLEN;
    Pumpenansteuerung(AN);
    if (MengeErreicht()){
      Pumpenansteuerung(AUS);
      state = VOLL;
    }
  break;
  
  case VOLL:
    // lcd schreiben "Becher entnehmen"
   if (!Becher) {
     state = START;
     // lcd schreiben "Knopf drücken"
   }    
  } // end switch