// Pin-Definitionen
const int startPin = 16; // Licht an (Start)
const int backPin = 17; // Licht aus (Back)
// Stepper 1
const int dirPin = 5; // Richtung Pin für Steppers 1
const int stepPin = 2; // Step Pin für Steppers 1
// Stepper 2
const int dirPin2 = 7; // Richtung Pin für Steppers 2
const int stepPin2 = 4; // Step Pin für Steppers 2
// Variablen für die Steuerung
const long stepsPerRevolution = 360; // Schritte pro Umdrehung
const long stepsTarget1 = 7200; // Ziel für Stepper 1 (bei Aktivierung)
const long stepsTarget2 = 3600; // Ziel für Stepper 2 (bei Aktivierung)
// Schrittzähler
long currentPosition = 0; // Position des ersten Steppers (0=Nullstellung)
long currentPosition2 = 0; // Position des zweiten Steppers (0=Nullstellung)
// Rücksetz-Schritte (nur bis Null)
const long stepsToReset1 = 7200; // Schritte, die Stepper 1 auf Null zurückdreht
const long stepsToReset2 = 3600; // Schritte, die Stepper 2 auf Null zurückdreht
// Flags für Steuerung
bool isRunning = false; // Bewegung läuft
bool resetting = false; // Rücksetzbewegung aktiv
bool backTriggered = false; // backPin ausgelöst
bool startPinLocked = false; // Sperre für Startpin
bool backPinLocked = false; // Sperre für Backpin
bool startPinActivated = false; // Startpin aktiv
bool backPinActivated = false; // Backpin aktiv
// Timing für nicht-blockierende Steuerung
unsigned long backTriggerTime = 0; // Zeitstempel bei backPin Aktivierung
unsigned long secondStepperStartTime = 0; // Startzeit für Verzögerung
unsigned long lastStepTime1 = 0; // Letzter Schritt für Stepper 1
unsigned long lastStepTime2 = 0; // Letzter Schritt für Stepper 2
// Parameter
const unsigned long stepInterval1 = 2; // Interval für Schritt 1 (Mikrosekunden)
const unsigned long stepInterval2 = 5; // Interval für Schritt 2 (Mikrosekunden)
const unsigned long delayForFirstStepper = 3000; // 3 Sekunden Verzögerung nach backPin (ms)
const unsigned long delaySecondStepper = 1500; // 1,5 Sekunden Verzögerung nach Start (ms)
void setup() {
pinMode(startPin, INPUT_PULLUP);
pinMode(backPin, INPUT_PULLUP);
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(dirPin2, OUTPUT);
pinMode(stepPin2, OUTPUT);
// Initiale Zustände
digitalWrite(dirPin, LOW);
digitalWrite(stepPin, LOW);
digitalWrite(dirPin2, LOW);
digitalWrite(stepPin2, LOW);
Serial.begin(9600);
}
void resetToInitial() {
// Alle Variablen und Pins auf Anfang setzen
currentPosition = 0;
currentPosition2 = 0;
isRunning = false;
resetting = false;
startPinLocked = false;
backPinLocked = false;
startPinActivated = false;
backPinActivated = false;
secondStepperStartTime = 0;
lastStepTime1 = 0;
lastStepTime2 = 0;
backTriggerTime = 0;
// Pins auf Anfangszustand
digitalWrite(dirPin, LOW);
digitalWrite(stepPin, LOW);
digitalWrite(dirPin2, LOW);
digitalWrite(stepPin2, LOW);
Serial.println("Internes Reset durchgeführt");
}
void loop() {
unsigned long currentTime = millis();
// 1. Start (Pin 12) aktivieren
if (digitalRead(startPin) == LOW && !startPinLocked && !startPinActivated && !isRunning && !resetting) {
startPinActivated = true;
startPinLocked = true; // Sperre nach Aktivierung
backPinLocked = false; // BackPin entsperren
isRunning = true; // Bewegung starten
Serial.println("Licht AN aktiviert");
}
// 2. Back (Pin 13) aktivieren
if (digitalRead(backPin) == LOW && !backPinLocked && !backPinActivated && !isRunning && !resetting) {
backPinActivated = true;
backPinLocked = true; // Sperre nach Aktivierung
startPinLocked = false; // Startpin entsperren
resetting = true; // Rücksetzbewegung starten
isRunning = false; // Bewegung stoppen
backTriggerTime = currentTime; // Zeitstempel
Serial.println("Licht AUS aktiviert");
}
// 3. Rücksetzvorgang (nur auf Null)
if (backPinActivated) {
// Schritt 1: Stepper 2 auf Null (rückwärts drehen), nur wenn noch nicht auf Null
if (currentPosition2 > 0) {
digitalWrite(dirPin2, LOW); // Rückwärts
if (currentTime - lastStepTime2 >= stepInterval2) {
// Schritt ausführen
digitalWrite(stepPin2, LOW);
delayMicroseconds(1500);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(1500);
currentPosition2--;
lastStepTime2 = currentTime;
}
} else {
currentPosition2 = 0; // sicherstellen
}
// Nach 3 Sekunden: Stepper 1 auf Null
if (currentTime - backTriggerTime >= delayForFirstStepper && currentPosition > 0) {
digitalWrite(dirPin, LOW); // Rückwärts
if (currentTime - lastStepTime1 >= stepInterval1) {
// Schritt ausführen
digitalWrite(stepPin, LOW);
delayMicroseconds(1800);
digitalWrite(stepPin, HIGH);
delayMicroseconds(1800);
currentPosition--;
lastStepTime1 = currentTime;
}
} else if (currentPosition <= 0) {
currentPosition = 0;
}
// Prüfen, ob beide auf Null sind
if (currentPosition == 0 && currentPosition2 == 0) {
// Rücksetzung beendet
backPinActivated = false;
resetting = false;
// Automatischer interner Reset
resetToInitial();
Serial.println("Rücksetzung auf Null abgeschlossen und intern zurückgesetzt");
}
}
// 4. Bewegung starten (wenn aktiv)
if (isRunning && !resetting) {
// Richtung vorwärts
digitalWrite(dirPin, HIGH);
digitalWrite(dirPin2, HIGH);
// Schritt für Stepper 1
if (currentTime - lastStepTime1 >= stepInterval1 && currentPosition < stepsTarget1) {
digitalWrite(stepPin, LOW);
delayMicroseconds(1800);
digitalWrite(stepPin, HIGH);
delayMicroseconds(1800);
currentPosition++;
lastStepTime1 = currentTime;
}
// Schritt für Stepper 2 nach Verzögerung starten
if (currentPosition2 < stepsTarget2) {
if (startPinActivated && secondStepperStartTime == 0) {
secondStepperStartTime = currentTime; // Startzeit für Verzögerung
lastStepTime2 = currentTime; // Initialisieren
}
if (secondStepperStartTime != 0 && (currentTime - secondStepperStartTime >= delaySecondStepper)) {
if (currentTime - lastStepTime2 >= stepInterval2 && currentPosition2 < stepsTarget2) {
// Schritt Stepper 2
digitalWrite(stepPin2, LOW);
delayMicroseconds(1500);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(1500);
currentPosition2++;
lastStepTime2 = currentTime;
}
}
}
// Ziel erreicht?
if (currentPosition >= stepsTarget1 && currentPosition2 >= stepsTarget2) {
isRunning = false; // Bewegung stoppen
Serial.println("Bewegung fertig");
}
}
// Rücksetzbewegung (auf Null) - falls aktiviert
if (resetting) {
// Immer rückwärts
digitalWrite(dirPin, LOW);
digitalWrite(dirPin2, LOW);
// Stepper 1: rückwärts bis 0
if (currentPosition > 0) {
if (currentTime - lastStepTime1 >= stepInterval1) {
digitalWrite(stepPin, LOW);
delayMicroseconds(1800);
digitalWrite(stepPin, HIGH);
delayMicroseconds(1800);
currentPosition--;
lastStepTime1 = currentTime;
}
} else {
currentPosition = 0;
}
// Stepper 2: rückwärts bis 0
if (currentPosition2 > 0) {
if (currentTime - lastStepTime2 >= stepInterval2) {
digitalWrite(stepPin2, LOW);
delayMicroseconds(1800);
digitalWrite(stepPin2, HIGH);
delayMicroseconds(1800);
currentPosition2--;
lastStepTime2 = currentTime;
}
} else {
currentPosition2 = 0;
}
// Prüfen, ob beide auf Null sind
if (currentPosition == 0 && currentPosition2 == 0) {
resetting = false;
Serial.println("Zurück auf Null abgeschlossen");
// Automatischer interner Reset
resetToInitial();
}
}
}