AccelStepper stepper.run bekomme ich nicht ans Laufen

Hallo zusammen,

ich baue gerade einen Tumbler (Poliertrommel) die mit einem Stepper angetrieben wird.
Dafür hab ich mir einen Sketch für nen ESP8266 geschrieben.
Dieser funktioniert soweit eigentlich auch.
Bis auf das er im void loop() den stepper.run() mehr als einmal ausführt.
Sprich er macht genau nur einen Schritt und mir ist nicht klar warum ?
In einem kleinen Test-Sketch wo nur die Ansteuerung des Motors implementiert ist funktioniert es jedoch.

Vielleicht kann mir jemand den entscheidenden Tip geben wo mein Fehler liegt :wink:

Hier der Test-Sketch:

#include <AccelStepper.h>

// Ausgänge
  #define MOTOR_DIRECTION_PIN 13  //D7
  #define MOTOR_ENABLE_PIN 15  //Enable D8
  #define MOTOR_STEP_PIN 16  // Step D0

  #define START_TASTER 0 // Start Button D3
  int actSTART_TASTER;
    
    #define BESCHLEUNIGUNG 1200  // Start/Stop BESCHLEUNIGUNG in ms
    #define STEPS_PER_UMDREHUNG 1600 // Anzahl der Pulse pro 1 Umdrehung
    int drehzahl = 40;    // U/min nach Encoder
    int laufzeit = 1;   // Zeit in Minuten nach Encoder die der Tumbler laufen soll
    int geschwindigkeit; // Steps per Sec
    int long stepsToGo =0; // Steps die zu laufen sind


// Define a stepper and the pins it will use
    AccelStepper stepper(AccelStepper::DRIVER, MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN); 

void setup()
{
      Serial.begin(115200);
        pinMode(START_TASTER, INPUT); // Setzt den Pin für den Start-Taster auf Input
        pinMode(MOTOR_ENABLE_PIN, OUTPUT); // Setzt den Pin für die Direction des Motors auf Output 
    geschwindigkeit = (STEPS_PER_UMDREHUNG/60*drehzahl); // Steps per Sec
    stepsToGo = (STEPS_PER_UMDREHUNG*drehzahl*laufzeit); // Steps die zu laufen sind
      delay(1000);
  
  // Change these to suit your stepper if you want
    stepper.setMaxSpeed(geschwindigkeit);
    stepper.setAcceleration(BESCHLEUNIGUNG);
    stepper.move(stepsToGo);
}
void Steht()
  {
    Serial.println("Steht");
    delay(50);
    digitalWrite(MOTOR_ENABLE_PIN, HIGH); // turn Enable ON
    delay(50);
    while (digitalRead(START_TASTER==HIGH))
      {
        delay(100);
      }
    delay(100);
    digitalWrite(MOTOR_ENABLE_PIN, LOW); // turn Enable Off
    stepper.setCurrentPosition(0);
    stepper.moveTo(stepsToGo);
    }

void loop()
{
//      Serial.println(stepper.currentPosition());
    if (stepper.distanceToGo() == 0)
        Steht();  //Sprung ins void Steht
    stepper.run();
}

Und hier mein "fertiger" Sketch:

#include <AccelStepper.h>
#include <Math.h>
#include <Encoder.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

// Ausgänge
  #define MOTOR_DIRECTION_PIN 13  //D7
  #define MOTOR_ENABLE_PIN 15  //Enable D8
  #define MOTOR_STEP_PIN 16  // Step D0

// Eingänge
  #define START_TASTER 0 // Start Button D3
//  #define STOP_TASTER 3 // Stop Button RXD0
  #define ENCODER_SWITCH 2 // Switch Encoder D4
  
// Variablen
  // debug
    int debug = 0; // 0= aus, 1 = ???, 2= serial.print encoderwerte, 3= serial.print variablen 
  //Buttons
    int buttonStatus1=0; 
    int buttonStatus2=0; 
  // voids
    bool drehen;
    int actSTART_TASTER;
 //Stepper
    #define BESCHLEUNIGUNG 1200  // Start/Stop BESCHLEUNIGUNG in ms
    #define STEPS_PER_UMDREHUNG 1600 // Anzahl der Pulse pro 1 Umdrehung
    int drehzahl;    // U/min nach Encoder
    int laufzeit;   // Zeit in Minuten nach Encoder die der Tumbler laufen soll
    int geschwindigkeit; // Steps per Sec
    int long stepsToGo =0; // Steps die zu laufen sind
    AccelStepper stepper(AccelStepper::DRIVER, MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
 // rotary encoder
    Encoder myEnc(14, 12); // CLK = 14 / D5 und DT 12 / D6
    int oldEncoderPositionDrehzahl  = 42; //EingabeStartDrehzahl
    int oldEncoderPositionLaufzeit  = 2;  //EingabeStartZeit
    int actEncoderPosition =0;
    int actENCODER_SWITCH;

// LCD Display
    LiquidCrystal_I2C lcd(0x27, 20, 4); // Initialisiert das LCD mit Addresse 0x27 und 20 Zeichen und 2 Zeilen


void setup()
  {
    Serial.begin(9600);
    Serial.println("im void setup angekommen");
//Pins
    //Stepper
        pinMode(MOTOR_STEP_PIN, OUTPUT); // Setzt den Pin für den Step des Motors auf Output
        pinMode(MOTOR_DIRECTION_PIN, OUTPUT); // Setzt den Pin für die Direction des Motors auf Output 
        pinMode(MOTOR_ENABLE_PIN, OUTPUT); // Setzt den Pin für den Enable des Motors auf Output 
    //Taster
        pinMode(START_TASTER, INPUT); // Setzt den Pin für den Start-Taster auf Input
    //    pinMode(STOP_TASTER, INPUT); // Setzt den Pin für den Stop-Taster auf Input
        pinMode(ENCODER_SWITCH, INPUT_PULLUP); // Setzt den Pin für den Taster des Encodersauf Input mit Pullup-Wiederstand
//Stepper
    stepper.setMaxSpeed(geschwindigkeit);
    stepper.setAcceleration(BESCHLEUNIGUNG);
    stepper.moveTo(stepsToGo);
    digitalWrite(MOTOR_ENABLE_PIN, HIGH); // turn Enable ON
//Display
    lcd.begin();
    lcd.backlight();  // Turn on the blacklight and print a message.
    lcd.clear();  //Löscht Display
    lcd.setCursor(3, 0);//Hier wird die Position des ersten Zeichens festgelegt. In diesem Fall bedeutet (0,0) das erste Zeichen in der ersten Zeile. 
    lcd.print("Willkommen bei"); 
    lcd.setCursor(2, 1);// In diesem Fall bedeutet (0,1) das erste Zeichen in der zweiten Zeile. 
    lcd.print("Andis Tumbler V1");
    lcd.setCursor(7, 2);// In diesem Fall bedeutet (5,2) das fünfte Zeichen in der dritten Zeile. 
    lcd.print("weiter");
    lcd.setCursor(2, 3);// In diesem Fall bedeutet (0,3) das erste Zeichen in der vierten Zeile. 
    lcd.print("mit Start-Taste");
//warten auf StartTaster drücken
    while (digitalRead(START_TASTER==HIGH))
      {
        delay(50);
      }
    lcd.clear();
//Sprung ins viod StartStop und start des Ablaufs
    StartStop(); // Aufruf void StartStop
  }

void StartStop()
   {
    Serial.println("im void StartStop angekommen");
    digitalWrite(MOTOR_ENABLE_PIN, HIGH); // turn Enable ON
    Serial.println("Sprung ins void Drehzahl");
    delay(200);
    Drehzahl(); // Sprung ins void Drehzahl
    Serial.println("zurück aus dem void Drehzahl");
    Serial.println("Sprung ins void Zeit");
    delay(200);
    Zeit(); // Sprung ins void Zeit
    Serial.println("zurück aus dem void Zeit");
//Debug
  if (debug == 3)
      {
        Serial.print("zurück nach void Drehzahl und void Zeit");
        Debug3();
      }
// schreibe Display
  lcd.clear();
  lcd.setCursor(8, 1);  //Pos 4, Zeile 1
  lcd.print("Bitte"); 
  lcd.setCursor(3, 2); //Pos 0, Zeile 1
  lcd.print("Start druecken");
//warten auf StartTaster drücken
    while (digitalRead(START_TASTER==HIGH))
      {
        drehen=false;
        delay(10);
      }
    drehen=true;
  //Sprung ins void Lauft
    Lauft();
//Debug
if (debug == 3)
      {
        Serial.println("Nach Starttaster");
        Debug3();
      }
   }

void Drehzahl()
  {
    Serial.println("im void Drehzahl angekommen");
    long newEncoderPosition;
    delay(200);
    actENCODER_SWITCH = digitalRead(ENCODER_SWITCH);  //liest Switch Eingang vom Encoder
    delay(50);
    myEnc.write(0); //setzte Encoder Eingänge
    lcd.clear();  //löscht LCD
//liest Encoder Eingänge und addiert zwischen Wert a und b
    while ((newEncoderPosition != oldEncoderPositionDrehzahl) && (actENCODER_SWITCH == HIGH))
      {
        newEncoderPosition = myEnc.read();
        actEncoderPosition = oldEncoderPositionDrehzahl+(newEncoderPosition/4);
        if (actEncoderPosition <= 30)
          {
            actEncoderPosition = 30;
           }
        if (actEncoderPosition >= 60)
          {
            actEncoderPosition =60;
           }
// schreibe Display
        lcd.setCursor(3, 1);  //Pos 0, Zeile 1
        lcd.print("Drehzahl: "); 
        lcd.setCursor(15, 1);  // ab Pos 12, Zeile 2 leeren
        lcd.print("    "); 
        lcd.setCursor(15, 1); //Pos 12, Zeile 1 
        lcd.print(actEncoderPosition);
//Debug
        if (debug == 2)
            {
              Debug2();
            }
//warte auf Switch vom Encoder
        actENCODER_SWITCH = digitalRead(ENCODER_SWITCH);
        if (actENCODER_SWITCH == LOW)
            {
              delay(200);
              drehzahl = actEncoderPosition;
            }
        delay(50);
      }
    Serial.println("void Drehzahl ENDE Ruecksprung nach StartStop");
//Rücksprung ins void StartStop
  }

void Zeit()
  {
    Serial.println("im void Zeit angekommen ;-)");
    long newEncoderPosition2;
    delay(200);
    actENCODER_SWITCH = digitalRead(ENCODER_SWITCH);  //liest Switch Eingang vom Encoder
    delay(50);
    myEnc.write(0); //setzte Encoder Eingänge
//liest Encoder Eingänge und addiert zwischen Wert a und b
    while ((newEncoderPosition2 != oldEncoderPositionLaufzeit) && (actENCODER_SWITCH == HIGH))
      {
        newEncoderPosition2 = myEnc.read();
        actEncoderPosition = oldEncoderPositionLaufzeit+(newEncoderPosition2/4);
        if (actEncoderPosition <= 2)
          {
            actEncoderPosition = 2;
          }
        if (actEncoderPosition >= 120)
          {
            actEncoderPosition =120;
          }
//schreibe Display
        lcd.setCursor(3, 2);  //Pos 0, Zeile 2
        lcd.print("Zeit: "); 
        lcd.setCursor(15, 2);  // ab Pos 12, Zeile 2 leeren
        lcd.print("    "); 
        lcd.setCursor(15, 2); //Pos 12, Zeile 2
        lcd.print(actEncoderPosition);
//Debug
        if (debug == 2)
            {
              Debug2();
            }
//warte auf Switch vom Encoder
        actENCODER_SWITCH = digitalRead(ENCODER_SWITCH);
          if (actENCODER_SWITCH == LOW)
              {
                delay(200);
//berechne Umdrehungszahl und Laufzeit des Tumblers
                laufzeit = actEncoderPosition;
                geschwindigkeit = (STEPS_PER_UMDREHUNG/60*drehzahl); // Steps per Sec bzw. Umdrehungen des Tumblers
                stepsToGo = (STEPS_PER_UMDREHUNG*drehzahl*laufzeit); // Steps die zu laufen sind bzw. Laufzeit in Min.
              }
        delay(50);
      }
    Serial.println("void Zeit ENDE");
//Rücksprung ins void StartStop
  }


void Steht()
  {
    Serial.println("im void Steht angekommen");
//Debug
    if (debug == 3)
          {
            Debug3();
          }
//schreibe Display
      lcd.clear();
      lcd.setCursor(5, 0);  //Pos 0, Zeile 1
      lcd.print("Tumbler ist"); 
      lcd.setCursor(7, 1); //Pos 5, Zeile 1 
      lcd.print("fertig");
      lcd.setCursor(5, 2);  //Pos 0, Zeile 1
      lcd.print("weiter mit"); 
      lcd.setCursor(5, 3); //Pos 5, Zeile 1 
      lcd.print("Start Taste");
// setzte Enable HIGH damit Motor entsperrt ist
      digitalWrite(MOTOR_ENABLE_PIN, HIGH); // turn Enable ON
//warten auf StartTaster drücken
    delay(200);
    while (digitalRead(START_TASTER==HIGH))
      {
        delay(50);
    }
//Rücksprung ins void StartStop
    StartStop();
  }

void Debug2()
  {
    Serial.print("Encoder Wert =  ");
    Serial.println(actEncoderPosition);
  }
  
void Debug3()
  {
    Serial.print("drehzahl =");
    Serial.println(drehzahl);
    Serial.print("laufzeit =");
    Serial.println(laufzeit);
    Serial.print("geschwindigkeit=");
    Serial.println(geschwindigkeit);
    Serial.print("stepsToGo=");
    Serial.println(stepsToGo); 
  }

void Lauft() 
 {
   Serial.println("im void Lauft angekommen");
//Debug
  if (debug == 3)
      {
        Serial.println("im void loop angekommen");
        Debug3();
      }
//schreibe Text läuft
    lcd.clear();
    lcd.setCursor(7, 0);  //Pos 0, Zeile 1
    lcd.print("Tumbler"); 
    lcd.setCursor(7, 1); //Pos 5, Zeile 1 
    lcd.print("laeuft");
    lcd.setCursor(0, 3); //Pos 0, Zeile 4 
    lcd.print("Restlaufzeit=");
    lcd.setCursor(13, 3); //Pos 14, Zeile 4 
    lcd.print("123");
    lcd.setCursor(17, 3); //Pos 17, Zeile 4 
    lcd.print("Min");
// Enable setzen
    digitalWrite(MOTOR_ENABLE_PIN, LOW); // turn Enable ON
// setzte Motor currentPosition auf 0 und übergebe dem stepper die Anzahl der Schritte die zu laufen sind
    stepper.setCurrentPosition(0);
    stepper.moveTo(stepsToGo);
    delay(150);
    loop();
 }
void loop()
  {
// starte Stepper
    stepper.run();
//    Serial.println("im void loop angekommen");
//    Serial.println(stepper.currentPosition());
//    Serial.println(stepper.distanceToGo());
// wenn der Stepper noch Schritte zu gehen hat dann bleib im loop
      actSTART_TASTER = digitalRead(START_TASTER);
      if (actSTART_TASTER == LOW)
      {
        Serial.println("Start Taster zum stopppen gedrückt");
        Steht();  //Sprung ins void Steht
      }
    if (stepper.distanceToGo() == 0)
      {
        Steht();  //Sprung ins void Steht
      }

  } //Ende void loop

Ich danke schon mal im Voraus für die Hilfe

Wieso benutzt Du für sowas einen Stepper? Stepper sind extrem ineffiziente Motoren, die das nur dadurch wettmachen, dass man sie genau positionieren kann. Wo man diese Positionierung nicht braucht und nur 'einfach drehen' will sind sie nur einfach ineffizient, da ist ein DC-Motor wesentlich besser.

Ich sehe in deinem 2. Sketch nicht, wo Du die Geschwindgkeit des Steppers setzt. Einmal am Anfang des Setup, da ist 'geschwindigkeit' aber noch 0. Und dann nie mehr.

Weil ich den Stepper da habe und mich generell mit Steppern auseinandersetzten will.

Danke !
Du hast mir den entscheidenden Tip gegeben !

Ich habe zwar die Variable geschwindigkeit() berechnet aber hinterher nicht mehr der stepper.setMaxSpeed() zugewiesen.

Das hätte ich in den letzte 2 Nächten auch selbst finden können/müssen.

Vielen Dank für die schnelle Hilfe.

Ein Klassiker. Manchmal sieht man halt den Wald vor lauter Bäumen nicht :wink:

Und ich bin kein Programmierer :wink:
Ich bin eher der Mc Gyver :joy:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.