Hello, I am having difficulty using a Joystick to control 2 1.5A NEMA 17 Bipolar Stepper Motors. I am driving it with a A4988 from HiLetgo. The program is an edited version of code created by https://www.brainy-bits.com/post/control-a-stepper-motor-using-a-joystick-and-an-arduino. The functionality I am aiming for is when I move left and right one of the steppers move, and when I move up and down the other stepper moves. This is to simulate movement in the X and Y direction. When clicking on the button on the Joystick, the speed increases. This works when I am at the slowest speed, but when I increase the speed I notice a difference in that both steppers move slower in one direction than another. This is especially true for the stepper motor controlling what's supposed to be the Y direction as pushing down on the joystick the speed stays at the slowest no matter which speed I currently am in. Attached are photos of my setup and the code used. Also the actual voltage in my circuit is a 12v multivariable power supply I just have a 9v battery there since I couldn't find a power supply like mine on fritzing.
//https://www.brainy-bits.com/post/arduino-nema-stepper-control-with-joystick-and-limit-switches CODE CREDIT
#define stepx = 14; // Pin 14 connected to the step pin in the x direction
#define dir_x = 32; // Pin 32 connected to direction pin in the x direction
#define stepy = 27; //Pin 27 connected to the step pin in the y direction
#define dir_y = 33; //Pin 33 connected to the direction pin in the y direction
#define sw = 15; // Pin 15 connected to joystick switch
int step_speed = 10; // Speed of Stepper motor (higher = slower)
void setup() {
pinMode(dir_x, OUTPUT);
pinMode(stepx, OUTPUT);
pinMode(dir_y, OUTPUT);
pinMode(stepy, OUTPUT);
pinMode(sw, INPUT_PULLUP);
}
void loop() {
if (!digitalRead(sw)) { // 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; // slow speed
break;
case 3:
step_speed=1; // fast speed
break;
case 10:
step_speed=3; // medium speed
break;
}
}
int X_pin = analogRead(26);
int Y_pin = analogRead(25);
int val = map(X, 0, 4096, 0, 100);
int val2 = map(Y, 0, 4096, 0, 100);
if (val > 75) { // If joystick is moved RIGHT
digitalWrite(dir_x, LOW); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(stepx, HIGH);
delay(step_speed);
digitalWrite(stepx, LOW);
delay(step_speed);
}
if (val < 25) { // If joystick is moved LEFT
digitalWrite(dir_x, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(stepx, HIGH);
delay(step_speed);
digitalWrite(stepx, LOW);
delay(step_speed);
}
if (val2 > 150) { // If joystick is moved UP
digitalWrite(dir_y, HIGH); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(stepy, HIGH);
delay(step_speed);
digitalWrite(stepy, LOW);
delay(step_speed);
}
if (val2 < 50) { // If joystick is moved DOWN
digitalWrite(dir_y, LOW); // (HIGH = anti-clockwise / LOW = clockwise)
digitalWrite(stepy, HIGH);
delay(step_speed);
digitalWrite(stepy, LOW);
delay(step_speed);
}
}
A stepper motor either performs with the exact speed you want, or misses steps!
So either your code says to the motor to move slower in one direction than the other direction. Or you have some mechanical friction that is bigger in one direction than the other direction.
To detect missing steps, add lines in your code where you print the number of steps as the motor performs them. Compare the number with the actual angle the motor has rotated. If they are not in conflict, the error is elsewhere. Print the values you read from the joystick. Print all values you get along the path from reading the joysticks and converting them to delay values or whatever you have in your code that controls the step frequency. You should know what the values should be.
Okay, so I calculated my Vref for this particular stepper motor for the A4988 driver, which is around 0.96V. For some reason when twisting the potentiometer knob on the stepper driver, I can only get a maximum of 0.82-0.84V. I'm not sure if that could be what's causing it or if I need to up the voltage being put into the circuit.
That's where one step happens. Add a variable that increments or decrements and that way holds a step count value, which should correlate with the stepper motor position. And add a line that prints the value to the serial monitor.
I suspect 9V is on the low side for the 4988 driver even though the datasheet says 8 to 35v, and you have probably got the current set too high. You should not aim to set the current to the rated value for the stepper but to a value that gives you the torque you need. If you are using a PP3 battery that also has limited current capability.
If you really need to operate at 9V the DRV8834 is rated for 2.5 - 10.8v, also available from Polulu. I run two of them in a clock from 9v which is derived from a 12v rail through a regulator.
You also write a very simple sketch that sends pulses to only one motor at a fixed speed and just toggle the direction to make sure there isn't a mechanical problem.
My apologies I should have specified before I actually am using a 12v power supply for the circuit I just had a 9v for the schematic. Would 12v be considered still too low? Or should I consider upping it to like 24v?
I have many steppers running at 12V with A4988 drivers. 12V works fine if the supply is capable of supplying the current required by the motors. Just because it says 12V does not mean that it is an appropriate supply.
Hmm thats interesting. I actually had this issue with some dc motors I was using. My power supply was making the motor skip, but when I connected it with USB power or some AA batteries, it was moving fine. Now Im wondering if its the same with the steppers.
The general recommendation is to supply steppers with the highest possible voltage to maximise speed. 12V will work for the 4988, on a stepper-driven rotary axis I have I use 20v, and 24v on another drive. I've got 2 CNC machines, lathe and mill, that use 36 - 40v.