Stepping motor no joy

Hi.

Can I get assistance with the below code?

This project has a CNC shield v3 on an UNO running a stepper motor with an adafruit joystick. A few years ago I used the Google, used this site, and some help from the community to derive the below sketch. It was meant to operate 2 motors to move a telescope about its base. I no longer have the telescope. I would like to control the stepper motor for forward and reverse still but I need full speed from the stepper motor. Below, int high/low Speed looks counterintuitive for what I would expect.

My first question to this group is, what value should low and high Speed be to attain the highest and lowest speeds afforded by the motor?

My other question is can this code be reworked to have a POT operate the motor? If so, can I get some help with that code? Also, is it possible to have the midpoint of the POT be 0 (off/no speed) and when turned to the left, the motor goes in a direction and when turned to the right, past midpoint, the motor goes in the opposite direction? Or, does this require a special POT?

Thanks in advance!!!

Begin Code:

// simple code to move a stepper with a joystick
// added second axis, X & Y step counts (displayed in serial monitor) and switch to zero step counts
// by C. Goulding aka groundFungus

#define FORWARD 1
#define REVERSE 0

const byte xJoyPin = A0; // Abort on CNC shield
const byte xStepPin = 2;
const byte xDirPin = 5;

const byte yJoyPin = A1; // Hold on CNC shield
const byte yStepPin = 3;
const byte yDirPin = 6;
const byte swPin = 16;  // Resume on CNC shield, pin 16 is digital pin for A2
const byte enablePin = 8;

boolean xDir = FORWARD;
int xPos;
boolean yDir = FORWARD;
int yPos;

int lowSpeed = 20;
int highSpeed = 5;

unsigned long curMillis = 0;
unsigned long prevStepMillisX = 0;
unsigned long millisBetweenStepsX = 10;
unsigned long prevStepMillisY = 0;
unsigned long millisBetweenStepsY = 10;

long stepCountX;
long stepCountY;

void setup()
{
   Serial.begin(115200);
   Serial.println("Telescope Project");
   pinMode(swPin, INPUT_PULLUP);
   pinMode(xStepPin, OUTPUT);
   pinMode(xDirPin, OUTPUT);
   pinMode(yStepPin, OUTPUT);
   pinMode(yDirPin, OUTPUT);
   pinMode(enablePin, OUTPUT);
   digitalWrite(enablePin, LOW);
}

void loop()
{
   curMillis = millis();
   getY();
   getX();   
   getSw();
   printStepCounts();
}

void getY()
{
   yPos = analogRead(yJoyPin);
   if (yPos >= 0 && yPos < 200)
   {
      millisBetweenStepsY = highSpeed;
      yDir = REVERSE;
      singleStepY();
   }
   else if (yPos > 201 && yPos < 450)
   {
      millisBetweenStepsY = lowSpeed;
      yDir = REVERSE;
      singleStepY();
   }
   else if (yPos > 560 && yPos < 850)
   {
      millisBetweenStepsY = lowSpeed;
      yDir = FORWARD;
      singleStepY();
   }
   else if (yPos > 851 && yPos < 1024)
   {
      millisBetweenStepsY = highSpeed;
      yDir = FORWARD;
      singleStepY();
   }
   //else stop
}


void getX()
{
   xPos = analogRead(xJoyPin);
   if (xPos >= 0 && xPos < 200)
   {
      millisBetweenStepsX = highSpeed;
      xDir = REVERSE;
      singleStepX();
   }
   else if (xPos > 201 && xPos < 450)
   {
      millisBetweenStepsX = lowSpeed;
      xDir = REVERSE;
      singleStepX();
   }
   else if (xPos > 560 && xPos < 850)
   {
      millisBetweenStepsX = lowSpeed;
      xDir = FORWARD;
      singleStepX();
   }
   else if (xPos > 851 && xPos < 1024)
   {
      millisBetweenStepsX = highSpeed;
      xDir = FORWARD;
      singleStepX();
   }
   //else stop
}

void singleStepY()
{
   if (curMillis - prevStepMillisY >= millisBetweenStepsY)
   {
      if (yDir == 1)
      {
         stepCountY ++;
      }
      else
      {
         stepCountY --;
      }
      digitalWrite(yDirPin, yDir);
      prevStepMillisY = curMillis;
      digitalWrite(yStepPin, HIGH);
      digitalWrite(yStepPin, LOW);
   }
}

void singleStepX()
{
   if (curMillis - prevStepMillisX >= millisBetweenStepsX)
   {
      if (xDir == 1)
      {
         stepCountX ++;
      }
      else
      {
         stepCountX --;
      }
      digitalWrite(xDirPin, xDir);
      prevStepMillisX = curMillis;
      digitalWrite(xStepPin, HIGH);
      digitalWrite(xStepPin, LOW);
   }
}

void getSw() // reset step counts.
{
   static unsigned long swTimer = 0;
   unsigned long swInterval = 50;
   if (curMillis - swTimer >= swInterval)
   {
      swTimer = curMillis;
      if (digitalRead(swPin) == LOW)
      {
         swTimer = millis();
         stepCountX = 0;
         stepCountY = 0;
      }
   }
}

void printStepCounts()
{
   static unsigned long printTimer = 0;
   unsigned long printInterval = 500;
   if (curMillis - printTimer >= printInterval)
   {
      printTimer = curMillis;
      Serial.print("X position = ");
      Serial.print(stepCountX);
      Serial.print("   Y position = ");
      Serial.println(stepCountY);
   }
}

Note I have changed the title of this thread to more accurately reflect the question. A stepping motor is not considered to be a DC motor.

There is no minimum value a stepping motor can be as slow as you like.

As to the maximum speed this is another matter. It depends on the torque of the motor and the torque of the load, and also if you want the figure from a standing start or you can afford to ramp up to a final speed, and stop, or ramp up to a speed and then ramp down from it and stop.

Each technique delvers an increasingly fast top speed.

Thanks Grumpy

The motor should ramp. Increasing from zero to/towards max speed as I move the joystick farther from the center. And as I move the joystick back toward center, the speed ramps down. I may not always want max speed but I certainly want the option. Does int highSpeed work within a range? If so, what is that range? Like 0 - 250 where 0 is stopped and 250 is max speed?

But as I mentioned in the original post, the code works great as is with joystick, just need more max speed allowance. And after looking at the inversely set low and high speed values, I was confuzzled.

And then the second part of my question with switching to a POT etc.

Thanks!

It will only ramp up because your joystick value changes the speed, so it is your physical action that cause the ramping. This is not so much in control as you might think, you might easily move your joystick too fast for your motor to ramp up to the requested speed.

One way round this might be to write some code that uses the joystick reading, not to directly set the speed, but to increment the speed setting with a value proportional to the reading. In that way if you move your joystick rapidly the maximum amount of acceleration could be kept under control. Similarly the deceleration could be applied when the joystick value was less than it was last time.

No any pot will do. However you should apply some hysteresis, that is only apply a speed change if the current pot reading is a certain distance away from the last point you changed the speed. This prevents the speed jittering, especially around the zero or stopped point.

You can do this using something like this

   if( abs(currentPotReading - lastPotReading) > thresholdForMovement) {
        lastPotReading = currentPotReading;
       // do other stuff to change the speed

The abs function here always returns a positive number so there is no need to have separate cases for going up and going down with your pot. You can also apply this to joystick control as well.

Thanks again Grumpy.

So, any feedback as to what will happen if I change the values for int low/highSpeed in the supplied code?

Thanks!

No because like I said in the first post it depends on a lot of factors you have no control over and are specific to your system. It is one of those cases where you have to experiment with values to see how your system copes.

have you considered making the speed proportional to the distance to the target, the absolute difference between the current and desired positions?

i've found that the smallest delay between steps is about 1 msec. (could be less for some motors) so this delay would be inversely proportional to the distance

isn't this how is currently works, the 2 pots, x & y set to the desired positions?