1

I'm trying to control the positioning of a NEMA17 bipolar stepper motor by turning the knob of a potentiometer, using an EasyDriver board. The control part is solved. My problem is that if I quickly turn the knob to one end of its range and then back, the stepper motor lags behind by about 1/5 of a second.

All the spec sheets for the motor says I should be able to expect a lot more responsiveness (based on max RPM, acceleration, etc...). I'd like to speed up the responsiveness of the motor to shorten the lag. My code is as follows:

//Declare pin functions on Arduino
#define stp 2
#define dir 3  //LOW => forward, HIGH => backward
#define MS1 4
#define MS2 5
#define EN  6

//Declare variables for functions
int x;
int const potPin = A0;
long potval; // current analog read of A0 voltage 
int potrotsteps = 166; //num of stepper motor steps for 300-degree rotation
int cur_step_pos = 0; //current position in terms of stepper steps
long cmd_step_pos = 0; //step-position to command stepper motor to go to
int tomove; //num steps to move

void setup() { 
  //stepper motor setup
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); //Set step, direction, microstep and enable pins to default states
  Serial.begin(9600); // initialize serial communication at 9600 bits per second
  Serial.println("\n\n\n#################    setup completed     #################");
}

void loop() { 

  //map analog voltage read from pot to a step-position (0-166) of the stepper motor
  potval = analogRead(potPin);
  cmd_step_pos = potval * potrotsteps / 1023; // find where stepper motor should be in terms of step-position
  tomove = abs(cur_step_pos - cmd_step_pos);

  if (cmd_step_pos > cur_step_pos) { //if should-be position greater than current position
    digitalWrite(dir, LOW); // move forward
    CommandStepperMotor(tomove); //move forward by the diff in position
  } else { //if should-be position is lower
    digitalWrite(dir, HIGH); //move backward
    CommandStepperMotor(tomove); //move backward by diff in position
  }
  cur_step_pos = cmd_step_pos; //current position is now former should-be position

}

//GLOBAL FUNCTIONS

//Reset Easy Driver pins to default states
void resetEDPins() {
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);  //default "forward" movement
  digitalWrite(MS1, LOW); // L-L => full steps, H-L => 1/2 step
  digitalWrite(MS2, LOW); // L-H => 1/4 steps, H-H => 1/8 step
  digitalWrite(EN, LOW); //Enable motor control
}

void CommandStepperMotor(int numsteps) {
  for (x = 0; x < numsteps; x++) {
    digitalWrite(stp, HIGH); //Trigger one step forward
    delay(1);
    digitalWrite(stp, LOW); //Pull step pin low so it can be triggered again
    delay(1);
  }
}

I understand that changing delay(1) to delayMicroseconds(100) in the CommandStepperMotor function should help, but as it turns out, anything smaller than a delay of 1 millisecond stalls the motor. I've tried to Google other's solutions to the problem, but it seems they had no problem at all lowering the delay in sending the HIGH/LOW signals to the stepper pin to <1 ms.

Any ideas? Thanks in advance!

1 Answer 1

1

Your problem is that you want to go from a standstill to full speed instantly. That just isn't going to happen. As you have seen there is a limit to how fast you can go from stationary.

If you want to go faster you will have to accelerate up to that speed.

The simplest way to do that is to use a library that is designed for it, such as the popular AccelStepper.h library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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