Accelurate and decelurate

Hi

im using 3 steppers to control my camera movement.

i include the multistepper and accelstepper library
(counts the steps to take for each motor to end at the same time) .

Its working real well and im happy i came this far.

i only want the motors to accelerate when starting to travel from IN point, and decelerate a few steps before reaching the OUT point.

I’m using this code

Code: [Select]

#include <Stepper.h>
#include “AccelStepper.h”
#include “MultiStepper.h”

void loop() {

while ((InandOut != 2) && (InandOut !=3)) { // Enable moving of steppers using the Joystick

if (analogRead(JoyX) < 200) {
joystepX=stepperX.currentPosition();
joystepX=joystepX-20; }

if (analogRead(JoyX) > 900) {
joystepX=stepperX.currentPosition();
joystepX=joystepX+20;
}

if (analogRead(JoyA) < 200) {
joystepA=stepperA.currentPosition();
joystepA=joystepA-20; }

if (analogRead(JoyA) > 900) {
joystepA=stepperA.currentPosition();
joystepA=joystepA+20;
}

if (analogRead(JoyY) < 200) {
joystepY=stepperY.currentPosition();
joystepY=joystepY-20; }

if (analogRead(JoyY) > 900) {
joystepY=stepperY.currentPosition();
joystepY=joystepY+20;
}
stepperA.moveTo(joystepA);
stepperX.moveTo(joystepX);
stepperY.moveTo(joystepY);

while (((stepperA.distanceToGo() !=0) || (stepperX.distanceToGo() !=0) || (stepperY.distanceToGo() !=0))) {
stepperA.runSpeedToPosition();
stepperX.runSpeedToPosition();
stepperY.runSpeedToPosition();
}
}

if (InandOut == 2) {

while (Serial.available() > 0) { // Check if values are available in the Serial Buffer

int setspeed = Serial.parseInt(); // Read entered Speed from Serial Buffer

if (setspeed > 0) {
stepperX.setMaxSpeed(setspeed);
Serial.println("");
Serial.println(“Speed set at: “);
Serial.println(setspeed);
Serial.println(””);
Serial.println(“Type ‘I’ to go to the IN points or ‘O’ to go to the OUT points”);
Serial.println(“OR”);
Serial.println(“Press Joystick Switch again to Reset IN and OUT Points”);
setspeed=0;
InandOut=3;
}
}
}

if (InandOut == 3) {

while (Serial.available() > 0) { // Check if values are available in the Serial Buffer

char checkinput = Serial.read(); // Read Character entered in Serial Monitor
Serial.println(checkinput);

if (checkinput == ‘I’) { // Move both steppers to IN points
gotoposition[0]=AInPoint;
gotoposition[1]=XInPoint;
gotoposition[2]=YInPoint;
StepperControl.moveTo(gotoposition);
StepperControl.runSpeedToPosition(); // Blocks until all are in position
Serial.println(“Steppers are at the IN Position…”);
Serial.println("");
Serial.println(“Type ‘I’ to go to the IN points or ‘O’ to go to the OUT points”);
Serial.println(“OR”);
Serial.println(“Press Joystick Switch again to Reset IN and OUT Points”);
}

if (checkinput == ‘O’) { // Move both steppers to OUT points
gotoposition[0]=AOutPoint;
gotoposition[1]=XOutPoint;
gotoposition[2]=YOutPoint;
StepperControl.moveTo(gotoposition);
StepperControl.runSpeedToPosition(); // Blocks until all are in position
Serial.println(“Steppers are at the OUT Position…”);
Serial.println("");
Serial.println(“Type ‘I’ to go to the IN points or ‘O’ to go to the OUT points”);
Serial.println(“OR”);
Serial.println(“Press Joystick Switch again to Reset IN and OUT Points”);
}

}
}
}

If anyone could help me out… That would be great!!

You didn't say what was wrong.

the movement is so sudden that the camera is shaking when the motors start and when stopping.

i want it to move smooth to the max speed. (the speed it askes for in the program)

than for example when its 100 steps before the outpoint it starts decelarate so the camera is not shaking when it stops.

You should also read Nick Gammon's post on the proper way to post source code to this Forum using code tags. Also, asking a clearly-stated question will likely result in a more clearly-stated solution. Both help us help you.

So the problem is, that it doesn't accelerate or decellerate, and you want to add that feature?

yes… that is what i want to build in the code

and sorry for the code but it went wrong when it exeed 9000 karaters so i cut the setup out…

lets try again

#include <Stepper.h>
#include "AccelStepper.h" 
#include "MultiStepper.h" 

// AccelStepper Setup
AccelStepper stepperA(1, 4, 5);   // 1 = Easy Driver interface
                                  // UNO Pin 3 connected to STEP pin of Easy Driver
                                  // UNO Pin 4 connected to DIR pin of Easy Driver
                                  
AccelStepper stepperX(1, 6, 7);   // 1 = Easy Driver interface
                                  // UNO Pin 6 connected to STEP pin of Easy Driver
                                  // UNO Pin 7 connected to DIR pin of Easy Driver

AccelStepper stepperY(1, 10, 11);   // 1 = Easy Driver interface
                                  // UNO Pin 3 connected to STEP pin of Easy Driver
                                  // UNO Pin 4 connected to DIR pin of Easy Driver

MultiStepper StepperControl;  // Create instance of MultiStepper
                                  
// Analog Joystick setup
#define JoyA A0  // Joystick X pin connected to A0 on the UNO
#define JoyX A1  // Joystick Y pin connected to A1 on the UNO
#define JoyY A2  // Joystick X pin connected to A2 on the UNO
#define JoySwitch 2 // Joystick switch connected to interrupt Pin 8 on UNO

long joystepA=0; // Used to move steppers when using the Joystick
long joystepX=0; // Used to move steppers when using the Joystick
long joystepY=0; // Used to move steppers when using the Joystick

// Variables used to store the IN and OUT points
volatile long AInPoint=0;
volatile long XInPoint=0;
volatile long YInPoint=0;
volatile long AOutPoint=0;
volatile long XOutPoint=0;
volatile long YOutPoint=0;

int InandOut=0;  // Used to detect if IN and OUT points have been set

long gotoposition[3];  // Used to move steppers using MultiStepper Control



void joyswitchclick ()  {  //  Interrupt runs when clicking the Joystick Switch

  static unsigned long last_call_interrupt = 0;  // Used to debounce to Joystick Switch
  unsigned long interrupt_length = millis();
  
  if (interrupt_length - last_call_interrupt > 300) {  // Check if enough time has passed since clicking switch
    
    switch (InandOut) {  // Keep track of number of times the switch has been clicked
      case 0:
        InandOut=1;
        AInPoint=stepperA.currentPosition();
        XInPoint=stepperX.currentPosition();  //  Set the IN points for both steppers
        YInPoint=stepperY.currentPosition();
        Serial.print("IN Points set at:  ");
        Serial.print(AInPoint);
        Serial.print(" , , ");
        Serial.print(XInPoint);
        Serial.print(" , ");
        Serial.println(YInPoint);
        Serial.println("");
        Serial.println("Use Joystick to set OUT Points: ");
        break;

      case 1:
        InandOut=2;
        AOutPoint=stepperA.currentPosition();
        XOutPoint=stepperX.currentPosition();  //  Set the OUT Points for both steppers
        YOutPoint=stepperY.currentPosition();
        Serial.print("OUT Points set at:  ");
        Serial.print(AOutPoint);
        Serial.print(" , , ");
        Serial.print(XOutPoint);
        Serial.print(" , ");
        Serial.println(YOutPoint);
        Serial.println("");
        Serial.println("Enter Stepper Travel Speed: ");
        Serial.println("OR");
        Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
        break;

      case 2:
        Serial.println("");
        Serial.println("IN and OUT Points have been Reset...");
        Serial.println("");
        Serial.println("");
        Serial.println("Set IN points for Steppers using the Joystick ");
        InandOut=0;
        break;

       case 3:
        Serial.println("");
        Serial.println("IN and OUT Points have been Reset...");
        Serial.println("");
        Serial.println("");
        Serial.println("Set IN points for Steppers using the Joystick ");
        InandOut=0;  
        joystepA=stepperA.currentPosition();
        joystepX=stepperX.currentPosition();  // Reset Positions
        joystepY=stepperY.currentPosition();
        stepperX.setMaxSpeed(350.0);      // Reset Max Speed of X axis
        break;
    }
  }
  last_call_interrupt = interrupt_length;
} 


void setup() {
  
  Serial.begin(9600);  // Start the Serial monitor with speed of 9600 Bauds
  
// Print out Instructions on the Serial Monitor at Start
  Serial.println("Set IN points for Steppers using the Joystick ");

  pinMode(JoySwitch, INPUT_PULLUP);

// Set Max Speed and Acceleration of each Steppers
  stepperA.setMaxSpeed (400.0);      // Set Max Speed of A axis
  stepperA.setAcceleration(800.0);  // Acceleration of A axis
  
  stepperX.setMaxSpeed(50.0);      // Set Max Speed of X axis
  stepperX.setAcceleration(200.0);  // Acceleration of X axis
  
  stepperY.setMaxSpeed(20.0);      // Set Max Speed of Y axis slower for rotation
  stepperY.setAcceleration(100.0);  // Acceleration of Y axis

// Create instances for MultiStepper
  StepperControl.addStepper(stepperA);  // Add Stepper #1 to MultiStepper Control
  StepperControl.addStepper(stepperX);  // Add Stepper #2 to MultiStepper Control
  StepperControl.addStepper(stepperY);  // Add Stepper #3 to MultiStepper Control

  attachInterrupt (0,joyswitchclick,FALLING); // interrupt 0 always connected to pin 2 

}


void loop() {

  while ((InandOut != 2) && (InandOut !=3)) {  // Enable moving of steppers using the Joystick

    if (analogRead(JoyX) < 200) {         
        joystepX=stepperX.currentPosition();         
        joystepX=joystepX-20;     }     

    if (analogRead(JoyX) > 900) {
        joystepX=stepperX.currentPosition();
        joystepX=joystepX+20;
    }

    if (analogRead(JoyA) < 200) {         
        joystepA=stepperA.currentPosition();         
        joystepA=joystepA-20;     }          

    if (analogRead(JoyA) > 900) {
        joystepA=stepperA.currentPosition();
        joystepA=joystepA+20;
    }

    if (analogRead(JoyY) < 200) {         
        joystepY=stepperY.currentPosition();         
        joystepY=joystepY-20;     }          

    if (analogRead(JoyY) > 900) {
        joystepY=stepperY.currentPosition();
        joystepY=joystepY+20;
    }
    stepperA.moveTo(joystepA);
    stepperX.moveTo(joystepX);
    stepperY.moveTo(joystepY);

    while (((stepperA.distanceToGo() !=0) || (stepperX.distanceToGo() !=0) || (stepperY.distanceToGo() !=0))) {
      stepperA.runSpeedToPosition();
      stepperX.runSpeedToPosition();
      stepperY.runSpeedToPosition();
    }
  }
  
  if (InandOut == 2) {

    while (Serial.available() > 0)  { // Check if values are available in the Serial Buffer
  
      int setspeed = Serial.parseInt();  //  Read entered Speed from Serial Buffer
    
       if (setspeed > 0) {
         stepperX.setMaxSpeed(setspeed);
         Serial.println("");
         Serial.println("Speed set at:  ");
         Serial.println(setspeed);
         Serial.println("");
         Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
         Serial.println("OR");
         Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
         setspeed=0;
         InandOut=3;
      }
    }
  }
    
  if (InandOut == 3) {

    while (Serial.available() > 0)  { // Check if values are available in the Serial Buffer
  
      char checkinput = Serial.read();  //  Read Character entered in Serial Monitor
      Serial.println(checkinput);
    
    if (checkinput == 'I') {  // Move both steppers to IN points
      gotoposition[0]=AInPoint;
      gotoposition[1]=XInPoint;
      gotoposition[2]=YInPoint;
      StepperControl.moveTo(gotoposition);
      StepperControl.runSpeedToPosition(); // Blocks until all are in position
      Serial.println("Steppers are at the IN Position...");
      Serial.println("");
      Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
      Serial.println("OR");
      Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
    }
    
    if (checkinput == 'O') {  //  Move both steppers to OUT points
      gotoposition[0]=AOutPoint;
      gotoposition[1]=XOutPoint;
      gotoposition[2]=YOutPoint;
      StepperControl.moveTo(gotoposition);
      StepperControl.runSpeedToPosition(); // Blocks until all are in position
      Serial.println("Steppers are at the OUT Position...");
      Serial.println("");
      Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
      Serial.println("OR");
      Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
    }

  }
}
}

When your program is too long you can add the .ino file as an attachment.

I suspect your problem is that the multi-stepper library does not support acceleration. If you think about it, it would be difficult to coordinate movement on 3 axes and acceleration while maintaining the appropriate relative positions at all time.

One answer would be to select a much slower maximum speed so that the "instant" acceleration is not inconvenient.

Another answer would be to abandon the AccelStepper / Multistepper library and write your own code with acceleration.

And yet another option is to consider whether you really need coordinated movements, and if not then the normal AccelStepper functions could be used (i.e. without MultiStepper).

...R

I never wrote code before. i was happy when i could transform it in a 3 axis sketch ... it was made for 2.

i also tryed other programs but as soon as it works with delay in the loop my steppers start stottering...

so no experience with programming makes it hard to abandon one of those libaries since i see that the motors are running smooth on it.

And yes i realy want controlled movement. I like to use it for greenscreen shootings.

isn't it a possibility to add it to the libary?

Rebelstudios:
isn't it a possibility to add it to the libary?

If by "add it" you mean would it be possible to adapt the MultiStepper library to include acceleration I suspect the answer is yes. But I reckon I would find it difficult and I have no plans to try to do so - not even for money.

Maybe there is some way to contact the author of MultiStepper and ask him to extend the library. There may be a contact point on the library website.

I can't think of anything else to suggest as you don't have any programming experience yourself.

...R

If you use AccelStepper you musn't busy-wait or call delay(), so that loop() gets called
very frequently, and thus its calls to stepperA.run() etc are called very frequently. That's
a pre-requisite for AccelStepper library.

It doesn the rest for you. So use calls like move() and moveTo(), not runToPosition(), and
ensure run() is called frequently - that makes it easy to drive multiple motors asynchronously.

You need to get rid of the while-loops that are busy-waiting for serial input and use if instead.

MarkT:
not runToPosition(), and

run() and runSpeedToPosition() are the only options for MultiStepper and run() calls runSpeed() so neither of them uses acceleration.

...R

Hi,
Have you looked at the AccelStepper Examples, it has a Multi-stepper example.

Tom... :slight_smile:

Robin2:
run() and runSpeedToPosition() are the only options for MultiStepper and run() calls runSpeed() so neither of them uses acceleration.

...R

Then don't use multistepper? AccelStepper supports multiple steppers, its fully asynchronous.

MarkT:
Then don't use multistepper? AccelStepper supports multiple steppers, its fully asynchronous.

As far as I can see the OP wants the ability of MultiStepper to coordinate the movements of the motors AND wants to have the motors accelerate and decelerate.

...R

TomGeorge:
Have you looked at the AccelStepper Examples, it has a Multi-stepper example.

You seem to have fallen behind - that was covered in the Original Post :slight_smile:

...R

Thanks for all the tips and thinking with me for this problem

I'm going to ask the designer of the Accelstepper program, meanwhile i'll try some other options you mentioned before.

all tips are still welcome controlling this project smoothly.