Hi,
This probably isn't super complicated but I have to control 3 stepper motors simultaneously with an esp32 for part of a robotic arm.
These are the nema 23 stepper motors I am using, they are normal open loop 4 wire stepper motors.
These are the motor drivers I am using.
One pin tells the driver which direction to take a step in, where high is clockwise and low is counterclockwise. The other pin is the step pin and takes a 50% duty cycle square wave, and each cycle tells it to take a step. So, the higher the frequency the square wave, the quicker it takes its steps. It is important that it send the square wave for the exact right number of cycles so that the stepper motor takes the right number of steps.
There are 3 motors of these motors, each with a motor driver, all connected to an ESP32. I must simultaneously output the correct square wave to all 3 step pins, as well as the right direction to the 3 direction pins (this is easier because it is just writing it high or low). Code with delays will not work because it will completely stop, and the built in arduino stepper library seems to wait to finish moving one motor before executing the next line of code.
Since the timing is important and must be pretty quick, I would like to do the stepper motor movement on core0 of the ESP32, and have core1 handle serial communication with a computer that decides how to move the arm. However, I am really just having trouble with the PWM and timing aspect of this. I think if I start with just getting the 3 stepper motors working, I can figure out the multithreading stuff.
I have heard of timers and other ways to do the PWM, but I am pretty confused by all that. Right now I am using micros() and this is my code. It mostly works, however when I uploaded a sketch to move all the motors back and forth a certain number of steps, I noticed it would slowly drift from the starting position, indicating that steps are being lost. I need help figuring out if the code is the problem or the hardware is the problem. I also need help fixing this problem. Thanks!
This probably isn't super complicated but I have to control 3 stepper motors simultaneously with an esp32 for part of a robotic arm.
These are the nema 23 stepper motors I am using, they are normal open loop 4 wire stepper motors.
These are the motor drivers I am using.
One pin tells the driver which direction to take a step in, where high is clockwise and low is counterclockwise. The other pin is the step pin and takes a 50% duty cycle square wave, and each cycle tells it to take a step. So, the higher the frequency the square wave, the quicker it takes its steps. It is important that it send the square wave for the exact right number of cycles so that the stepper motor takes the right number of steps.
There are 3 motors of these motors, each with a motor driver, all connected to an ESP32. I must simultaneously output the correct square wave to all 3 step pins, as well as the right direction to the 3 direction pins (this is easier because it is just writing it high or low). Code with delays will not work because it will completely stop, and the built in arduino stepper library seems to wait to finish moving one motor before executing the next line of code.
Since the timing is important and must be pretty quick, I would like to do the stepper motor movement on core0 of the ESP32, and have core1 handle serial communication with a computer that decides how to move the arm. However, I am really just having trouble with the PWM and timing aspect of this. I think if I start with just getting the 3 stepper motors working, I can figure out the multithreading stuff.
I have heard of timers and other ways to do the PWM, but I am pretty confused by all that. Right now I am using micros() and this is my code. It mostly works, however when I uploaded a sketch to move all the motors back and forth a certain number of steps, I noticed it would slowly drift from the starting position, indicating that steps are being lost. I need help figuring out if the code is the problem or the hardware is the problem. I also need help fixing this problem. Thanks!
Code:
const int stepPin[] = {27,16,25};//note that index 0 corresponds to base #1, 1 to base #2, 2 to base #3
const int dirPin[] = {14,4,26};//note that index 0 corresponds to base #1, 1 to base #2, 2 to base #3
double stepsPerRotation[] = {200,5*200,/*5.76*/200*4};
int freq[] = {0,0,0};//stepper motor frequency of steps
bool stepDir[] = {false,false,false};//false = ccw, true = cw
bool stateidk[] = {true,true,true};//state variable to help PWM stepper motor
long pMic[] = {micros(),micros(),micros()};//timer variables to keep track of when to pwm stepper motor
int stepsTaken[] = {0,0,0};
void setup() {
for (int i = 0; i < 3; i++){
pinMode(stepPin[i],OUTPUT);
pinMode(dirPin[i],OUTPUT);
}
}
void loop() {
int stt[] = {8,222,500};
int rpmm[] = {20,15,60};
moveSteps(stt,rpmm);
delay(3000);
for (int i = 0; i < 3; i++){
stepDir[i] = !stepDir[i];
}
}
void moveSteps (int stepsToTake[3], int rpm[3]){
for (int i = 0; i <3; i++){
stepsTaken[i] = 0;
freq[i] = rpm[i]*stepsPerRotation[i]/60;
}
while (stepsTaken[0]<stepsToTake[0]||stepsTaken[1]<stepsToTake[1]||stepsTaken[2]<stepsToTake[2]){
for (int i = 0; i < 3; i++){
digitalWrite(dirPin[i],stepDir[i]);
if (stepsTaken[i]<stepsToTake[i]&&freq[i]!=0 && micros() - pMic[i] > 1000000/2/freq[i]){
stateidk[i] = !stateidk[i];
if (stateidk[i]){
stepsTaken[i]++;
}
digitalWrite(stepPin[i],stateidk[i]);
pMic[i]=micros();
}
}
}
}