Adding buttons to control stepper motor speed.

Hi all. Wondering if someone can help/. Ive created the following sketch to use the Arduino joystick for a telescope motor focuser I’m building. It works great, however I’m realising that because I cant see the motor from my hut that I controll the focuser from, I need some visual representation of the speed the focuser (stepper) is running at.

Either:

LED’s indicating the speed (low, med or high)
3 buttons (1 for each) that I can press for the required speed.

The part I’m struggling with is how I change the routine for the single button push to 3 independent buttons, or add led’s to show the speed highlighted in red below.

Any help you can provide would be greatly appreciated. Feel free to use the sketch below for any project you have.

//Stepper control with Joystick. Coils disable when Joystick centred 24-12-17

#define step_pin 9 // Pin 9 connected to Steps pin on EasyDriver
#define dir_pin 8 // Pin 8 connected to Direction pin
#define MS1 10 // Pin 10 connected to MS1 pin
#define MS2 11 // Pin 11 connected to MS2 pin
#define MENABLE 6 // Pin 6 connected to ENABLE pin

#define X_pin A0 // Pin A0 connected to joystick x axis
#define Joy_switch 4 // Pin 4 connected to joystick switch

int step_speed = 30; // Speed of Stepper motor (higher = slower)

void setup() {
pinMode(MS1, OUTPUT);
pinMode(MS2, OUTPUT);
pinMode(dir_pin, OUTPUT);
pinMode(step_pin, OUTPUT);
pinMode(Joy_switch, INPUT_PULLUP);
pinMode (MENABLE, OUTPUT);

/* Configure type of Steps on EasyDriver:
// MS1 MS2
//
// LOW LOW = Full Step //
// HIGH LOW = Half Step //
// LOW HIGH = A quarter of Step //
// HIGH HIGH = An eighth of Step //
*/

digitalWrite(MS1, LOW); // Configures to Full Steps
digitalWrite(MS2, LOW); // Configures to Full Steps
}

void loop() {
if (!digitalRead(Joy_switch)) { // If Joystick switch is clicked
delay(500); // delay for deboucing
switch (step_speed) { // check current value of step_speed and change it
case 1:
step_speed = 10; // medium speed
break;
case 10:
step_speed = 30; // slow speed
break;
case 30:
step_speed = 1; // fast speed
break;
}
}

if (analogRead(X_pin) > 712) { // If joystick is moved Left

digitalWrite(dir_pin, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(step_pin, HIGH);
delay(step_speed);
digitalWrite(step_pin, LOW);
delay(step_speed);
}

if (analogRead(X_pin) < 312) { // If joystick is moved right

digitalWrite(dir_pin, LOW); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(step_pin, HIGH);
delay(step_speed);
digitalWrite(step_pin, LOW);
delay(step_speed);
}

if (analogRead (X_pin) > 320 && analogRead (X_pin) < 700) { // If joystick is centred - being 526

digitalWrite(MENABLE, HIGH); //Pull Enable Pin High
}
else digitalWrite(MENABLE, LOW); //Pull Enable Pin Low
}

    delay(500);  // delay for deboucing

There isn't a snowballs chance in hell that your switch will bounce for that long.

Why do you need to read the joystick 4 times to figure out what to do?

Why are you using a joystick, when the speed is not proportional to the joystick position? Or, why isn't the speed proportional?

Why aren't you using the Stepper library? Or AccelStepper?

What, EXACTLY, should the switches do?

What I'm trying to do is use the joystick to control direction of a stepper motor.

The push button of the joystick controls the step speed. Each time I click the button, the step speed changes giving me the control of slow, medium or high speed (which I need for a telescope focuser - this project).

it works, however as I cant see the motor, I don't know if the current state is slow, med or high. I would like to reference this either via leds for each state or a separate button to change the step speed so I know what it is currently.

Apologies if the code looks cr*p, it is a learning process I'm going through and it actually works well, apart from the speed reference I need to add.

Happy to learn form those more knowledgeable than myself so any input greatly appreciated.

Sorry - to answer your other questions:

And the reason I'm using a joystick is because I have better control than using a switch of sorts. The reason the speed is not proportional is because on a telescope focuser I need precise steps - I tried proportional but could get the accuracy needed. hence the reason for having 3 different speed steps (low, med, high or slow, med, fast).

What I don't understand is why the speed isn't proportional to the position of the joystick. The farther you push it forward (or backward or left or right), the faster the motor should move, shouldn't it?

You control the speed of your car with one control, not three or four or five. You know the speed of the car by looking at the speedo, but you also know where you have the accelerator, so you have a rough estimate of speed based solely on your ankle position.

What am I missing?

Hi Paul - thanks again for the response.

The reason it is not proportional is because with a telescope focuser, finite movements are needed & focussing can be down to 1 or 2 step movements. Having it proportional means it is quite easy to miss the right focus point. The way I have the joystick set up is that it takes into consideration the status of the speed steps and no matter how far you push the joystick, it will only move at the speed it is assigned with at that time.

It's mainly through choice using the joystick. I thought it would be easier than using buttons, however I'm happy to try buttons for forward & 1 for reverse, but not sure how to.

OK. You have valid reasons for not making the speed proportional.

So, what IS the problem? Reading the state of a pin with a switch connected to it (properly) is easy.

Setting the delay between steps when a switch is found to be pressed is easy. Turning a group of LEDs off is easy. Turning a single LED on is easy.

What do you need help with?

I need help in either:

Adding a switch (or switches) to trigger a change in the step speed in my sketch (slow/med/fast) where i can reference that step speed visually (either with a 3 way switch where each position of the switch defines a specific step speed or 3 switches where, depending on which switch is pressed, that step speed is used.

Or

Another solution (and probably easier/more user friendly) would be to use a rotary pot to control the speed, thus negating the need for multiple switches (less real estate on the hand controller also).

I thinking the pot would be the better option.

I just need to know the code to use a pot to control the speed and where to add it into my sketch. I'm guessing i would replace the code I already have for the joystick button with the pot code.

Lastly, any code to help me change from the joystick to buttons for forward/revers and I can build a 2nd hand controller & compare.

I've read through the tutorials on the stepper & accelstepper & the libraries but can only find info on either moving a stepper x distance or have it continually run and then a button to stop it, whereas I'm trying to jog.

Again, any advice/help is greatly appreciated Paul. Thanks again for your time.

You might try something like this, no button needed:

if(analog > 900)
  speed = fwdFast;
else if(analog > 775)
  speed = fwdMedium;
else if(analog > 651)
  speed = fwdSlow;
else if analog > 527)
  speed = fwdCreep: // 2 steps per second
else if(analog > 490)
  speed = 0;
else if(analog > 366)
  speed = revCreep;
else if(analog > 245)
 speed = revSlow;
else if(analog > 122)
  speed = revMedium;
else
  speed = revFast;

Thanks Outside, so looking at the code, it uses the joystick proportions to determine the speed - correct?

I could also alter the params for the joystick position to determine the best & most accurate movement?

At which point in my code would I enter this. I'm guessing after the "void loop()" & remove the red code in my sketch below?

I'd still like to try the forward/reverse jog buttons & a rotary pot or 3 way switch just to compare accuracy, however I can't seem to find much info on how to do that.

Any help greatly appreciated as always.

I'd still like to try the forward/reverse jog buttons & a rotary pot or 3 way switch just to compare accuracy, however I can't seem to find much info on how to do that.

Reading the state of a switch is dirt simple. Just call digitalRead() with the pin the the switch is wired (properly) to. If digitalRead() returns HIGH, and that means pressed, well, that might be important. Or, it might not. Or, HIGH could mean not pressed. And that might, or might not be important.

If you haven't figured it out yet, HOW you connect the switch is important. You haven't told us that yet, or asked how to connect them.

Whether the state of the switch is important, or not, depends on why you connected the switch. If the switch is to SELECT speed, then the fact that it is pressed means that the you want to SET the speed to some specific value.

If every time you press the switch, you want to INCREASE (or DECREASE) the speed, then the fact that the switch IS pressed is NOT enough information to determine whether to change the speed. You need to compare the current state to the previous state, and make a change only when the state has changed (to pressed).

The state change detection example could be useful reading.