0

Update:

Below I implemented how I understood your suggestions. And it still does only turn in one direction (forward). Curiously if I entered M_DEST in the stepperOneForward() function it turned forward very long but smooth. The code below made it rotate as usual very jittery. Is this the acceleration part and if so how can I change that ? Ideally I would be able to tell the stepper go to position X and return to start and that in constant speed.

 #include <AccelStepper.h>

const int stepPin = 5;
const int dirPin = 4;
const int enPin = 12;

unsigned int DEST = 800;
unsigned int M_DEST = -800;
unsigned int SPD = 1600;
unsigned int ACCEL = 800;

AccelStepper stepper1(1,stepPin,dirPin);

void setup() {

  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);

  stepper1.setEnablePin(enPin);
  stepper1.setPinsInverted(false, false, true);
  Serial.begin(9600);  // Start Serial
}

void loop() {

stepperOneForward();
Serial.println("Stepper1 turned forward.");
delay(1000);
stepperOneBackward();
Serial.println("Stepper1 turned backward.");
}

void stepperOneForward() {

  stepper1.enableOutputs();
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST > 0) {                          
    while ( stepper1.distanceToGo() > 0) { 
      stepper1.run();
      }
  //stepper1.disableOutputs();
  }
 }

 void stepperOneBackward() {

  stepper1.enableOutputs();
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(M_DEST);
  if (M_DEST < 0) {                          
    while ( stepper1.distanceToGo() > 0) { 
      stepper1.run();
      }
  //stepper1.disableOutputs();
  }
 }

I have multiple steppers that I would like to run forward until they hit a microswitch and backwards to the initial position. But to simplify things I would like to control one stepper going forward and then backward. The code below always just turns clockwise.

I tried to set the dirPin to low, which did not work. I tried to reverse the setMaxSpeed (by putting a minus in front of it). I found the "enum AccelStepper::Direction" class in Accelstepper that did not explain how to to set DIRECTION_CCW or DIRECTION_CW.

What I would like to achieve is control these steppers so they move smoothly forward, wait and then backwards. This should be very easy, but has frustrated me now for too long. I would use any library at this point that can do this and control more than 1 stepper.

The SPD and ACCEL values are so high because I use microstepping (6400 is a full cycle).

#include <AccelStepper.h>

const int stepPin = 5;
const int dirPin = 4;
const int enPin = 12;

unsigned int DEST = 6400;
unsigned int SPD = 1600;
unsigned int ACCEL = 800;

void setup() {

  pinMode(stepPin,OUTPUT);
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  Serial.begin(9600);  // Start Serial
}

void loop() {

stepperOneForward();
Serial.println("Stepper1 turned forward.");
stepperOneBackward();
Serial.println("Stepper1 turned backward.");
}

void stepperOneForward() {

  AccelStepper stepper1(1,stepPin,dirPin);
  digitalWrite(enPin,LOW);
  stepper1.setMaxSpeed(SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST > 0) {                          
    while ( stepper1.distanceToGo() > 0) { 
      stepper1.run();
      }
  digitalWrite(enPin,HIGH);
  }
 }

 void stepperOneBackward() {

  AccelStepper stepper1(1,stepPin,dirPin);
  digitalWrite(enPin,LOW);
  stepper1.setMaxSpeed(-SPD);
  stepper1.setAcceleration(ACCEL);
  stepper1.move(DEST);
  if (DEST < 0) {                          
    while ( stepper1.distanceToGo() > 0) { 
      stepper1.run();
      }
  digitalWrite(enPin,HIGH);
  }
 }
  • I think the way to do this is to use stepper1.move(-DEST). PS I'd suggest creating the stepper1 object only once, as a global variable. And then use that global stepper1 in the two functions, instead of re-creating the object every time you call the two function. – Gerben Feb 14 at 15:55
2

First, you are creating/destroying the AccelStepper stepper1() object at every call. This is not right, as the library can no longer keep track of the stepper position and state.

The stepper object should be created in the global scope (that is, outside of setup() or loop()).

Second, you can call stepper1.setEnablePin(enPin) and stepper1.setPinsInverted(false, false, true) after you create the object to have the AccelStepper library control the enable pin and to set the enable pin to operate active-low. Then the driver is enabled or disabled with calls to stepper1.enableOutputs() and stepper1.disableOutputs(). In practice, you would not disable the driver except for power saving, as the stepper can no longer hold it's position when the outputs are not enabled. It will lose it's position.

Third, do not set the speed to a negative value. The direction of the stepper is determined by the library based on the current position and the desired end position. When the library is created, the position is zero. You can set the new position in several ways:

  • stepper1.move(): Set the target position relative to the current position. This means to go backwards you pass this function a negative value. It will add this (negative) number to the internal target position, and then run() will work to get it there.

  • stepper1.moveTo(): Set a new absolute position. If you initially set the position to 100 and move there, then set it to 50, the stepper will run in reverse to be able to reach position 50. If you start in position 0 and run to 50, it will run forward. If you start at 0 and set to -50, it will run in reverse to get there, and so on.

  • Thank you very much for your answer, above my update. – digit Feb 15 at 8:09
  • @digit You may want to look into what the Acceleration and Speed values mean. The docs (airspayce.com/mikem/arduino/AccelStepper/…) say that speeds over 1000 are unreliable. Try lowering the speed and accel values to something in 200 range. 1600 steps per second is too fast for the physical rotor to respond to the coil changes. – jose can u c Feb 15 at 13:40
  • Well this is because I am microstepping and if I set the Speed to 200, but the Stepper has to run for 800 steps, it becomes very slow. I read this part of the Accelstepper. But all of this still does not solve the problem that never ran backwards. Only forwards. – digit Feb 18 at 14:10
  • If it runs forward and not backward with a stepper driver, then double-check your wiring... With AccelStepper using a driver, it only pulls the direction pin high or low and the driver handles the coil sequencing. – jose can u c Feb 18 at 14:20
  • If I use a different driver and code (but same wiring) it works like a charm, so it can't be the wiring (or am I missing something here). I would like to just have one example code that turns the stepper backward with Accelstepper and ideally in a dedicated void that only enables the motor when needed (and thus keep the stepper cool for continuous running. Still could not find a solution for that after 5 days :) – digit Feb 18 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.