Mehrere Taster für verschiedene Aufgaben

Hallo zusammen,

wir bauen gerade einen Barbot (Cocktailmaschine) und haben dabei ein kleines Problem.
Wir würden gerne über verschiedene Taster diverse Cocktails auswählen können.
Mit einem Taster und somit auch einem Cocktail ist das ganze kein Problem und funktioniert super,
aber sobald wir den 2. Cocktail auswählen läuft dieser sozusagen endlos durch und stoppt nicht mehr.

Danke schon mal für Anregungen und Tipps!

Viele Grüße
Jul_ino

#include <AccelStepper.h>
#include <PololuMaestro.h>
#include <SoftwareSerial.h>

#define motorInterfaceType 1
#define dirPin 2                // Richtung Schrittmotor
#define stepPin 3               // Schritte Schrittmotor
#define stopPin 8               // Endschalter
#define cocktail_1 11           // Taster für Cocktail 1
#define cocktail_2 12           // Taster für Cocktail 2
#define cocktail_3 13           // Taster für Cocktail 3

int sensorValue8 =  0;          // Endschalter (Nullpunkt)
int sensorValue11 = 0;          // Cocktail 1
int sensorValue12 = 0;          // Cocktail 2
int sensorValue13 = 0;          // Cocktail 3
int pos0 = 0;                   // Ausgangspunkt
int pos1 = -20;                 // Flasche 1
int pos2 = -620;                // Flasche 2
int pos3 = -1220;               // Flasche 3
int pos4 = -1820;               // Flasche 4
int pos5 = -2420;               // Flasche 5 
int pos6 = -3020;               // Flasche 6
int pos7 = -3620;               // Flasche 7

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
SoftwareSerial maestroSerial(19, 18);
MicroMaestro servo(maestroSerial);

void setup() {
  pinMode(dirPin, OUTPUT);      // Ausgang Richtung Schrittmotor
  pinMode(stepPin, OUTPUT);     // Ausgang Schritte Schrittmotor
  pinMode(stopPin, INPUT);      // Eingang Endschalter
  pinMode(cocktail_1, INPUT);   // Eingang Pin 11
  pinMode(cocktail_2, INPUT);   // Eingang Pin 12
  pinMode(cocktail_3, INPUT);   // Eingang Pin 13
  
  stepper.setMaxSpeed(600);
  stepper.setAcceleration(400);
  maestroSerial.begin(9600);
}

void loop() {
  sensorValue8 = digitalRead(stopPin);
  stepper.setSpeed(400);
  stepper.runSpeed();
  
  while (sensorValue8 == HIGH) {
    stepper.setCurrentPosition(pos0);
  }
 
  sensorValue11 = digitalRead(cocktail_1);    
    
  while (sensorValue11 == HIGH) {             // Taster für Cocktail startet Schleife
    stepper.moveTo(pos1);                     // Schrittmotor fährt zu pos1 bzw. Flasche 1
    stepper.runToPosition();
    delay(1000);                              // Pause von 1 Sekunde
    servo.setTarget(0, 4500);                 // Servomotor betätigt Dosierer
    delay(3000);                              // Servomotor hält Position für 3 Sekunden
    servo.setTarget(0, 7000);                 // Servomotor wechselt in Ausgangsposition zurück
    delay(1000);                              // Pause von 1 Sekunde
  
    stepper.moveTo(pos2);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
  
    stepper.moveTo(pos3);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);   
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);

    stepper.moveTo(pos5);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);   
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);

    stepper.moveTo(pos7);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
      
    stepper.moveTo(pos0);
    stepper.runToPosition();
    sensorValue11 = digitalRead(cocktail_1); 
    }

  sensorValue12 = digitalRead(cocktail_2);
    
  while (sensorValue12 == HIGH) {
    stepper.moveTo(pos4);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
      
    stepper.moveTo(pos5);
    stepper.runToPosition();
    delay(1000); 
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
  
    stepper.moveTo(pos6);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
      
    stepper.moveTo(pos0);
    stepper.runToPosition();
    sensorValue12 = digitalRead(cocktail_2);
    }

  sensorValue13 = digitalRead(cocktail_3);
  
  while (sensorValue13 == HIGH) {
    stepper.moveTo(pos1);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);

    stepper.moveTo(pos4);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);

    stepper.moveTo(pos7);
    stepper.runToPosition();
    delay(1000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(3000);
    servo.setTarget(0, 4500);
    delay(3000);
    servo.setTarget(0, 7000);
    delay(1000);
    
    stepper.moveTo(pos0);
    stepper.runToPosition();
    sensorValue13 = digitalRead(cocktail_3);
  }
}

Barbot.ino.ino (5.26 KB)

(deleted)

@TO: Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Nein die Variable wird nicht gelöscht.
Eine while-Schleife macht doch nur etwas, wenn man ihr den Befehl gibt,
ansonsten dürfte das doch gar nicht durchlaufen, oder?

ansonsten dürfte das doch gar nicht durchlaufen, oder?

Und wenn sie mal läuft, die Schleife, kommt sie nie nicht zum Ende!

Also läuft sie nie und nimmer nicht durch.
Dann kann sie auch weg.

Nun haben wir nur noch ein Problem und zwar das die Schleife ununterbrochen durchläuft, wie kann ich dies nach einmaligem Durchlaufen beenden?

#include <AccelStepper.h>
#include <PololuMaestro.h>
#include <SoftwareSerial.h>

#define motorInterfaceType 1
#define dirPin 2                // Richtung Schrittmotor
#define stepPin 3               // Schritte Schrittmotor
#define stopPin 8               // Endschalter
#define cocktail_1 11           // Taster für Cocktail 1 Pin 11
#define cocktail_2 12           // Taster für Cocktail 2 Pin 12
#define cocktail_3 13           // Taster für Cocktail 3 Pin 13

int sensorValue8 =  0;          // Endschalter (Nullpunkt)
int sensorValue11 = 0;          // Cocktail 1
int sensorValue12 = 0;          // Cocktail 2
int sensorValue13 = 0;          // Cocktail 3
int pos0 = 0;                   // Ausgangspunkt
int pos1 = -20;                 // Flasche 1
int pos2 = -620;                // Flasche 2
int pos3 = -1220;               // Flasche 3
int pos4 = -1820;               // Flasche 4
int pos5 = -2420;               // Flasche 5 
int pos6 = -3020;               // Flasche 6
int pos7 = -3620;               // Flasche 7

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
SoftwareSerial maestroSerial(19, 18);
MicroMaestro servo(maestroSerial);

void setup() {
  pinMode(dirPin, OUTPUT);      // Ausgang Richtung Schrittmotor
  pinMode(stepPin, OUTPUT);     // Ausgang Schritte Schrittmotor
  pinMode(stopPin, INPUT);      // Eingang Endschalter
  pinMode(cocktail_1, INPUT);   // Eingang Pin 11
  pinMode(cocktail_2, INPUT);   // Eingang Pin 12
  pinMode(cocktail_3, INPUT);   // Eingang Pin 13
  
  stepper.setMaxSpeed(600);
  stepper.setAcceleration(400);
  maestroSerial.begin(9600);
}

void loop() {
  sensorValue8 = digitalRead(stopPin);
  stepper.setSpeed(400);
  stepper.runSpeed();

  sensorValue8 = digitalRead(stopPin);
  sensorValue11 = digitalRead(cocktail_1);
  
  if(sensorValue8 == HIGH) {
    stepper.setCurrentPosition(pos0);
    sensorValue8 = digitalRead(stopPin);
  }
// Cocktail 1
    sensorValue11 = digitalRead(cocktail_1);    
       
  while (sensorValue11 == HIGH) {             // Taster für Cocktail startet Schleife
    stepper.moveTo(pos1);                     // Schrittmotor fährt zu pos1 bzw. Flasche 1
    stepper.runToPosition();
    delay(1000);                              // Pause von 1 Sekunde
    servo.setTarget(0, 4500);                 // Servomotor betätigt Dosierer
    delay(3000);                              // Servomotor hält Position für 3 Sekunden
    servo.setTarget(0, 7000);                 // Servomotor wechselt in Ausgangsposition zurück
    delay(1000);                              // Pause von 1 Sekunde
  
    stepper.moveTo(pos2);                     // Schrittmotor fährt zu pos2 bzw. Flasche 2
    stepper.runToPosition();
    delay(1000);                              // Pause von 1 Sekunde
    servo.setTarget(0, 4500);                 // Servomotor betätigt Dosierer
    delay(3000);                              // Servomotor hält Position für 3 Sekunden
    servo.setTarget(0, 7000);                 // Servomotor wechselt in Ausgangsposition zurück
    delay(1000);                              // Pause von 1 Sekunde
  }
}

Hallo,

Wozu überhaupt die while schleife ?

Durch Euren Spagetti Code durchzublicken macht irgendwie keinen Spaß.

Erst mal die Frage, wie habt Ihr die Taster angeschlossen. Es sieht so aus als würden sie plus schalten, dann ist ein externer Pull-down Widerstand z.B 4,7KOhm erforderlich.

Dann solltet Ihr ein paar Komentare verwenden damit klar wird was da passieren soll. Die 3 "Programme" könnte man in je eine eigene Funktion schreiben, damit das etwas übersichtlicher wird. Sinnvoll wäre auch eine Status-Variable für jeden Taster, die wird dann zurück gesetzt wenn das Programm beendet ist, damit hätte man die Chance die delays durch millis zu ersetzen. Und natürlich schreit das Ganze eigendlich nach einer Statemaschine, Schrittkette oder wie immer Ihr das nennen wollt.

hier mal ein Ansatz

Nachtrag habe dieKommentare gefunden :wink:

// Taster schalten plus externer pulldown erforderlich

const byte taster1 = 2;
const byte taster2 = 3;
bool status1, status2; // StatusVariable

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(taster1, INPUT);
  pinMode(taster2, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

  if (digitalRead(taster1)) { // Taster 1 abfragen
    status1 = true;
  }

  if (digitalRead(taster2)) { // Taster 2 abfragen
    status2 = true;
  }

  // Verzweigung zum Program
  if (status1) program1();
  else if (status2) program2();

}

// --- Pogramm 1----
void program1() {
  // hier program 1
  Serial.println("Program 1");
  delay(1000);
  status1 = false;
}
// ---- Program 2----
void program2() {
  // hier program 2
  Serial.println("Program 2");
  delay(1000);
  status2 = false;
}

Das wurde dir doch schon geschrieben: Das while ist das Problem. Und Du schreibst es auch noch selbst hin:

while (sensorValue11 == HIGH) {             // Taster für Cocktail startet Schleife

Du startest die Schleife, und dann 'schleift' die auch. Was soll sie sonst machen, da sensorValue1 niemals wieder LOW wird?.
Du brauchst doch keine Schleife um einen Cocktail zu mixen.
N.B. das mit den delay() ist auch nicht das gelbe vom Ei, Du kannst so z.B. den Ablauf nie abbrechen. Besser wäre einen 'State machine', auch 'Endlicher Automat' genannt. Für deinen Mixer auch in der einfachen Form einer 'Schrittkette' ausreichend ( ist aber letztendlich auch ein endlicher Automat )

P.S. statt die sensor-Variablen durchzunummerieren und nur im Kommentar zu schreiben was sie bewirken sollen, könnte man sie gleich auch entsprechend benennen.