OVERVIEW
In our prior tutorial we saw how to control 2 stepper motor simultaneously using the Arduino Serial Monitor.
Continuing from this, we will now add an Analog Joystick to our project to set IN and OUT points for the Steppers to travel to.
We will also be seeing a new way to move both steppers simultaneously and make sure that they reach their destination at the same time.
Again we will be using the Serial Monitor to input some values like the Speed we want the Steppers to travel but we will also be using the Joystick integrated switch to set the IN and OUT points.
PARTS USED
EasyDriver Stepper Driver
Analog Joystick Module
Stepper Motor NEMA 17
These are Amazon affiliate links...
They don't cost you anything and it helps me keep the lights on
if you buy something on Amazon. Thank you!
CONNECTIONS
The connection for the Easy Driver boards are almost the same as our prior tutorial:
To power the Stepper Motors connected to the Easy Driver boards we are using a 12V 1A power supply.
The GND and 5V (out) of the Power Supply are connected to the breadboard power rails.
GND and 5V (in) of the Easy Driver boards are connected to the breadboard power rails.
Each pair of winding of the Stepper motors are connected to the A-B pins of the Easy Drivers.
The GND of the UNO is connected to the breadboard GND power rail.
Each Easy Driver GND is connected to the breadboard GND power rail.
Pin 3 and 4 of the UNO are connected to the STEP and DIR pins of one Easy Driver.
Pin 6 and 7 of the UNO are connected to the STEP and DIR pins of the other Easy Driver.
In this tutorial we added these connections for the Analog Joystick:
GND of the Joystick is connected to the GND of the UNO.
V+ of the Joystick is connected to the 5V of the UNO.
The X and Y axis Pins of the Joystick are connected to Pins A0 and A1 of the UNO.
The Switch Pin of the Joystick is connected to Pin 2 (Interrupt zero) of the UNO.
THE CODE
The code we are using is different from our prior tutorial, but we are using some parts of it to read data from the Serial Monitor.
We are still using the AccelStepper class of the library to move the Steppers using the Joystick X and Y axis.
But we are now using the MultiStepper class of the same library to move both Steppers once we have set the IN and OUT points using the Joystick.
The MultiStepper class not only provide us with a way to move both Steppers at once, but also calculates the speed needed to move each Steppers so they end up at their destination (IN or OUT point) at the same time.
We use the Serial Monitor window to provide us with information like what the sketch is expecting at a particular point as well as give us the ability to enter information like the desired Speed and what move we want to execute.
As always for more information about the tutorial and explanation of the code please watch our tutorial video.
/* Arduino Multiple Stepper Control Using Joystick switch
Created by Yvan / https://Brainy-Bits.com
This code is in the public domain...
You can: copy it, use it, modify it, share it or just plain ignore it!
Thx!
*/
// Library created by Mike McCauley at http://www.airspayce.com/mikem/arduino/AccelStepper/
#include "AccelStepper.h"
#include "MultiStepper.h"
// AccelStepper Setup
AccelStepper stepperX(1, 3, 4); // 1 = Easy Driver interface
// UNO Pin 3 connected to STEP pin of Easy Driver
// UNO Pin 4 connected to DIR pin of Easy Driver
AccelStepper stepperZ(1, 6, 7); // 1 = Easy Driver interface
// UNO Pin 6 connected to STEP pin of Easy Driver
// UNO Pin 7 connected to DIR pin of Easy Driver
MultiStepper StepperControl; // Create instance of MultiStepper
// Analog Joystick setup
#define JoyX A0 // Joystick X pin connected to A0 on the UNO
#define JoyY A1 // Joystick Y pin connected to A1 on the UNO
#define JoySwitch 2 // Joystick switch connected to interrupt Pin 2 on UNO
long joystepX=0; // Used to move steppers when using the Joystick
long joystepY=0; // Used to move steppers when using the Joystick
// Variables used to store the IN and OUT points
volatile long XInPoint=0;
volatile long ZInPoint=0;
volatile long XOutPoint=0;
volatile long ZOutPoint=0;
int InandOut=0; // Used to detect if IN and OUT points have been set
long gotoposition[2]; // Used to move steppers using MultiStepper Control
void joyswitchclick () { // Interrupt runs when clicking the Joystick Switch
static unsigned long last_call_interrupt = 0; // Used to debounce to Joystick Switch
unsigned long interrupt_length = millis();
if (interrupt_length - last_call_interrupt > 300) { // Check if enough time has passed since clicking switch
switch (InandOut) { // Keep track of number of times the switch has been clicked
case 0:
InandOut=1;
XInPoint=stepperX.currentPosition(); // Set the IN points for both steppers
ZInPoint=stepperZ.currentPosition();
Serial.print("IN Points set at: ");
Serial.print(XInPoint);
Serial.print(" , ");
Serial.println(ZInPoint);
Serial.println("");
Serial.println("Use Joystick to set OUT Points: ");
break;
case 1:
InandOut=2;
XOutPoint=stepperX.currentPosition(); // Set the OUT Points for both steppers
ZOutPoint=stepperZ.currentPosition();
Serial.print("OUT Points set at: ");
Serial.print(XOutPoint);
Serial.print(" , ");
Serial.println(ZOutPoint);
Serial.println("");
Serial.println("Enter Stepper Travel Speed: ");
Serial.println("OR");
Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
break;
case 2:
Serial.println("");
Serial.println("IN and OUT Points have been Reset...");
Serial.println("");
Serial.println("");
Serial.println("Set IN points for Steppers using the Joystick ");
InandOut=0;
break;
case 3:
Serial.println("");
Serial.println("IN and OUT Points have been Reset...");
Serial.println("");
Serial.println("");
Serial.println("Set IN points for Steppers using the Joystick ");
InandOut=0;
joystepY=stepperZ.currentPosition(); // Reset Positions
joystepX=stepperX.currentPosition();
stepperX.setMaxSpeed(350.0); // Reset Max Speed of X axis
break;
}
}
last_call_interrupt = interrupt_length;
}
void setup() {
Serial.begin(9600); // Start the Serial monitor with speed of 9600 Bauds
// Print out Instructions on the Serial Monitor at Start
Serial.println("Set IN points for Steppers using the Joystick ");
pinMode(JoySwitch, INPUT_PULLUP);
// Set Max Speed and Acceleration of each Steppers
stepperX.setMaxSpeed(350.0); // Set Max Speed of X axis
stepperX.setAcceleration(5000.0); // Acceleration of X axis
stepperZ.setMaxSpeed(150.0); // Set Max Speed of Z axis slower for rotation
stepperZ.setAcceleration(1000.0); // Acceleration of Y axis
// Create instances for MultiStepper
StepperControl.addStepper(stepperX); // Add Stepper #1 to MultiStepper Control
StepperControl.addStepper(stepperZ); // Add Stepper #2 to MultiStepper Control
attachInterrupt (0,joyswitchclick,FALLING); // interrupt 0 always connected to pin 2
}
void loop() {
while ((InandOut != 2) && (InandOut !=3)) { // Enable moving of steppers using the Joystick
if (analogRead(JoyX) < 200) {
joystepX=stepperX.currentPosition();
joystepX=joystepX-20; }
if (analogRead(JoyX) > 900) {
joystepX=stepperX.currentPosition();
joystepX=joystepX+20;
}
if (analogRead(JoyY) < 200) {
joystepY=stepperZ.currentPosition();
joystepY=joystepY-20; }
if (analogRead(JoyY) > 900) {
joystepY=stepperZ.currentPosition();
joystepY=joystepY+20;
}
stepperX.moveTo(joystepX);
stepperZ.moveTo(joystepY);
while ((stepperX.distanceToGo() !=0) || (stepperZ.distanceToGo() !=0)) {
stepperX.runSpeedToPosition();
stepperZ.runSpeedToPosition();
}
}
if (InandOut == 2) {
while (Serial.available() > 0) { // Check if values are available in the Serial Buffer
int setspeed = Serial.parseInt(); // Read entered Speed from Serial Buffer
if (setspeed > 0) {
stepperX.setMaxSpeed(setspeed);
Serial.println("");
Serial.println("Speed set at: ");
Serial.println(setspeed);
Serial.println("");
Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
Serial.println("OR");
Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
setspeed=0;
InandOut=3;
}
}
}
if (InandOut == 3) {
while (Serial.available() > 0) { // Check if values are available in the Serial Buffer
char checkinput = Serial.read(); // Read Character entered in Serial Monitor
Serial.println(checkinput);
if (checkinput == 'I') { // Move both steppers to IN points
gotoposition[0]=XInPoint;
gotoposition[1]=ZInPoint;
StepperControl.moveTo(gotoposition);
StepperControl.runSpeedToPosition(); // Blocks until all are in position
Serial.println("Steppers are at the IN Position...");
Serial.println("");
Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
Serial.println("OR");
Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
}
if (checkinput == 'O') { // Move both steppers to OUT points
gotoposition[0]=XOutPoint;
gotoposition[1]=ZOutPoint;
StepperControl.moveTo(gotoposition);
StepperControl.runSpeedToPosition(); // Blocks until all are in position
Serial.println("Steppers are at the OUT Position...");
Serial.println("");
Serial.println("Type 'I' to go to the IN points or 'O' to go to the OUT points");
Serial.println("OR");
Serial.println("Press Joystick Switch again to Reset IN and OUT Points");
}
}
}
}
TUTORIAL VIDEO
DOWNLOAD
Copy the above Sketch code in your Arduino IDE software to program your Arduino.
Used Libraries:
Download The AccelStepper Library
created by ‘Mike McCauley’ :
Once downloaded, just extract the content of the zip files inside your “arduino/libraries” folder, and make sure to restart the Arduino IDE (Close and Reopen) software so it detect this newly installed library.