Slight Problem with Stepper Motor Controlled by Joystick.

Good day. I’m trying to build a clock drive for my homemade telescope using a stepper motor. I thought it would be convenient to have a joystick control for easy slewing back and forth.

I am using a Seeed Motor Shield V1.0, an Adafruit Analog Thumb Joystick, a Ming Jong ST28 12V Stepper Motor, 8 AA batteries, and an Arduino Uno.

My code is as follows:

// Include arduino stepper library
#include <Stepper.h>
 
const int stepsPerRevolution = 2048;  // specific to my motor
 
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,11,12,13);  

//Joystick is on analog pin 0
int joyPin1 = 0;
 
void setup() {

// Activate the motor shield by setting pins nine and ten to a digital high, as per the shield's specs.
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  
}


 
void loop() {
  top:
  // Read the Joystick's analog signal
  float xjoy = analogRead(joyPin1);
  
  // Set the speed accordingly .(I want the motor to spin at 4 1/6 rpm when the Joystick is at rest,
  // so that the telescope will counteract the earth's rotation. The other operations just process
  // the joystick readings to be reasonable.)
  myStepper.setSpeed(abs(4.1667 + (xjoy-525)/50));
  
  // If the speed is greater than zero, then move counterclockwise
  if (((xjoy-525)/50) > -4.1667)  {
    myStepper.step(64);
  }
  // Otherwise, move clockwise.
  else  {
//Unless the speed is zero
    if ((abs(4.1667 + (xjoy-525)/50)) != 0)  {
      myStepper.step(-64);
    }
    // In which case, start over.
    else  {
      goto top;
    }

  }
}

However, when the joystick is in a certain position and the motor speed is zero, it takes infinitely long to move the sixty-four steps that it has to, and the motor stops indefinitely. As shown above, I tried this bit of code to address the issue:

//Unless the speed is zero
    if ((abs(4.1667 + (xjoy-525)/50)) != 0)  {
      myStepper.step(-64);
    }
    // In which case, start over.
    else  {
      goto top;
    }

Unfortunately, this doesn’t seem to work. Any ideas? Thanks!

cressmanj24:
However, when the joystick is in a certain position and the motor speed is zero, it takes infinitely long to move the sixty-four steps that it has to, and the motor stops indefinitely.

Your description does not make sense. If the motor speed is zero it should stop indefinitely and take infinitely long (literally) to move 64 steps.

Maybe with a more accurate description it would be worth studying your code.

…R

Thank you for replying. I apologize for any ambiguity in my post. My problem is that when the motor stops indefinitely, I can’t make it change speed. The segment of code I added should have fixed that, but the fact that it didn’t makes me wonder if there is another problem.

// If the speed is greater than zero, then move counterclockwise
  if (((xjoy-525)/50) > -4.1667)  {
    myStepper.step(64);
  }
  // Otherwise, move clockwise.
  else  {
    //Unless the speed is zero
    if ((abs(4.1667 + (xjoy-525)/50)) != 0)  {
      myStepper.step(-64);
    }
    // In which case, start over.
    else  {
      goto top;
    }
  }

Just going on your comments, why isn't the code as simple as this

 // If the speed is greater than zero, then move counterclockwise
  if (((xjoy-525)/50) > -4.1667)  {
    myStepper.step(64);
  }
  // Otherwise, move clockwise.
  else  {
      myStepper.step(-64);
    }

...R

My code was as you suggest, but I added the latter segment in order to address the problem, but to no avail. So, I suppose it is as you say. I will do that, though it will not solve the problem.

cressmanj24:
but I added the latter segment in order to address the problem, but to no avail.

Another problem is that you have not explained what the problem is. If you do, I will try to help.

What happens if you use the simple code I suggested?
What would like to happen?

...R

The problem is that sometimes the motor stops and becomes unresponsive to the joystick. The execution of your code is identical to that of mine.

It looks like you changed the code in your original post and now my earlier comment will make no sense to other readers. Don't do that.

When you make changes (apart from correcting typos) put them in a new Post so the whole Thread makes sense.

Perhaps you could reinstate the Original Post ?

...R

Don't write code like this

myStepper.setSpeed(abs(4.1667 + (xjoy-525)/50));

Put the calculated value in a variable

stepSpeed = abs(4.1667 + (xjoy-525)/50)
myStepper.setSpeed(stepSpeed);

Then you can use Serial.print() to see the calculated value

You have something similar in an IF test - so you can't see what value the test is based on.

...R

1 Sorry about that. I’ll change it back.

2 Good idea. Thanks. I was immediately able to diagnose the problem: The speed was 0.59, and apparently the stepper library rounds to the nearest whole. I altered my code to fix that:

// Include arduino stepper library
#include <Stepper.h>
 
const int stepsPerRevolution = 2048;  // specific to my motor
 
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,11,12,13);  

//Joystick is on analog pin 0
int joyPin1 = 0;
 
void setup() {

// Activate the motor shield by setting pins nine and ten to a digital high, as per the shield's specs.
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  // Initiate serial communication
  Serial.begin(9600);
  
}


 
void loop() {
  top:
  // Read the Joystick's analog signal
  float xjoy = analogRead(joyPin1);
  
  // Store the adjusted readings
  // (I want the motor to spin at 4 1/6 rpm when the Joystick is at rest,
  // so that the telescope will counteract the earth's rotation. The other operations just process
  // the joystick readings to be reasonable.)
  float stepspeed = abs(4.1667 + (xjoy-525)/50);
  
  // Print the speed.
  Serial.println(stepspeed);
  
  // Set the speed accordingly .
  myStepper.setSpeed(stepspeed);
  
  //If speed is substantial, then proceed
  if (stepspeed > 1)  {
    // If the speed is greater than zero, then move counterclockwise
    if (((xjoy-525)/50) > -4.1667)  {
      myStepper.step(1);
    }
    // Otherwise, move clockwise.
    else  {
      myStepper.step(-1);
    }
  }
}

However, this introduces another problem: How to make the motor spin at 4.1666666667 rpm.

cressmanj24:
However, this introduces another problem: How to make the motor spin at 4.1666666667 rpm.

Maybe you won't be able to use the library. You can create pretty much any timing you want if you write code that controls the interval between steps.

My own experience is only with writing code for a stepper driver that takes step and direction signals. Things are a little more complex if you use a h-bridge type of driver because your code needs to manage the sequencing of pulses for the motor. If it was my problem I would certainly change to a specialized stepper driver - assuming you have a bipolar stepper motor.

...R

I believe that my motor is unipolar. Also, I just noticed that after fixing my code, the motor will no longer slew counterclockwise, and I have no notion why.

cressmanj24:
I believe that my motor is unipolar. Also, I just noticed that after fixing my code, the motor will no longer slew counterclockwise, and I have no notion why.

How many wires has your motor? 4 = bipolar, 5 = unipolar. Small unipolar motors are usually driven with a ULN2003.

You will have to post the "fixed" code if you want assistance. I can't see your PC screen from here.

...R

Five. The most recent code that I posted is the “fixed” (post 11).

Also, I had an idea for making the motor spin at 4 1/6 rpm:

If I set up the stepper object with a false “stepsperrevolution” of approximately 1966, then when the Uno drives the stepper at 4 rpm, it will actually be spinning at 4.166667.

Would this be prudent? If not, what would go wrong?

cressmanj24:
If I set up the stepper object with a false "stepsperrevolution" of approximately 1966, then when the Uno drives the stepper at 4 rpm, it will actually be spinning at 4.166667.

Would this be prudent? If not, what would go wrong?

If the maths is correct that would be a good solution.

...R

As far as I can see, my math is correct:

4.166667/2048 = 4/x Therefore x = (2048 * 4)/4.166667 = 1966.0799

I uploaded the code, and it seems to be working~~, except for the problem with slewing counterclockwise~~.

cressmanj24:
As far as I can see, my math is correct:

I wasn't doubting it. I just had not bothered to check it.

I uploaded the code, and it seems to be working, except for the problem with slewing counterclockwise.

If you have already mentioned this I have lost track of the question. Perhaps you can repeat it and post the latest version of the code.

...R

Never mind. Everything is working fine. I thank you profusely for your help and advice, Robin2. My final code, after tweaking certain things (I got a new motor because the other one was insubstantial for my purposes) is as follows:

// Include arduino stepper library
#include <Stepper.h>
 
const int stepsPerRevolution = 215;  // specific to my motor
 
// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,11,12,13);  

//Joystick is on analog pin 0
int joyPin1 = 0;

void setup() {

// Activate the motor shield by setting pins nine and ten to a digital high, as per the shield's specs.
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  // Initiate serial communication
  Serial.begin(9600);
  
}


 
void loop() {
  // Read the Joystick's analog signal
  float xjoy = analogRead(joyPin1);
  
  // Store the adjusted readings
  // (I want the motor to spin at 4 1/6 rpm when the Joystick is at rest,
  // so that the telescope will counteract the earth's rotation. The other operations just process
  // the joystick readings to be reasonable.)
  float stepspeed = abs(3 + (xjoy-525)/25);
  
  // Print the speed.
  Serial.println(stepspeed);
  
  // Set the speed accordingly .
  myStepper.setSpeed(stepspeed);
  
  //If speed is substantial, then proceed
  if (stepspeed > 1)  {
    // If the speed is greater than zero, then move counterclockwise
    if ( 3 + ((xjoy-525)/25) > 0)  {

      myStepper.step(1);
    }
    // Otherwise, move clockwise.
    else  {
      myStepper.step(-1);
    }
  }
}