I've built this little machine and I'm trying to code it to learn some skills and what not. I don't want to use GRBL so I'm trying to set up my own code to do this.
Ultimately my goal is to create a function I can draw a line directed at a given angle 0-359, and a given length.
Something like: drawline(angle, length)
At this point my goal along the way is to drive two stepper motors in a near simultaneous way instead of moving motor#1 by distance_a and motor#2 by distance_a. I assume the only way to do it is by moving each motor by 1 step followed by the next motor, back and forth.
But I can't figure out how to drive them simultaneously so thats why I'm going about it like this... I'm trying to make a function with these arguments: drive(motor, speed) such that drive will return one single step from the chosen motor. Using this single step function I will loop it as I did.
you need to determine rates for movements, step along the longer dimension, x or y, which should require moving one stepper at each step and the 2nd motor periodically. keep track of steps infractions and move step a motor whenever the accumulated value increases about the previous integer value
Remember that Einstein proved that nothing can happen simultaneously ('c' being a speed limit and all that), so you have to decide what your definition of "simultaneously" is.
The arduino can send the step command to both motors far faster than they can physically respond to it, so what is the problem that you're seeing?
For example, this following code where the motors moves 1600 steps for one revolution 1600 when called by drive(stepper m, s) function works fine; however, the code alternates back and fourth between the two steppers spinning one revolution for x then one revolution for y over and over.
#include <Stepper.h>
const int rev=1600;
int drivefunc;
Stepper x(rev,8,9); //Defining Stepper Pins
Stepper y(rev,10,11);
void setup() {
Serial.begin(9600);
}
void loop() {
for(int n; n<rev; ++n){ //Loop to repeat drive()
drivefunc=drive(x,60);
drivefunc=drive(y,60);
}
end();
}
int drive(Stepper m,int s){ //Drive function moves motor in arg by speed in arg for steps in m.step()
m.setSpeed(s);
m.step(1600); //changing this value to 1 produces no motor motion
return 1;
}
void end(){ // This function uses a while loop to stop running the void loop
while(1){}
}
I would like to drive() to drive the motor only 1 step so that alternating between motor x and motor y for one step each in a for loop determined length by Const Int Rev appears to draw a diagonal line. I don't know why the following code program outputs no motor movement when the former code program alternates the motor one rev by one rev.
#include <Stepper.h>
const int rev=1600;
int drivefunc;
Stepper x(rev,8,9); //Defining Stepper Pins
Stepper y(rev,10,11);
void setup() {
Serial.begin(9600);
}
void loop() {
for(int n; n<rev; ++n){ //Loop to repeat drive()
drivefunc=drive(x,60);
drivefunc=drive(y,60);
}
end();
}
int drive(Stepper m,int s){ //Drive function moves motor in arg by speed in arg for steps in m.step()
m.setSpeed(s);
m.step(1); //produces no output
return 1;
}
void end(){ // This function uses a while loop to stop running the void loop
while(1){}
}
Your problem is the stepper.h library. All stepper movements of this library are blocking. So you cannot move two steppers at the same time simultaneously.
Use another ( non blocking ) stepper library . Or create the steps without a library at all.
If you don't need acceleration, the multistepper part of the AccelStepper library may be a solution.
At any angle other than 45°, you need to drive one motor more steps than the other, so they can't all be "simultaneous" or paired.
You don't need a function to drive a stepper moter by one step, you already have that in drive(). What you need is a function to decide whether or not the slower axis needs to take a step or not.
Take a look into the Bresenham Line Algorithm for scheduling whether the axis with slower stepping needs to do a step or not.
The trick is figuring out which axis needs more steps, and each time you to take a step, decide whether or not the other axis also needs a step. The Bresenham algorithm does the ratio math with repeated additions and subtractions so it is fast and precise.
CNCs and 3d printers use the algorithm to coordinate motion between axes.
the Stepper library code you're using is designed to drive the individual coils of the motor. The TB6600 board has direction and pulse inputs.
it doesn't make sense that your code for 1600 steps did what you say given the diagram you posted and you're use of the Stepper library
the Stepper library will generate pulses so maybe that's why you saw some movement, but if there are 1600 steps/revolution, did the motor turn one complete revolution?
Stepper.h will drive a step/dir driver with the two-pin initialization setup, but it will be slow (1/4 speed) because it sends quadrature signals out on the two pins and needs to send a full 4-step cycle to toggle the PULSE line once.
int rev = 400;
int d=0;
void setup() {
pinMode(8,OUTPUT); //XPul
pinMode(9,OUTPUT); //XDir
}
void loop() { //loop to call drive func in a loop for steps in one revolution
while(d<rev){
drive(8,9);
++d;
}
while(1){} //loop to "end" this void loop() program body function
}
int drive(int pul,int dir){ //function to drive motor one step
digitalWrite(pul,HIGH);
digitalWrite(dir,HIGH);
delayMicroseconds(500);
digitalWrite(dir,LOW);
delayMicroseconds(500);
digitalWrite(pul,LOW);
return ;
}
can you fix this code so that it works so I can understand?
I feel like this should turn the X stepper one revolution which I set to have 400 steps on the driver dip switches. Unfortunately nothing happens.