Arduino + Stepper motor + Joystick - Help

Hello, I am trying to control a stepper motor(Nema 17) with a joystick however I am encountering jerky/erratic movements from the motor. When running the code with just stepper motor movements programmed, the movement is smooth and fast however when adding the joystick into the equation, the speed and the smoothness go away. I'm using a modified code I found online that should theoretically lead to variable speed depending on the joystick but I am not sure if that is really what is happening.

I'm using a L298N to drive the stepper motor.

#include <Stepper.h>

// Number of steps per output rotation
const int stepsPerRevolution = 200;

// Create Instance of Stepper library
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);


void setup()
{
	// set the speed at 60 rpm:
	myStepper.setSpeed(60);
	// initialize the serial port:
	Serial.begin(9600);
}

void loop() 
{
	// step one revolution in one direction:
	Serial.println("clockwise");
	myStepper.step(stepsPerRevolution);
	delay(500);

	// step one revolution in the other direction:
	Serial.println("counterclockwise");
	myStepper.step(-stepsPerRevolution);
	delay(500);
}

So you post the code that works and ask on the code that does not work and is not posted?

1 Like

That looks like “bounce”

I did exactly what you are trying to do. Below is the code I used to successfully implement a joystick. I directly controlled the pulse step to the driver instead of using a library; that allows me a lot more control and flexibility.

// A stepper motor with a Pololu A4988 driver board or equivalent
// Uses micros() to manage timing

byte directionPin = 3; // direction pin for stepper motor
byte stepPin = 4; // step pin for stepper motor

const int SW_pin = 2; // digital pin connected to switch output
const int X_pin = 0; // analog pin connected to X output

int xValue;
float JoystickRatio = 0.5;
int LowSpeedMicro = 300;
int JoystickMiddle = 510;

unsigned long curMicros;
unsigned long prevStepMicros = 0;
unsigned long microsBetweenSteps; // microseconds between steps

void setup() {
    pinMode(directionPin, OUTPUT); // for stepper motor
    pinMode(stepPin, OUTPUT); // for stepper motor
    digitalWrite(directionPin, LOW); // for stepper motor
    pinMode(SW_pin, INPUT); // for joystick
    digitalWrite(SW_pin, HIGH); // for joystick
}

void loop() {
    curMicros= micros();
    xValue = analogRead(X_pin);
    if (xValue > 510 || xValue < 500) {
      if (xValue > 510){
        digitalWrite(directionPin, LOW); // switch for stepper motor
        microsBetweenSteps = ((JoystickMiddle - xValue) * JoystickRatio) + LowSpeedMicro;
        singleStep();
      } else {
        digitalWrite(directionPin, HIGH); // switch for stepper motor
        microsBetweenSteps = ((xValue - JoystickMiddle) * JoystickRatio) + LowSpeedMicro;
        singleStep();
      }
    }
}

void singleStep() {
    if (curMicros - prevStepMicros >= microsBetweenSteps) {
        prevStepMicros = curMicros;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}        
1 Like

You're right, seemed like I grabbed the wrong code but it isn't too much different, just adding in the joystick part.

#include <Stepper.h>

 

#define STEPS 200

 

const int stepsPerRevolution = 10;  

#define VRX_PIN  A0 // Arduino pin connected to VRX pin

int xValue = 0;

 

Stepper stepper(stepsPerRevolution, 8, 9, 10, 11);


void setup()

 

{

 

  Serial.begin(9600);

 

}

 

 

 

void loop()

 

{

 

  //  read analog value from the potentiometer

 

  int val = analogRead(VRX_PIN);

 

 

 

  // if the joystic is in the middle ===> stop the motor

 

  if(  (val > 500)  && (val < 523) )

 

  {

    Serial.println("idle");

  }

  else
 

  {

    while (val  >= 523)

    {

 

      // map the speed between 5 and 500 rpm

      int speed_  = map(val, 523, 1023, 5, 60);

      stepper.setSpeed(200);

      stepper.step(200);

      Serial.println("clockwise");

      val  = analogRead(VRX_PIN);

 

    }

    while (val <= 500)

 

    {

      int speed_ = map(val, 500, 0, 5, 60);

      // set motor speed

      stepper.setSpeed(200);

      // move the motor (1 step)

      stepper.step(-200);

      Serial.println("Counterclockwise");

      val  = analogRead(VRX_PIN);

 

    }

 

 

 

  }

 

 

 

}

 

 


I'm using the L2893N which looks like this and has 4 outputs. I'm pretty amateur when it comes to this stuff so I'm not really sure how I would take the principles from this code and turn it into the code for the L2893N, mainly because of how I am currently controlling the stepper motor which is using a library. It looks like stepper.setSpeed(200); and uses all 4 pins so I'm not sure how to turn that into only 2 pins.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.