Problems with Code for Stepper Control

My motors are moving too slow!

I am driving a stepper motor using a joystick, and I believe I have some coding inefficiencies that I can’t seem to crack.

The code that I have patched together from various sources is set up to control a motor with a joystick shield. The joystick has variable speed based on toggle position (either direction). There are also buttons that, when pressed move the motor a set distance.

The problem I am having is the maximum steps I can supply seems to be 15,000 steps/s. I’m not sure if there is any programming solutions that would increase the ability to supply steps faster? My coding for the joystick control seems to make it even slower, which is probably where I have inefficient code.

it’s very late, so I apologize if I am not doing a good job of explaining. Still new to forum questions.

It would be great if someone could look at the code and see if anything pops out.

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

#define STEPS 200

float xinterval = 1.0;  //user sets the distance (decimal feet) for preprogrammed movements
float yinterval = 1.0; 

int xstepsPerFoot = 25800;  //steps per foot of movement (will vary with motor and microstepping mode)
int ystepsPerFoot = 15000;

int xstepinterval = xinterval * xstepsPerFoot;  //converts the desired x movements to # of steps
int ystepinterval = yinterval * ystepsPerFoot;  //converts the desired y movements to # of steps

const byte PIN_BUTTON_SEL = 2;     //Joystick Shield Pins (preset)
const byte PIN_BUTTON_RIGHT = 3; 
const byte PIN_BUTTON_UP = 4;
const byte PIN_BUTTON_DOWN = 5;
const byte PIN_BUTTON_LEFT = 6;

int XmotorDirPin = 8;         //MOTOR PINS
int XmotorStepPin = 9;     

int maxSpeed = 14000;        //maximum (steps/s) (X motor)
int motorSpeed = 100;       //generic motor speed (steps/s)
int motorAccel = 10000;      //steps/s/s to accelerate

const byte PIN_ANALOG_X = 0;  //the joystick left/right
const byte PIN_ANALOG_Y = 1;  //the joystick up/down

int val_S = 0;
int val_R = 0;
int val_L = 0;
int val_U = 0;
int val_D = 0;

AccelStepper stepper1(1, XmotorStepPin, XmotorDirPin); //set up the accelStepper intance

void setup(){

  Serial.begin(9600);

  pinMode (PIN_BUTTON_RIGHT, INPUT); 
  digitalWrite (PIN_BUTTON_RIGHT, HIGH); 

  pinMode (PIN_BUTTON_LEFT, INPUT);
  digitalWrite (PIN_BUTTON_LEFT, HIGH);

  pinMode(PIN_BUTTON_UP, INPUT);  
  digitalWrite(PIN_BUTTON_UP, HIGH);

  pinMode(PIN_BUTTON_DOWN, INPUT);  
  digitalWrite(PIN_BUTTON_DOWN, HIGH);

  stepper1.setMaxSpeed(maxSpeed);          //initialize the speed and acceleration for the motors
  stepper1.setSpeed(motorSpeed);
  stepper1.setAcceleration(motorAccel);
}

void loop()
{
  val_S = digitalRead(PIN_BUTTON_SEL);
  val_R = digitalRead(PIN_BUTTON_RIGHT);  //Reads state of Gamepad buttons
  val_L = digitalRead(PIN_BUTTON_LEFT);  
  val_U = digitalRead(PIN_BUTTON_UP);  
  val_D = digitalRead(PIN_BUTTON_DOWN);

  int val_x=analogRead(PIN_ANALOG_X);    //Reads state of Gamepad Joysticks
  int val_y=analogRead(PIN_ANALOG_Y);


//////// RIGHT-LEFT JOYSTICK CONTROLS /////////////////////////////////////////////////////////////////////////////////////////

 if (val_x >= 500 && val_x <= 530 && val_y >= 500 && val_y <= 530) //&& xlast ==! stepper1.currentPosition())  // If joystick is centered
  { 
    stepper1.stop();                 //Stops the X_motor if the joystick is centered
    stepper1.setSpeed(motorSpeed);
 
  }

  if (val_x > 530)// If joystick is pushed right
  {
    int K = map (val_x, 531,1023,1000,5000);
    stepper1.move(100);
    stepper1.setSpeed(-K); 
    stepper1.run(); 
    stepper1.setSpeed(motorSpeed);
  }

  if (val_x < 500)  //if joystick is pushed left
  {
    int K= map (val_x, 0,499,5000,1000); 
    stepper1.move(100);
    stepper1.setSpeed(K);
    stepper1.run();
    stepper1.setSpeed(motorSpeed);
  }


  ////// BUTTON CONTROLS//////////////////

  if (val_R == LOW) {
stepper1.setSpeed(motorSpeed);
    stepper1.runToNewPosition(stepper1.currentPosition() - xstepinterval);
  }

  if (val_L == LOW) {
stepper1.setSpeed(motorSpeed);
    stepper1.runToNewPosition(stepper1.currentPosition() + xstepinterval);
  }

}

To clarify....

Pushing a button, I can get full speed, which appears to be limited to 15,000 steps/s (setting higher values does not increase actual motor speed)

Using the joystick, the speed is significantly less than the 15,000 steps/s which I believe is likely attributed to the coding I have.

One other code snippet question that I wasn't able to find an answer to is regarding the "#define STEPS 200". Should the value reflect the actual full step count for the motor rotation? or should it consider the microstep mode as well? My motor is a 200 step motor, but the driver I am using is a gecko g201 which is a 10 microstepping driver.

Thanks for any help!

15000 steps/sec is very fast BTW - I presume you are using a microstepping driver.
Perhaps you are reaching the physical limits of the motor?

The fastest simple approach I can think of it to use DDS/NCO with a lightweight interrupt
routine. Something like:

volatile long frequency ;
volatile long phase ;

void timer_int ()
{
  long old_phase = phase ;
  phase += frequency ;       // DDS - update phase
  if ((old_phase ^ phase) < 0)    // test for sign bit change
  {
    digitalWrite (dir_pin, frequency < 0 ? LOW : HIGH) ;
    digitalWrite (step_pin, HIGH) ;
    digitalWrite (step_pin, LOW) ;
  }
}

You configure a timer to run at high speed, declare timer_int as the appropriate
ISR for that timer’s overflow interrupt.

Then in the rest of the code you simply update frequency (with interrupts
briefly disabled) whenever you want to.

int K = map (val_x, 531,1023,1000,5000);

Isn’t this limiting the speed to 5000 maximum.

Mark

Thanks for the reply.

15000 steps/sec is very fast BTW - I presume you are using a microstepping driver. Perhaps you are reaching the physical limits of the motor?

Yes, it seems like that # is consistent with the high end that I have read in various posts on the topic. I am using the Gecko g201 driver http://www.geckodrive.com/g201.html (which is a 10 microstep driver)

I am not familiar with DDS/NCO, so I will do a little research and play with incorporating the code you have provided (THANK YOU!).

I dug a little deeper into the manual for it, and it looks like there is an internal multiplier header that may allow me to play with the output speed. I will also play with this and report my results.

Groundfungus

Yes, I should have discussed this value more. The high end of the map value is already higher than the speed at which it can move with the joystick. I could set it at 15000 and it will still move at the same speed. I think that the max speed of the "if" loop is controlling the motor speed because the stepper1.run moves it 1 step at a time (which I don't totally understand why).