Accelstepper Hilfe

Hallo,

ich habe mir mit "MIT App inventor 2" ein Programm geschrieben, mit dem ich Befehle (in dem Fall Buchstaben) per Bluetooth an den Arduino senden kann. Das funktioniert soweit auch. Wenn ich Homen drücke, sendet das Programm ein "h" und der Arduino dreht den Motor bis ich einen Taster betätige und fährt dann kurz zurück. Allerings, wenn ich "Vorwärts" (v) oder "Rückwärts" (r) drücke, dann dreht der Motor viel langsamer. Woran könnte das liegen?

#include <AccelStepper.h>
#include <MultiStepper.h>
#include <TMC2208Stepper.h>             // Include library
TMC2208Stepper driver = TMC2208Stepper(&Serial2);  // Create driver and use
                                                   // HardwareSerial2 for communication

#define limitSwitch 50
#define EN_PIN    53                
AccelStepper stepper(1, 52, 51); // (Type:driver, STEP, DIR)

char receivedCommand; // character for commands

long stepper_current; // number for stepper current in milliampere
long micro_steps;     // number for microstep setting of the driver
long set_start;
long set_end;

bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag

void setup() {

  Serial.begin(115200); //define baud rate
  Serial1.begin(9600); //define HC-06 Bluetooth baud rate
  Serial2.begin(115200); //TMC2208 UART Baudrate
  Serial.println("Focus Stacking Bot Bereit!"); //print a message

  driver.pdn_disable(1);              // Use PDN/UART pin for communication
  driver.I_scale_analog(0);           // Adjust current from the registers
  driver.rms_current(700);            // Set driver current 700mA
  driver.mstep_reg_select(1);         // Set microsteps using pins or Register
  driver.mres(8);                     //
  driver.microsteps(64);              // Set driver microsteps
  driver.toff(0x2);                   // Enable driver
  
  // Set initial seed values for the steppers
  stepper.setMaxSpeed(6000);
  stepper.setAcceleration(200); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(2000);
  pinMode(limitSwitch, INPUT_PULLUP);
  pinMode(EN_PIN, OUTPUT);
}

void loop() {

  checkSerial(); //check serial port for new commands

// Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
  while (digitalRead(limitSwitch) == 0 || stepper.currentPosition() < -64800) {}
}

void checkSerial() //method for receiving the commands
{  
  //switch-case would also work, and maybe more elegant
 
  if (Serial1.available() > 0) //if something comes
  {
    receivedCommand = Serial1.read(); // this will read the command character
    newData = true; //this creates a flag
  }
 
  if (newData == true) //if we received something (see above)
  { 
    //HOMING
    if (receivedCommand == 'h') //homing, this movement will be interrupted via the attachInterrupt() triggered by the microswitch.
    {
      runallowed = true; //allow running          
 
      Serial.println("HOMING!"); //print action
  while (digitalRead(limitSwitch) != 0) {
  digitalWrite(53, LOW);              // Enable driver
    stepper.setSpeed(6000);
    stepper.runSpeed();
    stepper.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
  }
  delay(20);
  // Move 200 steps back from the limit switch
  while (stepper.currentPosition() != -200) {
    stepper.setSpeed(-6000);
    stepper.run();
  }
  Serial.println("HOMING FINISHED!"); //print action
    }
  }
   
   //Vorwärts Verfahren
   
   if (receivedCommand == 'v') {
   
     runallowed = true; //allow running          
    digitalWrite(53, LOW);   // Enable driver
    stepper.setSpeed(6000);
    stepper.runSpeed();
    Serial.print("Stepper Position: ");
    Serial.println(stepper.currentPosition() );
   
  while (receivedCommand == 's') {
    stepper.stop();
    Serial.println("Stop!");
 
  }
   }
   

   //Rückwärts Verfahren
   
   if (receivedCommand == 'r') {
   
     runallowed = true; //allow running          
  digitalWrite(53, LOW);              // Enable driver
    stepper.setSpeed(-6000);
    stepper.runSpeed();
    Serial.print("Stepper Position: ");
    Serial.println(stepper.currentPosition() );
   
  while (receivedCommand == 's') {
    stepper.stop();
    Serial.println("Stop!");
 
  }
   }
   
  //after we went through the above tasks, newData becomes false again, so we are ready to receive new commands again.
  newData = false;
 
 
}

ManMadeDesaster:
Allerings, wenn ich "Vorwärts" (v) oder "Rückwärts" (r) drücke, dann dreht der Motor viel langsamer. Woran könnte das liegen?

Schmeiß diese Zeilen mal raus:

    Serial.print("Stepper Position: ");
    Serial.println(stepper.currentPosition() );

Welchen Arduino benutzt Du? Auf einem AtMega sind Stepraten von 6000 Steps/sec seeehr optimistisch.

Du benutzt auch mal runSpeed() und mal run(). Ist das Absicht? Kennst Du den Unterschied?
Erklär mal genauer was Du überhaupt machen willst. Derzeit sieht das etwas 'unstrukturiert' aus, was Du mit der Accelstepper treibst.

Zum Geschwindigkeitsproblem: Beim 'Homing' nutzt Du rel. kurze while Schleifen. Da schafft er verhältnismäßig hohe Stepraten. Beim Vorwärts- und Rückwärtsdrehen macht er nur einen Step pro kompletten loop-Durchlauf. Das ist deutlich langsamer.

Schmeiß diese Zeilen mal raus:

ich kann das gerade nicht ausprobieren, reicht es aus, diese Zeilen einfach auszuklammern oder müssen die wirklich gelöscht werden?

Welchen Arduino benutzt Du? Auf einem AtMega sind Stepraten von 6000 Steps/sec seeehr optimistisch.

ja ich habe sehr viel herum experimentiert, daher ist auch mal run() und mal runSpeed() im code.

Der Arduino soll mal eine Focus Stacking Mechanik ansteuern, mit der ich meine Kamera in definierten Abständen von Startposition bis Endposition bewegen kann und er nach jeder Bewegung kurz wartet bis alles still steht und dann automatisch die Kamera auslöst. Hat den Zweck, dass ich mit mehreren Fotos den Schärfebereich stark vergrößern kann und das Automatisiert und gleichbleibend.

Ich möchte den Arduino Mega 2560 mit meinem Handy folgend steuern:

Homen Taste drücken => Arduino soll Achse solange fahren bis Taster geschaltet wird, dann Stepper Nullen und dann kurz zurückfahren.

Vorwärts/Rückwärts fahren => Manuell den Schlitten Positionieren und dann

Set Start/End => soll dann die Start/End Position Speichern und mit

Start => soll er dann zur Startposition fahren und in definierten schritten zur Endposition fahren (letzter schritt +-1 Foto ist egal, da es sehr unwahrscheinlich ist, dass die Abstände genau in den Verfahrbereich passen).

Zusätzlich möchte ich dann noch Motorstrom, Microstepping, Beschleunigung und maximale Geschwindigkeit in einem Zug Programmieren. (müsste dann beispielsweise ungefähr so aussehen: s700m32a2000v4000; (s=Motorstrom; m=Microstepping; a=Beschleunigung; v=maximale Geschwindigkeit) sollte doch gehen oder?)

Ich habe am Code noch ein bisschen gearbeitet und fast alles implementiert, ich werde diesen dann eventuell später hier Posten, wenn ich wieder kann.

Danke für die Hilfe erstmal :slight_smile:

ManMadeDesaster:
ich kann das gerade nicht ausprobieren, reicht es aus, diese Zeilen einfach auszuklammern oder müssen die wirklich gelöscht werden?

Als Kommentar genügt, aber das

MicroBahner:
Zum Geschwindigkeitsproblem: Beim 'Homing' nutzt Du rel. kurze while Schleifen. Da schafft er verhältnismäßig hohe Stepraten. Beim Vorwärts- und Rückwärtsdrehen macht er nur einen Step pro kompletten loop-Durchlauf. Das ist deutlich langsamer.

dürfte noch relevanter sein!

Ich sehe gerade auch noch delay(20);, was innerhalb von loop noch mehr bremsen könnte.

stimmt, das mit dem Delay hab ich anscheinend vergessen/überlesen. Das könnte ich aber auch aus dem Loop rausnehmen.

also im Endeffekt lag es an den beiden Zeilen:

    Serial.print("Stepper Position: ");
    Serial.println(stepper.currentPosition() );

hab die weg gehauen und jetzt dreht der Motor genauso schnell wie beim Referenzieren. Ich werde dann erstmal den Code aufräumen und dann weiter machen, ansonsten danke erstmal :slight_smile:

ManMadeDesaster:
Ich werde dann erstmal den Code aufräumen und dann weiter machen, ansonsten danke erstmal :slight_smile:

Gute Idee, bitte gerne :slight_smile:

Frohe Festtage und bleib gelassen, kreativ und gesund!

Gute Idee, bitte gerne :slight_smile:

Frohe Festtage und bleib gelassen, kreativ und gesund!

Danke und ebenso :slight_smile:

Grob gesehen funktioniert jetzt alles, solange die End-Schrittzahl größer ist als die Start-Schrittzahl (start 100; end 2000). Dann fährt der Stepper ganz normal zur Startposition und dreht dann vorwärts, macht ein Foto, dreht vorwärts usw bis die Endschrittzahl erreicht wurde. Wenn die End-Schrittzahl allerdings kleiner ist, als die Startzahl (start 2000; end 100) dann dreht der Stepper ab der startposition nicht rückwärts (wahrscheinlich weil ich ihm sage, dass er positive schritte machen soll, er aber in die andere Richtung fahren muss). Da hänge ich gerade noch ein wenig fest.

Zudem stimmt soweit ich gesehen habe die schritte pro Umdrehung nicht (200 schritte pro Umdrehung vom Stepper * microstepping / steigung gewindespindel). Es scheint so als würden die schritte pro mm (für den korrekten Abstand zwischen den einzelnen Fotos rechne ich die Schritte pro Umdrehung in schritte pro mikrometer um) ungefähr halbiert berechnet werden.

#include <AccelStepper.h>
#include <MultiStepper.h>
#include <TMC2208Stepper.h>             // Include library
TMC2208Stepper driver = TMC2208Stepper(&Serial2);  // Create driver and use HardwareSerial2 for communication
AccelStepper stepper(1, 52, 51); // (Type:driver, STEP, DIR)

#define EN_PIN       53
#define limitSwitch1 50
#define limitSwitch2 49
#define ausloesen    48

char receivedCommand; // character for commands

long stepper_current; // number for stepper current in milliampere
long micro_steps;     // number for microstep setting of the driver
long set_start;
long set_end;
long schrittmass;
long micro_schrittmass;
long steigung;
long int i, j;

bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag

void setup() {

  Serial.begin(115200); //define baud rate
  Serial1.begin(9600); //define HC-06 Bluetooth baud rate
  Serial2.begin(115200); //TMC2208 UART Baudrate
  Serial.println("Focus Stacking Bot Bereit!"); //print a message

  driver.pdn_disable(1);              // Use PDN/UART pin for communication
  driver.I_scale_analog(0);           // Adjust current from the registers
  driver.rms_current(700);            // Set driver current 700mA
  driver.mstep_reg_select(1);         // Set microsteps using pins or Register
  driver.mres(8);                     //
  driver.microsteps(32);              // Set driver microsteps
  driver.toff(0x2);                   // Enable driver
  
  // Set initial seed values for the steppers
  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(4000); //ACCELERATION = Steps /(second)^2
  stepper.setSpeed(2000);
  pinMode(limitSwitch1, INPUT_PULLUP);
  pinMode(limitSwitch2, INPUT_PULLUP);
  pinMode(EN_PIN, OUTPUT);
  pinMode(ausloesen, OUTPUT);
  
  steigung    = 8; //Steigung der Trapezgewindespindel
}

void loop() {

  checkSerial(); //check serial port for new commands

// if limitSwitch1 pressed while jogging, move axis opposite way
while (digitalRead(limitSwitch1) == 0) { 
      stepper.setSpeed(2000);
      stepper.run();
}
// if limitSwitch2 pressed while jogging, move axis opposite way
while (digitalRead(limitSwitch2) == 0) {
      stepper.setSpeed(-2000);
      stepper.run();
}
  
}

void checkSerial() //method for receiving the commands
{  
 
  if (Serial1.available() > 0) //if something comes
  {
    receivedCommand = Serial1.read(); // this will read the command character
    newData = true; //this creates a flag
  }
 
  if (newData == true) //if we received something (see above)
  {
    
//HOMING

    if (receivedCommand == 'h') //homing, this movement will be interrupted via the attachInterrupt() triggered by the microswitch.
    {
      runallowed = true; //allow running          
 
      Serial.println("HOMING!"); //print action
      while (digitalRead(limitSwitch1) != 0) {
             digitalWrite(53, LOW);              // Enable driver
             stepper.setSpeed(-2000);
             stepper.runSpeed();
             stepper.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
      }
      delay(20);
      
// Move 200 steps back from the limit switch

      while (stepper.currentPosition() != 200) {
            stepper.setSpeed(2000);
            stepper.run();
      }
      Serial.println("HOMING FINISHED!"); //print action
    }
  }
   
//Vorwärts Verfahren
   
   if (receivedCommand == 'v') {
   
      runallowed = true; //allow running          
      digitalWrite(53, LOW); // Enable driver
      stepper.setSpeed(4000);
      stepper.run();
     }
   
   if (receivedCommand == 's') {
      stepper.stop();
      Serial.println("Stop!");
 
     }
   
//Rückwärts Verfahren
   
   if (receivedCommand == 'r') {
   
      runallowed = true; //allow running          
      digitalWrite(53, LOW); // Enable driver
      stepper.setSpeed(-4000);
      stepper.run();
   
      while (receivedCommand == 's') {
         stepper.stop();
         Serial.println("Stop!");
  
     }
   }


//Startpunkt speichern
   
   if (receivedCommand == 'a') {
      set_start = stepper.currentPosition();
      Serial.print("Start Position: ");
      Serial.println(set_start);
   }

//Endpunkt speichern
   
   if (receivedCommand == 'e') {
      set_end = stepper.currentPosition();
      Serial.print("End Position: ");
      Serial.println(set_end);
   }

//debug Endpunkt anzeigen
   
   if (receivedCommand == 'm') {
      Serial.print("End Position: ");
      Serial.println(set_end);
      Serial.print("Start Position: ");
      Serial.println(set_start);
   }



   if (receivedCommand == 'n') {
      stepper.setAcceleration(8000);
      stepper.setMaxSpeed(4000);
      stepper.stop();

micro_schrittmass = (200 * driver.microsteps() / steigung);
micro_schrittmass = (micro_schrittmass * schrittmass / 1000);

Serial.println(micro_schrittmass);

   while (stepper.currentPosition() != set_start) {
         stepper.moveTo(set_start);
         stepper.run();
   }
      for (stepper.currentPosition(); stepper.currentPosition() < set_end; i++) {
          trigger();
         for (j = 0; j < micro_schrittmass; j++) {
            schritt();
        }
      }
    trigger();
    stepper.stop();
    stepper.runToNewPosition(set_start);
   }






if (receivedCommand == 'y') //set distance between shots
{
schrittmass = Serial1.parseInt(); //value for the steps
Serial.println(schrittmass); //print the values for checking
}





  //after we went through the above tasks, newData becomes false again, so we are ready to receive new commands again.
  newData = false;
 
 
}


void trigger()
{
   delay(1000); // wait for vibration to settle
   digitalWrite(ausloesen, HIGH); // enable 4N35 Optoisolator (Take a picture)
   delay(1000);
   digitalWrite(ausloesen, LOW); // disable 4N35 Optoisolator
}

// Advance the motor by one step
void schritt()
{
   stepper.setSpeed(4000);
   stepper.move(micro_schrittmass);
   stepper.run();
}

Du musst dich dringend intensiver mit den Methoden der Accelstepper beschäftigen. Die funktionieren nicht so, wie Du sie einsetzt. Vor allem musst Du unterscheiden zwischen
setSpeed / runSpeed
und
setMaxSpeed / run / move / moveTo

Die darf man eigentlich nicht so vermischen, wie Du das tust.

runSpeed dreht den Motor mit der durch setSpeed vorgegebenen Geschwindigkeit. Die Drehrichtung wird das Vorzeichen von setSpeed bestimmt. Die Position ist runSpeed dabei egal. Es gibt da auch keine Beschleunigungsrampen.

run bewegt den Stepper zu einer mit move oder moveTo vorgegebenen Position. Dabei werden auch Beschleunigungs und Bremsrampen gefahren. Die maximale Geschwindigkeit, die der Stepper dabei erreicht wird durch setMaxSpeed bestimmt, die Brems- bzw Beschleuniigungsrampe durch setAcceleration. Die Drehrichtung ergibt sich aus der Differenz zwischen der momentanen Position und der Zielposition. setMaxSpeed ist Vorzeichenlos. Und für den mit setSpeed gesetzten Wert interessiert sich run garnicht. Im Gegenteil, er verändert ihn sogar ( run ruft intern runSpeed auf, und setzt dabei auch die Geschwindgkeit für runSpeed ).

Sowohl für run, als auch für runSpeed gilt, dass sie im loop möglichst häufig aufgerufen werden müssen. Der Motor macht bei jedem Aufruf maximal einen Step. Sie müssen also auf jeden Fall häufiger aufgerufen werden, als es der Stepfrequenz entspricht. Wo sie im Sketch aufgerufen werden ist dabei prinzipiell egal - Hauptsache sie kommen oft genug dran. Wenn beim Aufruf gerade kein Step ansteht, machen sie einfach nichts.
Ausgelöst wird die jeweilige Bewegung durch setSpeed bzw. move/moveTo. Diese Methoden muss man deshalb auch nicht in einer Schleife ständig aufrufen - sie starten die jeweilige Bewegung nur.

Gemischt sollte man das nicht einsetzen.

Hat ein bisschen gedauert, da ich die Platine gelötet habe und noch ein paar andere Sachen gemacht habe.

Ich habe das jetzt mal umgeschrieben auf move / moveTo allerdings ist es jetzt so, dass er bei der Taste "vorwärts" zwar beschleunigt, aber wenn ich die Taste dann los lasse, bleibt er sofort stehen. Wenn ich dann die selbe Taste wieder drücke, dreht der Motor ohne Beschleunigung wieder los. Drücke ich rückwärts bremst der Motor ab und beschleunigt dann in die andere Richtung.

Ich frage mich auch, ob ich "driver.microsteps()" als Parameter für die Distanzberechnung verwenden kann.

Derzeit sieht mein Code so aus:

#include <AccelStepper.h>
#include <MultiStepper.h>
#include <TMC2208Stepper.h>             // Include library
TMC2208Stepper driver = TMC2208Stepper(&Serial2);  // Create driver and use HardwareSerial2 for communication
AccelStepper stepper(1, 52, 44); // (Type:driver, STEP, DIR)

#define EN_PIN       42
#define limitSwitch1 50
#define limitSwitch2 46
#define ausloesen    48

char receivedCommand; // character for commands

long stepper_current; // number for stepper current in milliampere
long micro_steps;     // number for microstep setting of the driver
long set_start;
long set_end;
long schrittmass;
long micro_schrittmass;
long steigung;
long int i, j;
long wartezeit;       
long zwischenschritt;

bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag

void setup() {

  Serial.begin(115200); //define baud rate
  Serial1.begin(9600); //define HC-06 Bluetooth baud rate
  Serial2.begin(115200); //TMC2208 UART Baudrate
  Serial.println("Focus Stacking Bot Bereit!"); //print a message

  driver.pdn_disable(1);              // Use PDN/UART pin for communication
  driver.I_scale_analog(0);           // Adjust current from the registers
  driver.rms_current(700);            // Set driver current 700mA
  driver.mstep_reg_select(1);         // Set microsteps using pins or Register
  driver.mres(8);                     //
  driver.microsteps(16);              // Set driver microsteps
  driver.toff(0x2);                   // Enable driver
  
  // Set initial seed values for the steppers
  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(8000); //ACCELERATION = Steps /(second)^2
  pinMode(limitSwitch1, INPUT_PULLUP);
  pinMode(limitSwitch2, INPUT_PULLUP);
  pinMode(EN_PIN, OUTPUT);
  pinMode(ausloesen, OUTPUT);
  
  steigung    = 8; //Steigung der Trapezgewindespindel
  micro_steps = 16;
}

void loop() {

  checkSerial(); //check serial port for new commands

// if limitSwitch1 pressed while jogging, move axis opposite way
while (digitalRead(limitSwitch1) == 0) { 
      stepper.move(1000);
      stepper.run();
}
// if limitSwitch2 pressed while jogging, move axis opposite way
while (digitalRead(limitSwitch2) == 0) {
      stepper.move(-1000);
      stepper.run();
}
  
}

void checkSerial() //method for receiving the commands
{  
 
  if (Serial1.available() > 0) //if something comes
  {
    receivedCommand = Serial1.read(); // this will read the command character
    newData = true; //this creates a flag
  }
 
  if (newData == true) //if we received something (see above)
  {
    
//HOMING

    if (receivedCommand == 'h') //homing, this movement will be interrupted via the attachInterrupt() triggered by the microswitch.
    {
      runallowed = true; //allow running          
 
      Serial.println("HOMING!"); //print action
      while (digitalRead(limitSwitch1) != 0) {
             digitalWrite(53, LOW);              // Enable driver
             stepper.move(-2000);
             stepper.run();
            // stepper.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
      }
      stepper.setCurrentPosition(0);
      delay(20);
      
// Move 200 steps back from the limit switch

      while (stepper.currentPosition() != 200) {
            stepper.move(200);
            stepper.run();
      }
      Serial.println("HOMING FINISHED!"); //print action
      runallowed = false;
    }
  }
   
//Vorwärts Verfahren
   
   if (receivedCommand == 'v') {
   
//      runallowed = true; //allow running          
      digitalWrite(53, LOW); // Enable driver
//      stepper.setSpeed(4000);
      stepper.move(4000);
      stepper.run();
     }
   
   if (receivedCommand == 's') {
      stepper.stop();
      Serial.println("Stop!");
 
     }
   
//Rückwärts Verfahren
   
   if (receivedCommand == 'r') {
   
//      runallowed = true; //allow running          
      digitalWrite(53, LOW); // Enable driver
      stepper.move(-4000);
      stepper.run();
   
      while (receivedCommand == 's') {
         stepper.stop();
         Serial.println("Stop!");
  
     }
   }


//Startpunkt speichern
   
   if (receivedCommand == 'a') {
      set_start = stepper.currentPosition();
      Serial.print("Start Position: ");
      Serial.println(set_start);
   }

//Endpunkt speichern
   
   if (receivedCommand == 'e') {
      set_end = stepper.currentPosition();
      Serial.print("End Position: ");
      Serial.println(set_end);
   }

//debug Endpunkt anzeigen und stoppen
   
   if (receivedCommand == 'm') {
      Serial.print("End Position: ");
      Serial.println(set_end);
      Serial.print("Start Position: ");
      Serial.println(set_start);
      runallowed = false; //disable running
   }


// Abstand zwischen Fotos in Mikrometer

if (receivedCommand == 'y') //set distance between shots
{
schrittmass = Serial1.parseInt(); //value for the steps
Serial.print("Schrittmass ");
Serial.println(schrittmass); //print the values for checking
}

// wartezeit zwischen Fotos in Sekunden

if (receivedCommand == 'z') //wartezeit
{
wartezeit = Serial1.parseInt(); //value for the steps
Serial.print("Wartezeit ");
Serial.println(wartezeit); //print the values for checking
}


if (wartezeit > 0 && schrittmass > 0 && set_end > set_start){
  runallowed = true;
}


   if (receivedCommand == 'n' && runallowed == true) {
ablauf();
   }



  //after we went through the above tasks, newData becomes false again, so we are ready to receive new commands again.
  newData = false;
 
 
}


void ablauf()
{
      stepper.setAcceleration(4000);
      stepper.setMaxSpeed(4000);
      stepper.stop();

//micro_schrittmass = (200 * driver.microsteps() / steigung);
//micro_schrittmass = (micro_schrittmass * schrittmass / 1000);

micro_schrittmass = (200 * micro_steps / steigung);
micro_schrittmass = (micro_schrittmass * schrittmass / 1000);

Serial.println(micro_schrittmass);

   while (stepper.currentPosition() != set_start) {
         stepper.moveTo(set_start);
         stepper.run();
   }
      for (int i = stepper.currentPosition(); stepper.currentPosition() < set_end; i++) {
          trigger();
         for (j = 0; j < micro_schrittmass; j++) {
            schritt();
        }
      }
    trigger(); 
    stepper.stop();
    stepper.runToNewPosition(set_start);
}

void trigger()
{
   delay(wartezeit); // wait for vibration to settle
   digitalWrite(ausloesen, HIGH); // enable 4N35 Optoisolator (Take a picture)
   delay(wartezeit);
   digitalWrite(ausloesen, LOW); // disable 4N35 Optoisolator
}

// Advance the motor by one step
void schritt()
{
//   stepper.setSpeed(4000);
zwischenschritt = stepper.currentPosition() + micro_schrittmass;
while (stepper.currentPosition() < zwischenschritt){
   stepper.move(micro_schrittmass);
   stepper.run();
}
}

Dir fehlt immer noch das Verständnis für die Arbeitsweise der AccelStepper.
Die run() Methode erzeugt die Steps, und erkennt auch selbst ob beim Aufruf ein Step notwendig ist oder nicht. Die muss man einfach nur möglichst oft aufrufen. Z.B. direkt am Anfang des loop(). Das muss und sollte nicht im Zusammenhang mit den Befehlen sein, die die Bewegung auslösen ( move, movtTo ... )[/u]. Man muss allerdings blockadefrei programmieren - z.B. kein delay() - und für eine schnelle Umlaufzeit des loop sorgen. Die run() Methode muss häufiger aufgrufen werden, als es der maximalen Steprate entspricht. Das ist die einzige - und wesentliche - Bedingung für den Aufruf von run(). Falls die loop() Durchlaufzeit doch etwas zu groß für die Steprate ist, muss man run() u.U. an mehreren Stellen im loop aufrufen, um die notwendige Aufrufhäufigkeit zu erreichen.
Wenn man das nicht macht, passiert genau das, was Du beschreibst: Wenn Du die Taste loslässt, wird run() nicht mehr aufgerufen, und die AccelStepper hat keine Chance mehr die Bremsrampe zu fahren.

Edit: kannst Du auch mal erklären, warum Du sämtliche Variabel als 'long' definierst, und wozu Du die MultiStepper.h einbindest?