Ich hab mal was gebaut.
Ich hoffe es ausreichend kommentiert zu haben.
Mit den LED bin ich noch nciht durch.
In back2Home() musst Du sehen, ob ich richtig rum drehe. Wenn falsch, muss da rechts reingeschrieben werden 
Die Logik ist so gemacht, dass immer alle shots abgefragt werden und nicht nach einem Durchlauf wieder von vorn angefangen wird.
Sonst würden bei einem dauerndem Neuaufstellen von #1 und #2 die Shots dahinter nie voll werden 
Mit den LED's bin ich noch nciht ganz durch - aber mach mal erstmal, dass ich grobe Fehler ausschliessen kann.
/*
Stepper filling station by m0rph3xx https://forum.arduino.cc/u/morphexx/summary
Driver DRV8825 from AZ
*/
//----------------------------------------------------------------------------------------------------------------------
//STEPPER AND home_switch (MICROSWITCH)
#include <AccelStepper.h> // Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/
// Define a stepper and the pins it will use
#define dir_pin 2 // Pin 2 connected to DIR pin
#define step_pin 3 // Pin 3 connected to STP pin
// #define MS0 x // Pin x connected to MS1 pin
// #define MS1 x // Pin x connected to MS1 pin
// #define MS2 x // Pin x connected to MS2 pin
// #define SLEEP_PIN x // Pin x connected to SLEEP pin
AccelStepper stepper(AccelStepper::DRIVER, step_pin, dir_pin); // Pin 2 connected to STP pin and Pin 3 connected to DIR pin of AZ DRV8825
// pinMode(MS0, OUTPUT);
// pinMode(MS1, OUTPUT);
// pinMode(MS2, OUTPUT);
// pinMode(SLEEP_PIN, OUTPUT);
// digitalWrite(SLEEP_PIN, HIGH); // Wake up AZ DRV8825
// delay(5); // Wait for stepper driver wake up
/* Configure type of Steps on AZ DRV8825:
The DRV8825 driver has three input pins for microstep resolutions:
" MS0
" MS1
" MS2
By setting appropriate logic levels on these pins, we can set the drive mode of the motor to
drive mode of the motor to one of these six modes:
M0 M1 M2 Microstep resolution
LOW LOW LOW Full step
HIGH LOW LOW Half step
LOW HIGH LOW Quarter step
HIGH HIGH LOW Eighth step
LOW LOW HIGH Sixteenth step
HIGH LOW HIGH 1/32 step
LOW HIGH HIGH 1/32 step
HIGH HIGH HIGH 1/32 step
Remember that you don’t need to manually set the pins
The DRV8825 handles this configuration for you based on the desired mode.
Alternatively, to save pins on the microcontroller, the modes can be permanently connected
via the 5V pin of the controller (5V=HIGH, disconnected=LOW).
*/
// digitalWrite(MS0, LOW); // Configures to Full Steps
// digitalWrite(MS1, LOW); // Configures to Full Steps
// digitalWrite(MS2, LOW); // Configures to Full Steps
//----------------------------------------------------------------------------------------------------------------------
// Start homing of stepper motor at startup
// REED SWITCH AND LED and Number of steps for positions 1-5 of the shot glasses
constexpr byte shotNums {5};
struct SHOT
{
const byte switchPin;
const byte ledPin;
const uint16_t position;
bool isFilled;
uint32_t ledTime;
} shot[shotNums] =
{
{4, A1, 90, false, 0,},
{5, A2, 165, false, 0,},
{6, A3, 240, false, 0,},
{7, A4, 315, false, 0,},
{8, A5, 395, false, 0,},
};
//RELAY AND BUTTON
constexpr byte relayPin {9}; //PIN RELAY - Relay requires 5V
constexpr byte homePin {10}; //PIN home switch (MICROSWITCH) - Pin to set home/zero for stepper after startup/reset
constexpr byte prefillPin {11}; //PIN BUTTON GREY - Pin to activate the relay (pump) manually via grey foil button
constexpr bool relayOn{ HIGH }; // Turn relay on
constexpr bool relayOff{ !relayOn }; // Turn relay off
constexpr bool ledOn{ HIGH };
constexpr bool ledOff{ !ledOn };
constexpr bool rechts { LOW };
constexpr bool links (!rechts);
enum class STATUS // was es alles so gibt
{
waitToStart, // Tastenabfrage für Start
prefill, //
fillpos,
filling,
fillend,
homepos,
backtohome,
};
STATUS status = STATUS::waitToStart;
byte activeShot;
uint32_t switchTime;
constexpr uint32_t fillTime {2000};
constexpr uint32_t pauseTime {800};
//----------------------------------------------------------------------------------------------------------------------
void setup()
{
//STEPPER HOMING WITH home_switch - Enable internal pull-up for the switch
pinMode(homePin, INPUT_PULLUP);
pinMode(dir_pin, OUTPUT);
pinMode(step_pin, OUTPUT);
stepper.setMaxSpeed(1000); // Set Maximum Speed of stepper (Slower to get better accuracy)
stepper.setAcceleration(400); // Set acceleration of stepper
//----------------------------------------------------------------------------------------------------------------------
// REED SWITCH AND LED - Enable internal pull-up for the reed switch - LED on
for (byte b = 0; b < shotNums; b++)
{
pinMode(shot[b].switchPin, INPUT_PULLUP);
pinMode(shot[b].ledPin, OUTPUT);
digitalWrite(shot[b].ledPin, ledOn);
}
//----------------------------------------------------------------------------------------------------------------------
// RELAY AND BUTTON - Enable internal pull-up for the button
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, relayOff); // Turn the RELAY off
pinMode(prefillPin, INPUT_PULLUP);
//
back2Home(); // -> Ausgangsstellung und Nullpunkt setzen
}
void loop()
{
fillingGlass();
}
void fillingGlass()
{
switch (status)
{
case STATUS::waitToStart: // Ausgangslage
allLed(ledOn); //
if (!digitalRead(prefillPin)) //
{
allLed(ledOff); // Visualisierung
// nur in der Ausgangslage prefill ausführbar!
if (back2Home) // fährt gesichert in Ausgangsposition
{
digitalWrite(relayPin, relayOn); //
status = STATUS::prefill;
}
}
else // Nicht im Vorfüllmodus
{
if (!digitalRead(shot[activeShot].switchPin)) // Glas steht drauf
{
if (!shot[activeShot].isFilled) // Es ist nicht besetzt
{
stepper.moveTo(shot[activeShot].position); // aktivieren
shot[activeShot].isFilled = true; // Merken
switchTime = millis(); // Startzeit
status = STATUS::fillpos; // Nächsten Schritt
}
}
else // Glas steht nicht drauf
{
shot[activeShot].isFilled = true; // Merker löschen
if (++activeShot >= shotNums) // Nächstes Glas auswählen
{ activeShot = 0; } // Am Ende von vorn anfangen
}
}
break;
case STATUS::prefill:
for (byte b = 0; b < shotNums; b++) // Visualisierung
{ ledBlink(150); }
if (digitalRead(prefillPin)) // Button nicht gedrückt
{
digitalWrite(relayPin, relayOff); //
status = STATUS::waitToStart; // gehe in Ausgangszustand
}
break;
case STATUS::fillpos:
ledBlink(70); // Kleines blinkblink AuslaufLED
if (millis() - switchTime > pauseTime) // Zwangspause abgelaufen
{
digitalWrite(relayPin, relayOn); // Füllen starten
switchTime = millis(); // Startzeit merken
status = STATUS::filling; // Nächster Schritt
}
break;
case STATUS::filling:
ledBlink(200); // blinkblink
if (millis() - switchTime > fillTime) // Füllzeit abgelaufen
{ status = STATUS::fillend; } // Nächster Schritt
break;
case STATUS::fillend:
digitalWrite(shot[activeShot].ledPin, ledOff); // gesichert AUS machen
digitalWrite(relayPin, relayOff); // Füllen beenden
switchTime = millis(); // merken
status = STATUS::homepos; // nächster Schritt
break;
case STATUS::homepos:
if (millis() - switchTime > pauseTime) // Zwangspause -> es tropft nach!
{ status = STATUS::waitToStart; } // fange an von Vorn
break;
}
stepper.runToPosition();
}
//
bool back2Home() //
{
while (digitalRead(homePin)) // Microtaster nicht ausgelöst
{
digitalWrite(dir_pin, links); // Stepper Richtung Endanschlag
oneStep(); // Ein Stück fahren
stepper.setCurrentPosition(0); // Null- / Startpunkt
}
stepper.moveTo(0); // Feststellen
return !digitalRead(homePin); // gibt true zurück, wenn ausgelöst
}
//
void oneStep() // Macht wie es heisst
{
digitalWrite(step_pin, HIGH);
delay(5);
digitalWrite(step_pin, LOW);
delay(5);
}
//
void ledBlink(const byte blinkTime) //
{
if (millis() - shot[activeShot].ledTime > blinkTime)
{
digitalWrite(shot[activeShot].ledPin, !digitalRead(shot[activeShot].ledPin));
shot[activeShot].ledTime = millis();
}
}
//
void allLed(bool state)
{
for (byte b = 0; b < shotNums; b++)
{
digitalWrite(shot[b].ledPin, state);
shot[b].ledTime = millis();
}
}